diff --git a/CMakeLists.txt b/CMakeLists.txt index e5884b278f1bcf9289ca970f3770d7f830ca01b9..10f3de092f905ef93cea16aed17bcd8f84ceb68f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,8 +51,8 @@ SET(DESTDIR "/opt/${PROJECT_NAME}") SET( CPACK_GENERATOR "DEB") SET( CPACK_PACKAGE_NAME "${PROJECT_NAME}") SET( CPACK_PACKAGE_VERSION_MAJOR 2) -SET( CPACK_PACKAGE_VERSION_MINOR 10) -SET( CPACK_PACKAGE_VERSION_PATCH 1) +SET( CPACK_PACKAGE_VERSION_MINOR 11) +SET( CPACK_PACKAGE_VERSION_PATCH 0) SET( CPACK_SYSTEM_NAME "debian-10.0-amd64") SET( CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}-${CPACK_PACKAGE_VERSION_PATCH}") diff --git a/lib/mongoc/CMakeLists.txt b/lib/mongoc/CMakeLists.txt deleted file mode 100755 index f36b1dc88625d3be590f58288582ba37decf3a08..0000000000000000000000000000000000000000 --- a/lib/mongoc/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -cmake_minimum_required(VERSION 3.0 FATAL_ERROR) - -set (ENABLE_SSL OFF CACHE STRING - "Enable TLS connections and SCRAM-SHA-1 authentication. Options are - \"DARWIN\" to use Apple's Secure Transport, \"WINDOWS\" to use Windows - Secure Channel, \"OPENSSL\", \"LIBRESSL\", \"AUTO\",\ or \"OFF\". These options are - case-sensitive. The default is \"AUTO\". Note\ that SCRAM-SHA-1 is - required for authenticating to MongoDB 3.0 and later.") -set (ENABLE_SASL OFF CACHE STRING - "Enable SASL authentication (Kerberos). Options are \"CYRUS\" to use Cyrus - SASL, \"SSPI\" to use Windows Native SSPI, \"AUTO\",\ or \"OFF\". These options are case-sensitive.") -set (ENABLE_STATIC AUTO CACHE STRING "Build static libmongoc. Set to ON/AUTO/OFF, default AUTO.") -option (ENABLE_TESTS "Build MongoDB C Driver tests." ON) -option (ENABLE_EXAMPLES "Build MongoDB C Driver examples." ON) -set (ENABLE_SRV AUTO CACHE STRING "Support mongodb+srv URIs. Set to ON/AUTO/OFF, default AUTO.") -option (ENABLE_MAINTAINER_FLAGS "Use strict compiler checks" OFF) -option (ENABLE_AUTOMATIC_INIT_AND_CLEANUP "Enable automatic init and cleanup (GCC only)" ON) -option (ENABLE_CRYPTO_SYSTEM_PROFILE "Use system crypto profile (OpenSSL only)" OFF) -option (ENABLE_TRACING "Turn on verbose debug output" OFF) -option (ENABLE_COVERAGE "Turn on compile options for lcov" OFF) -set (ENABLE_SHM_COUNTERS AUTO CACHE STRING "Enable memory performance counters that use shared memory on Linux. Set to ON/AUTO/OFF, default AUTO.") -set (ENABLE_MONGOC ON CACHE STRING "Whether to build libmongoc. Set to ON/OFF, default ON.") -set (ENABLE_BSON AUTO CACHE STRING "Whether to build libbson. Set to ON/AUTO/SYSTEM, default AUTO.") -set (ENABLE_SNAPPY AUTO CACHE STRING "Enable snappy support. Set to ON/AUTO/OFF, default AUTO.") -set (ENABLE_ZLIB AUTO CACHE STRING "Enable zlib support") -set (ENABLE_ZSTD AUTO CACHE STRING "Enable zstd support. Set to ON/AUTO/OFF, default AUTO.") -option (ENABLE_MAN_PAGES "Build MongoDB C Driver manual pages." OFF) -option (ENABLE_HTML_DOCS "Build MongoDB C Driver HTML documentation." OFF) -option (ENABLE_EXTRA_ALIGNMENT - "Turn on extra alignment of libbson types. Set to ON/OFF, default ON.\ - Required for the 1.0 ABI but better disabled." - ON -) -option (ENABLE_RDTSCP - "Fast performance counters on Intel using the RDTSCP instruction" - OFF -) -option (ENABLE_APPLE_FRAMEWORK "Build libraries as frameworks on darwin platforms" OFF) -set (ENABLE_ICU AUTO CACHE STRING "Enable ICU support, necessary to use non-ASCII usernames or passwords, default AUTO.") -option (ENABLE_UNINSTALL "Enable creation of uninstall script and associated uninstall build target." ON) -set (ENABLE_CLIENT_SIDE_ENCRYPTION AUTO CACHE STRING "Enable Client-Side Field Level Encryption support. Requires libmongocrypt. Set to ON/AUTO/OFF, default AUTO.") - -add_subdirectory(libmongoc) - -#target_include_directories(libcurl INTERFACE "libcurl/include/") - -#target_include_directories(libcurl PUBLIC -# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libcurl/include> -# $<INSTALL_INTERFACE:include/mylib> -#) diff --git a/lib/mongoc/libmongoc/.gitignore b/lib/mongoc/libmongoc/.gitignore deleted file mode 100644 index 977d22700b8f8ff83b6e34c3910cc4f281e34135..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -libmongoc-1.0-config-version.cmake -libmongoc-1.0-config.cmake -libmongoc-static-1.0-config-version.cmake -libmongoc-static-1.0-config.cmake -example-client -example-collection-watch -example-command-monitoring -example-command-with-opts -example-create-indexes -example-gridfs -example-pool -example-scram -example-sdam-monitoring -example-session -example-transaction -example-update -fam -mongoc-dump -mongoc-ping -mongoc-stat -mongoc-tail -test-libmongoc -test-mongoc-gssapi diff --git a/lib/mongoc/libmongoc/CMakeLists.txt b/lib/mongoc/libmongoc/CMakeLists.txt deleted file mode 100644 index afddcc0851e62f44c98d482d1e18002561d09514..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/CMakeLists.txt +++ /dev/null @@ -1,1112 +0,0 @@ -cmake_minimum_required (VERSION 3.1) - -project (libmongoc C) - -set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/../../build/cmake) - -set (ENABLE_ZLIB OFF CACHE STRING "Enable zlib support") - -include (InstallRequiredSystemLibraries) - -message ("libmongoc version (from VERSION_CURRENT file): ${MONGOC_VERSION}") - -# Defaults. -set (MONGOC_ENABLE_SSL 0) -set (MONGOC_ENABLE_SSL_OPENSSL 0) -set (MONGOC_HAVE_ASN1_STRING_GET0_DATA 0) -set (MONGOC_ENABLE_SSL_LIBRESSL 0) -set (MONGOC_ENABLE_SSL_SECURE_TRANSPORT 0) -set (MONGOC_ENABLE_SSL_SECURE_CHANNEL 0) - -set (MONGOC_ENABLE_CRYPTO 0) -set (MONGOC_ENABLE_CRYPTO_LIBCRYPTO 0) -set (MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO 0) -set (MONGOC_ENABLE_CRYPTO_CNG 0) - -set (MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE 0) - -set (MONGOC_ENABLE_COMPRESSION 0) -set (MONGOC_ENABLE_COMPRESSION_SNAPPY 0) -set (MONGOC_ENABLE_COMPRESSION_ZLIB 0) -set (MONGOC_ENABLE_COMPRESSION_ZSTD 0) - -set (MONGOC_OUTPUT_BASENAME "mongoc" CACHE STRING "Output mongoc library base name") - -if (ENABLE_COVERAGE) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g --coverage") -endif () - -if (NOT ENABLE_ZLIB MATCHES "SYSTEM|AUTO|BUNDLED|OFF") - message (FATAL_ERROR - "ENABLE_ZLIB option must be SYSTEM, BUNDLED, AUTO, or OFF" - ) -endif () - -if (NOT ENABLE_ZSTD MATCHES "ON|AUTO|OFF") - message (FATAL_ERROR "ENABLE_ZSTD option must be ON, AUTO, or OFF") -endif () - -# Disable warnings on bundled zlib source files. -set_source_files_properties (${ZLIB_SOURCES} PROPERTIES COMPILE_FLAGS -w) - -# Copy zconf.h.in to zconf.h; even when using system zlib, the 'dist' target -# will look for zconf.h in that location. -configure_file ( - "${SOURCE_DIR}/src/zlib-1.2.11/zconf.h.in" - "${CMAKE_BINARY_DIR}/src/zlib-1.2.11/zconf.h" - COPYONLY -) -if (ENABLE_ZLIB MATCHES "SYSTEM|AUTO") - message (STATUS "Searching for zlib CMake packages") - include (FindZLIB) - if (ZLIB_FOUND) - message ("-- zlib found version \"${ZLIB_VERSION_STRING}\"") - message ("-- zlib include path \"${ZLIB_INCLUDE_DIRS}\"") - message ("-- zlib libraries \"${ZLIB_LIBRARIES}\"") - else () - if (ENABLE_ZLIB STREQUAL "SYSTEM") - message (FATAL_ERROR - "Unable to find system zlib package. Either specify the zlib \ - location by setting ZLIB_ROOT, or else set ENABLE_ZLIB=BUNDLED or \ - set ENABLE_ZLIB=OFF." - ) - endif () - set (ZLIB_LIBRARIES "") - endif () -endif () - -set (PRIVATE_ZLIB_INCLUDES "") -if ( (ENABLE_ZLIB STREQUAL "BUNDLED") - OR (ENABLE_ZLIB STREQUAL "AUTO" AND NOT ZLIB_FOUND) ) - message (STATUS "Enabling zlib compression (bundled)") - set (SOURCES ${SOURCES} ${ZLIB_SOURCES}) - set ( - PRIVATE_ZLIB_INCLUDES - "${SOURCE_DIR}/src/zlib-1.2.11" - "${CMAKE_BINARY_DIR}/src/zlib-1.2.11" - ) -endif () - -if (NOT ENABLE_ZLIB STREQUAL "OFF") - # At this point the system zlib was found, or the bundled library was used - include (CheckIncludeFiles) - check_include_files ("unistd.h" HAVE_UNISTD_H) - check_include_files ("stdarg.h" HAVE_STDARG_H) - set (MONGOC_ENABLE_COMPRESSION 1) - set (MONGOC_ENABLE_COMPRESSION_ZLIB 1) -else () - message (STATUS "Disabling zlib compression") -endif () - - -if (NOT ENABLE_ZSTD STREQUAL OFF) - message (STATUS "Searching for compression library zstd") - find_package(PkgConfig) - pkg_check_modules (ZSTD libzstd) - - if (NOT ZSTD_FOUND) - if (ENABLE_ZSTD MATCHES "ON") - message (FATAL_ERROR " Not found") - else () - message (STATUS " Not found") - endif () - # The compression format below this version isn't supported. See SERVER-43070 - elseif (${ZSTD_VERSION} VERSION_LESS "0.8.0") - if (ENABLE_ZSTD MATCHES "ON") - message (FATAL_ERROR "Detected zstd version ${ZSTD_VERSION} but version 0.8.0 required") - else () - message (STATUS "Detected zstd version ${ZSTD_VERSION} but version 0.8.0 required") - endif () - else () - message (STATUS " Found in ${ZSTD_INCLUDE_DIRS}") - set (MONGOC_ENABLE_COMPRESSION 1) - set (MONGOC_ENABLE_COMPRESSION_ZSTD 1) - set (MONGOC_INTERNAL_INCLUDE_DIRS ${MONGOC_INTERNAL_INCLUDE_DIRS} ${ZSTD_INCLUDE_DIRS}) - - if (${CMAKE_VERSION} VERSION_LESS "3.12.0") - link_directories(${ZSTD_LIBRARY_DIRS}) - set (MONGOC_ZSTD_LIBRARIES ${ZSTD_LIBRARIES}) - else () - set (MONGOC_ZSTD_LIBRARIES ${ZSTD_LINK_LIBRARIES}) - endif () - endif() -endif() - -if (NOT ENABLE_SSL STREQUAL OFF) - # Try OpenSSL automatically everywhere but Mac and Windows. - if (ENABLE_SSL STREQUAL "OPENSSL" - OR (NOT APPLE AND NOT WIN32 AND ENABLE_SSL STREQUAL "AUTO")) - # Sets OPENSSL_FOUND on success. - include (FindOpenSSL) - endif () - - if (ENABLE_SSL STREQUAL LIBRESSL) - include (FindPkgConfig) - message ("-- Searching for LibreSSL/libtls") - pkg_check_modules (LIBRESSL libtls) - if (LIBRESSL_FOUND) - message ("-- Found ${LIBRESSL_LIBRARIES}") - set (SSL_LIBRARIES ${LIBRESSL_LIBRARIES}) - if (LIBRESSL_INCLUDE_DIRS) - include_directories ("${LIBRESSL_INCLUDE_DIRS}") - endif () - link_directories ("${LIBRESSL_LIBRARY_DIRS}") - set (LIBRESSL 1) - else () - message ("-- Not found") - endif () - endif () - - if (ENABLE_SSL STREQUAL DARWIN OR (APPLE AND ENABLE_SSL STREQUAL "AUTO")) - if (APPLE) - set (SECURE_TRANSPORT 1) - else () - message (FATAL_ERROR "ENABLE_SSL=DARWIN only supported on Mac OS X") - endif () - endif () - - if (ENABLE_SSL STREQUAL WINDOWS OR (WIN32 AND ENABLE_SSL STREQUAL "AUTO")) - if (WIN32) - set (SECURE_CHANNEL 1) - else () - message (FATAL_ERROR "ENABLE_SSL=WINDOWS only supported on Windows") - endif () - endif () - - if (NOT OPENSSL_FOUND AND NOT SECURE_TRANSPORT AND NOT SECURE_CHANNEL AND NOT LIBRESSL) - if (ENABLE_SSL STREQUAL AUTO) - set (ENABLE_SSL OFF) - else () - message (FATAL_ERROR "No SSL library found") - endif () - endif () -endif () - -if (OPENSSL_FOUND) - if (WIN32 AND OPENSSL_VERSION GREATER 1.1 AND NOT - ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.7) - message (FATAL_ERROR "Building against OpenSSL 1.1.0 and later requires CMake 3.7 or later (hint:" - " You can also compile against Windows Secure Transport with -DENABLE_SSL=WINDOWS") - endif () - if (APPLE AND NOT OPENSSL_ROOT_DIR) - message (WARNING "Building with OpenSSL but OPENSSL_ROOT_DIR not defined. If build fails to link" - " to OpenSSL, define OPENSSL_ROOT_DIR as the path to the OpenSSL installation directory.") - endif () - include (CheckLibraryExists) - # Check for newer OpenSSL string function. - check_library_exists ("${OPENSSL_CRYPTO_LIBRARY}" - ASN1_STRING_get0_data "openssl/asn1.h" HAVE_ASN1_STRING_GET0_DATA - ) - if (HAVE_ASN1_STRING_GET0_DATA) - set (MONGOC_HAVE_ASN1_STRING_GET0_DATA 1) - endif () - set (MONGOC_ENABLE_SSL 1) - set (MONGOC_ENABLE_SSL_OPENSSL 1) - set (MONGOC_ENABLE_CRYPTO 1) - set (MONGOC_ENABLE_CRYPTO_LIBCRYPTO 1) -elseif (SECURE_TRANSPORT) - set (MONGOC_ENABLE_SSL 1) - set (MONGOC_ENABLE_SSL_SECURE_TRANSPORT 1) - set (MONGOC_ENABLE_CRYPTO 1) - set (MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO 1) -elseif (SECURE_CHANNEL) - set (MONGOC_ENABLE_SSL 1) - set (MONGOC_ENABLE_SSL_SECURE_CHANNEL 1) - set (MONGOC_ENABLE_CRYPTO 1) - set (MONGOC_ENABLE_CRYPTO_CNG 1) -elseif (LIBRESSL) - set (MONGOC_ENABLE_SSL 1) - set (MONGOC_ENABLE_SSL_LIBRESSL 1) - set (MONGOC_ENABLE_CRYPTO 1) - set (MONGOC_ENABLE_CRYPTO_LIBCRYPTO 1) -endif () - -if (ENABLE_CRYPTO_SYSTEM_PROFILE) - if (OPENSSL_FOUND) - set (MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE 1) - else () - message (FATAL_ERROR "ENABLE_CRYPTO_SYSTEM_PROFILE only available with OpenSSL") - endif () -endif () - -if (NOT ENABLE_SASL MATCHES "CYRUS|SSPI|AUTO|OFF") - message (FATAL_ERROR - "ENABLE_SASL option must be CYRUS, SSPI, AUTO, or OFF") -endif () - -# Defaults. -set (MONGOC_ENABLE_SASL 0) -set (MONGOC_ENABLE_SASL_CYRUS 0) -set (MONGOC_ENABLE_SASL_SSPI 0) -set (MONGOC_HAVE_SASL_CLIENT_DONE 0) - -if (NOT ENABLE_SASL STREQUAL OFF) - if ( (ENABLE_SASL MATCHES "SSPI|AUTO") AND WIN32) - set (MONGOC_ENABLE_SASL 1) - set (MONGOC_ENABLE_SASL_SSPI 1) - elseif (ENABLE_SASL MATCHES "AUTO|CYRUS") - # Sets SASL_LIBRARIES. - include (FindSASL2) - if (SASL_FOUND) - set (MONGOC_ENABLE_SASL 1) - set (MONGOC_ENABLE_SASL_CYRUS 1) - elseif (ENABLE_SASL STREQUAL "CYRUS") - message (FATAL_ERROR "ENABLE_SASL=CYRUS could not be satisfied") - endif() - endif () -endif () - - -if (ENABLE_AUTOMATIC_INIT_AND_CLEANUP) - set (MONGOC_NO_AUTOMATIC_GLOBALS 0) -else () - set (MONGOC_NO_AUTOMATIC_GLOBALS 1) -endif () - -include (CheckTypeSize) -if (WIN32) - SET (CMAKE_EXTRA_INCLUDE_FILES "ws2tcpip.h") -else () - SET (CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") -endif () -CHECK_TYPE_SIZE (socklen_t HAVE_SOCKLEN) -SET (CMAKE_EXTRA_INCLUDE_FILES) - -if (HAVE_SOCKLEN) - set (MONGOC_HAVE_SOCKLEN 1) - set (MONGOC_SOCKET_ARG3 "socklen_t") -else () - set (MONGOC_HAVE_SOCKLEN 0) - set (MONGOC_SOCKET_ARG3 "int") -endif () - -include (FindResSearch) -include (CheckSchedGetCPU) - -function (mongoc_get_accept_args ARG2 ARG3) - SET (VAR 0) - foreach (ARG2_VAL "struct sockaddr" "void") - foreach (ARG3_VAL "socklen_t" "size_t" "int") - - MATH (EXPR VAR "${VAR}+1") - - FILE (WRITE ${CMAKE_CURRENT_BINARY_DIR}/accept_test${VAR}.c - "#include <sys/types.h> - #include <sys/socket.h> - - int main () - { - int a = 0; - ${ARG2_VAL} *b = 0; - ${ARG3_VAL} *c = 0; - accept (a, b, c); - return 0; - } - ") - - TRY_COMPILE (RES ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/accept_test${VAR}.c CMAKE_FLAGS - "-Werror -DCMAKE_CXX_LINK_EXECUTABLE='echo not linking now...'" OUTPUT_VARIABLE LOG2) - - if (RES) - message ( - STATUS - "Detected parameters: accept (int, ${ARG2_VAL} *, ${ARG3_VAL} *)") - - set (${ARG2} ${ARG2_VAL} PARENT_SCOPE) - set (${ARG3} ${ARG3_VAL} PARENT_SCOPE) - return () - endif () - - endforeach () - endforeach () - -endfunction () - -# Reasonable defaults. -set (MONGOC_SOCKET_ARG2 "struct sockaddr") -set (MONGOC_SOCKET_ARG3 "socklen_t") - -if (NOT WIN32) - mongoc_get_accept_args (MONGOC_SOCKET_ARG2 MONGOC_SOCKET_ARG3) -endif () - -set (MONGOC_API_VERSION 1.0) - -set (CPACK_PACKAGE_VERSION_MAJOR ${MONGOC_MAJOR_VERSION}) -set (CPACK_PACKAGE_VERSION_MINOR ${MONGOC_MINOR_VERSION}) - -set (MONGOC_CC ${CMAKE_C_COMPILER}) -set (MONGOC_USER_SET_CFLAGS ${CMAKE_C_FLAGS}) -set (MONGOC_USER_SET_LDFLAGS ${CMAKE_EXE_LINKER_FLAGS}) - -set (MONGOC_TRACE 0) - -if (ENABLE_TRACING) - set (MONGOC_TRACE 1) -endif () - -# Sets SNAPPY_LIBRARIES and SNAPPY_INCLUDE_DIRS. -include (FindSnappy) -if (SNAPPY_INCLUDE_DIRS) - set (MONGOC_ENABLE_COMPRESSION 1) - include_directories ("${SNAPPY_INCLUDE_DIRS}") -endif () - -set (MONGOC_ENABLE_SHM_COUNTERS 0) - -if (NOT ENABLE_SHM_COUNTERS MATCHES "ON|OFF|AUTO") - message (FATAL_ERROR "ENABLE_SHM_COUNTERS option must be ON, OFF, or AUTO") -endif () - -if (ENABLE_SHM_COUNTERS STREQUAL "AUTO") - if (UNIX AND NOT APPLE) - set (ENABLE_SHM_COUNTERS ON) - endif () -endif () - -if (ENABLE_SHM_COUNTERS STREQUAL "ON") - if (APPLE OR NOT UNIX) - message ( - FATAL_ERROR - "Shared memory performance counters not supported on Mac or Windows") - endif () - set (MONGOC_ENABLE_SHM_COUNTERS 1) - find_library(RT_LIBRARY rt HINTS /usr/lib32) - if (RT_LIBRARY) - set (SHM_LIBRARIES rt) - endif () -endif () - -if (NOT ENABLE_ICU MATCHES "AUTO|ON|OFF") - message (FATAL_ERROR, "ENABLE_ICU option must be AUTO, ON, or OFF") -endif() - -if (NOT ENABLE_ICU STREQUAL OFF) - if (ENABLE_ICU STREQUAL ON) - # do not suppress log output if find_package cannot find ICU - find_package (ICU COMPONENTS uc) - elseif (ENABLE_ICU STREQUAL AUTO) - find_package (ICU QUIET COMPONENTS uc) - endif() - if (ICU_FOUND) - set (MONGOC_ENABLE_ICU 1) - include_directories ("${ICU_INCLUDE_DIR}") - elseif (ENABLE_ICU STREQUAL ON) - message (FATAL_ERROR "No ICU library found. If ICU is installed in a non-standard directory, define ICU_ROOT as the ICU installation path.") - elseif (ENABLE_ICU STREQUAL AUTO) - message (STATUS "No ICU library found, SASLPrep disabled for SCRAM-SHA-256 authentication.") - message (STATUS "If ICU is installed in a non-standard directory, define ICU_ROOT as the ICU installation path.") - endif() -endif() - -# Configure client side encryption. -set (MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION 0) -if (NOT ENABLE_CLIENT_SIDE_ENCRYPTION MATCHES "AUTO|ON|OFF") - message (FATAL_ERROR, "ENABLE_CLIENT_SIDE_ENCRYPTION option must be AUTO, ON, or OFF") -endif () - -if (NOT MONGOC_ENABLE_SSL) - if (ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL ON) - message (FATAL_ERROR "SSL disabled, but is required for Client-Side Field Level Encryption support.") - elseif (ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL AUTO) - message (STATUS "SSL disabled. Configuring without Client-Side Field Level Encryption support.") - endif () -elseif (NOT ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL OFF) - message ("Searching for libmongocrypt") - find_package (mongocrypt) - if (mongocrypt_FOUND) - set (CLIENT_SIDE_ENCRYPTION_LIBRARIES mongo::mongocrypt) - get_target_property (LIBMONGOCRYPT_LOCATION mongo::mongocrypt LOCATION) - get_target_property (LIBMONGOCRYPT_INCLUDE_DIRECTORIES mongo::mongocrypt INTERFACE_INCLUDE_DIRECTORIES) - message ("-- libmongocrypt found at ${LIBMONGOCRYPT_LOCATION}") - message ("-- libmongocrypt include path ${LIBMONGOCRYPT_INCLUDE_DIRECTORIES}") - set (MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION 1) - elseif (ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL ON) - message (FATAL_ERROR "Required library (libmongocrypt) not found.") - else () - message (STATUS "libmongocrypt not found. Configuring without Client-Side Field Level Encryption support.") - endif () -endif () - -configure_file ( - "${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-config.h.in" - "${PROJECT_BINARY_DIR}/src/mongoc/mongoc-config.h" -) - -configure_file ( - "${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-version.h.in" - "${PROJECT_BINARY_DIR}/src/mongoc/mongoc-version.h" -) - -if (ENABLE_APPLE_FRAMEWORK) - configure_file ( - "${PROJECT_SOURCE_DIR}/src/mongoc/modules/module.modulemap.in" - "${PROJECT_BINARY_DIR}/src/mongoc/modules/module.modulemap" - ) -endif () - -include_directories ("${PROJECT_BINARY_DIR}/src") -include_directories ("${PROJECT_SOURCE_DIR}/src") -include_directories ("${PROJECT_SOURCE_DIR}/../../src/common") - -set (SOURCES ${SOURCES} - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-aggregate.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-apm.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-array.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-async.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-async-cmd.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-buffer.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulk-operation.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-change-stream.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-pool.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-side-encryption.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster-sasl.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-collection.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-compression.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-counters.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-array.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-cmd.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-change-stream.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-cmd-deprecated.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-find.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-find-cmd.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-find-opquery.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-legacy.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-array.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-database.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-error.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-find-and-modify.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-init.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-bucket.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-bucket-file.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-list.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-page.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-list.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-handshake.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-host-list.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-index.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-init.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-list.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-linux-distro-scanner.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-log.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-matcher.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-matcher-op.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-memcmp.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cmd.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-opts.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-opts-helpers.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-queue.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-read-concern.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-read-prefs.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rpc.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-description.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-stream.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-session.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-set.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-socket.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-buffered.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-buffered.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-file.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-gridfs.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-gridfs-download.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-gridfs-upload.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-socket.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-description.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-description-apm.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-scanner.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-uri.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-util.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-version-functions.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-write-command.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-write-command-legacy.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-write-concern.c - ${PROJECT_SOURCE_DIR}/../../src/common/common-b64.c - ${PROJECT_SOURCE_DIR}/../../src/common/common-md5.c -) - -set (HEADERS - ${PROJECT_BINARY_DIR}/src/mongoc/mongoc-config.h - ${PROJECT_BINARY_DIR}/src/mongoc/mongoc-version.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-apm.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulk-operation.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-change-stream.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-pool.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-side-encryption.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-collection.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-database.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-error.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-flags.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-find-and-modify.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-bucket.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-page.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-list.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-handshake.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-host-list.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-init.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-index.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-iovec.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-log.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-macros.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-matcher.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-opcode.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-prelude.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-read-concern.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-read-prefs.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-description.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-session.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-socket.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-libressl.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-openssl.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-buffered.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-file.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-gridfs.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-socket.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-description.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-uri.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-version-functions.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-write-concern.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls.h - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-ssl.h -) - -set (HEADERS_FORWARDING - ${PROJECT_SOURCE_DIR}/src/mongoc/forwarding/mongoc.h -) - -if (NOT ENABLE_SSL STREQUAL OFF) - set (SOURCES ${SOURCES} - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-scram.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-ssl.c - ) - - if (OPENSSL_FOUND) - message (STATUS "Compiling against OpenSSL") - set (SOURCES ${SOURCES} - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto-openssl.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand-openssl.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-openssl.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-openssl-bio.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-openssl.c - ) - set (SSL_LIBRARIES ${OPENSSL_LIBRARIES}) - include_directories (${OPENSSL_INCLUDE_DIR}) - if (WIN32) - set (SSL_LIBRARIES ${SSL_LIBRARIES} crypt32.lib) - endif () - elseif (SECURE_TRANSPORT) - message (STATUS "Compiling against Secure Transport") - set (SOURCES ${SOURCES} - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto-common-crypto.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand-common-crypto.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-secure-transport.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-secure-transport.c - ) - set (SSL_LIBRARIES "-framework CoreFoundation -framework Security") - elseif (SECURE_CHANNEL) - message (STATUS "Compiling against Secure Channel") - set (SOURCES ${SOURCES} - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto-cng.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand-cng.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-secure-channel.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-secure-channel.c - ) - set (SSL_LIBRARIES secur32.lib crypt32.lib Bcrypt.lib) - elseif (LIBRESSL) - message (STATUS "Compiling against LibreSSL") - set (SOURCES ${SOURCES} - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto-openssl.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand-openssl.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-libressl.c - ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-libressl.c - ) - set (SSL_LIBRARIES -ltls -lcrypto) - endif () -else () - message (STATUS "SSL disabled") -endif () # ENABLE_SSL - -if (MONGOC_ENABLE_SASL) - set (SOURCES ${SOURCES} ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-sasl.c) - if (MONGOC_ENABLE_SASL_CYRUS) - message (STATUS "Compiling against Cyrus SASL") - set (SOURCES ${SOURCES} ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster-cyrus.c) - set (SOURCES ${SOURCES} ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cyrus.c) - include_directories (${SASL_INCLUDE_DIRS}) - elseif (MONGOC_ENABLE_SASL_SSPI) - message (STATUS "Compiling against Windows SSPI") - set (SOURCES ${SOURCES} ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster-sspi.c) - set (SOURCES ${SOURCES} ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-sspi.c) - set (SASL_LIBRARIES secur32.lib crypt32.lib Shlwapi.lib) - endif () -else () - message (STATUS "SASL disabled") -endif () - - -set (THREADS_PREFER_PTHREAD_FLAG 1) -find_package (Threads REQUIRED) -if (CMAKE_USE_PTHREADS_INIT) - set (THREAD_LIB ${CMAKE_THREAD_LIBS_INIT}) -endif () - -set (LIBRARIES - ${SASL_LIBRARIES} ${SSL_LIBRARIES} ${SHM_LIBRARIES} ${RESOLV_LIBRARIES} - ${SNAPPY_LIBRARIES} ${ZLIB_LIBRARIES} ${MONGOC_ZSTD_LIBRARIES} Threads::Threads ${ICU_LIBRARIES} ${CLIENT_SIDE_ENCRYPTION_LIBRARIES} -) -set (STATIC_LIBRARIES - ${SASL_LIBRARIES} ${SSL_LIBRARIES} ${SHM_LIBRARIES} ${RESOLV_LIBRARIES} - ${SNAPPY_LIBRARIES} ${ZLIB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${ICU_LIBRARIES} ${CLIENT_SIDE_ENCRYPTION_LIBRARIES} -) - -if (WIN32) - set (LIBRARIES ${LIBRARIES} ws2_32) -endif () - -add_library (mongoc_shared SHARED ${SOURCES} ${HEADERS} ${HEADERS_FORWARDING}) -set_target_properties (mongoc_shared PROPERTIES CMAKE_CXX_VISIBILITY_PRESET hidden) -target_link_libraries (mongoc_shared PRIVATE ${LIBRARIES} PUBLIC ${BSON_LIBRARIES}) -target_include_directories (mongoc_shared BEFORE PUBLIC ${MONGOC_INTERNAL_INCLUDE_DIRS}) -target_include_directories (mongoc_shared PRIVATE ${PRIVATE_ZLIB_INCLUDES}) -target_compile_definitions (mongoc_shared PRIVATE MONGOC_COMPILATION) - -set_target_properties (mongoc_shared PROPERTIES VERSION 0.0.0 SOVERSION 0) -set_target_properties (mongoc_shared PROPERTIES OUTPUT_NAME "${MONGOC_OUTPUT_BASENAME}-${MONGOC_API_VERSION}" PREFIX "lib") - -if (MONGOC_ENABLE_STATIC) - add_library (mongoc_static STATIC ${SOURCES} ${HEADERS} ${HEADERS_FORWARDING}) - target_link_libraries (mongoc_static ${STATIC_LIBRARIES} ${BSON_STATIC_LIBRARIES}) - target_include_directories (mongoc_static BEFORE PUBLIC ${MONGOC_INTERNAL_INCLUDE_DIRS}) - target_include_directories (mongoc_static PRIVATE ${PRIVATE_ZLIB_INCLUDES}) - target_compile_definitions (mongoc_static - PUBLIC MONGOC_STATIC ${BSON_STATIC_PUBLIC_DEFINITIONS} - PRIVATE MONGOC_COMPILATION - ) - set_target_properties (mongoc_static PROPERTIES VERSION 0.0.0) - set_target_properties (mongoc_static PROPERTIES OUTPUT_NAME "${MONGOC_OUTPUT_BASENAME}-static-${MONGOC_API_VERSION}") -endif () - -if (ENABLE_APPLE_FRAMEWORK) - set_target_properties (mongoc_shared PROPERTIES - FRAMEWORK TRUE - MACOSX_FRAMEWORK_BUNDLE_VERSION ${MONGOC_VERSION} - MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${MONGOC_VERSION} - MACOSX_FRAMEWORK_IDENTIFIER org.mongodb.mongoc - OUTPUT_NAME "${MONGOC_OUTPUT_BASENAME}" - PUBLIC_HEADER "${HEADERS}" - ) -endif () - -add_executable (mongoc-stat ${PROJECT_SOURCE_DIR}/../../src/tools/mongoc-stat.c) -target_link_libraries (mongoc-stat mongoc_shared ${LIBRARIES}) - -# mongoc-stat works if shared memory performance counters are enabled. -if (ENABLE_SHM_COUNTERS STREQUAL "ON") - install (PROGRAMS ${PROJECT_BINARY_DIR}/mongoc-stat - DESTINATION ${CMAKE_INSTALL_BINDIR} - ) -endif () - -function (mongoc_add_test test use_shared) - if (ENABLE_TESTS) - add_executable (${test} ${ARGN}) - if (NOT MSVC) - # We've tests that test our deprecated api. MSVC 2013 will complain about invalid flag - set_source_files_properties (${ARGN} PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations) - endif () - target_include_directories (${test} PRIVATE ${PROJECT_SOURCE_DIR}/tests) - target_compile_definitions (${test} PUBLIC "MONGOC_COMPILATION" PUBLIC "BSON_COMPILATION") - if (${use_shared}) - target_link_libraries (${test} mongoc_shared ${LIBRARIES}) - target_include_directories (${test} PRIVATE ${BSON_INCLUDE_DIRS} ${MONGOC_INTERNAL_INCLUDE_DIRS}) - else () - target_link_libraries (${test} mongoc_static ${LIBRARIES}) - target_include_directories (${test} PRIVATE ${BSON_STATIC_INCLUDE_DIRS} ${MONGOC_INTERNAL_INCLUDE_DIRS}) - endif () - target_link_libraries (${test} ${RESOLV_LIBRARIES}) - if (WIN32) - target_link_libraries (${test} shlwapi) - else () - target_link_libraries (${test}) - endif () - endif () -endfunction () - -function (mongoc_add_example example use_shared) - if (ENABLE_EXAMPLES) - add_executable (${example} ${ARGN}) - if (${use_shared}) - target_link_libraries (${example} mongoc_shared ${LIBRARIES}) - else () - target_link_libraries (${example} mongoc_static ${LIBRARIES}) - endif () - if (WIN32) - target_link_libraries (${example} shlwapi) - endif () - set (EXAMPLES ${EXAMPLES} ${example}) - endif () -endfunction () - -set (test-libmongoc-sources - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/corpus-test.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/corpus-test.h - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-atomic.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-bson.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-bson-corpus.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-bson-error.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-bson-version.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-endian.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-clock.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-decimal128.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-iso8601.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-iter.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-json.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-oid.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-reader.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-string.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-utf8.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-value.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-writer.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-bcon-basic.c - ${PROJECT_SOURCE_DIR}/../../src/libbson/tests/test-bcon-extract.c - ${PROJECT_SOURCE_DIR}/tests/debug-stream.c - ${PROJECT_SOURCE_DIR}/tests/json-test.c - ${PROJECT_SOURCE_DIR}/tests/json-test-monitoring.c - ${PROJECT_SOURCE_DIR}/tests/json-test-operations.c - ${PROJECT_SOURCE_DIR}/tests/mock_server/future.c - ${PROJECT_SOURCE_DIR}/tests/mock_server/future-functions.c - ${PROJECT_SOURCE_DIR}/tests/mock_server/future-value.c - ${PROJECT_SOURCE_DIR}/tests/mock_server/sync-queue.c - ${PROJECT_SOURCE_DIR}/tests/mock_server/mock-rs.c - ${PROJECT_SOURCE_DIR}/tests/mock_server/mock-server.c - ${PROJECT_SOURCE_DIR}/tests/mock_server/request.c - ${PROJECT_SOURCE_DIR}/tests/test-conveniences.c - ${PROJECT_SOURCE_DIR}/tests/test-libmongoc.c - ${PROJECT_SOURCE_DIR}/tests/test-happy-eyeballs.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-aggregate.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-array.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-async.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-buffer.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-bulk.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-change-stream.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-client.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-client-pool.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-client-side-encryption.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-cluster.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-collection.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-collection-find.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-collection-find-with-opts.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-connection-uri.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-command-monitoring.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-counters.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-crud.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-cursor.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-database.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-error.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-exhaust.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-find-and-modify.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-gridfs.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-gridfs-bucket.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-gridfs-file-page.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-handshake.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-linux-distro-scanner.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-list.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-log.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-matcher.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-max-staleness.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-mongos-pinning.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-opts.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-queue.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-primary-stepdown.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-read-concern.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-read-write-concern.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-read-prefs.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-retryable-writes.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-retryable-reads.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-rpc.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-sample-commands.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-scram.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-sdam.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-sdam-monitoring.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-selection.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-selection-errors.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-transactions.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-client-session.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-set.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-socket.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-dns.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-stream.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-thread.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-topology.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-topology-description.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-topology-reconcile.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-topology-scanner.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-uri.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-version.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-usleep.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-util.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-with-transaction.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-write-commands.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-write-concern.c - ${PROJECT_SOURCE_DIR}/tests/TestSuite.c -) - -if (MONGOC_ENABLE_SSL) - set (test-libmongoc-sources ${test-libmongoc-sources} - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-x509.c - ${PROJECT_SOURCE_DIR}/tests/ssl-test.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-stream-tls.c - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-stream-tls-error.c - ) -endif () - -if (MONGOC_ENABLE_SASL_CYRUS) - set (test-libmongoc-sources ${test-libmongoc-sources} - ${PROJECT_SOURCE_DIR}/tests/test-mongoc-cyrus.c - ) -endif () - -mongoc_add_test (test-libmongoc FALSE ${test-libmongoc-sources}) -mongoc_add_test (test-mongoc-gssapi TRUE ${PROJECT_SOURCE_DIR}/tests/test-mongoc-gssapi.c) - -if (ENABLE_TESTS) - enable_testing () - add_test (NAME test-libmongoc - COMMAND test-libmongoc - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/../.. - ) - - # "make test" doesn't compile tests, so we create "make check" which compiles - # and runs tests: https://gitlab.kitware.com/cmake/cmake/issues/8774 - add_custom_target (check COMMAND ${CMAKE_CTEST_COMMAND} -V - DEPENDS test-libmongoc - ) -endif () - -# examples/ -mongoc_add_example (example-client TRUE ${PROJECT_SOURCE_DIR}/examples/example-client.c) -mongoc_add_example (example-collection-watch TRUE ${PROJECT_SOURCE_DIR}/examples/example-collection-watch.c) -if (NOT WIN32) - mongoc_add_example (example-resume TRUE ${PROJECT_SOURCE_DIR}/examples/example-resume.c) -endif() -mongoc_add_example (example-start-at-optime TRUE ${PROJECT_SOURCE_DIR}/examples/example-start-at-optime.c) -mongoc_add_example (example-command-monitoring TRUE ${PROJECT_SOURCE_DIR}/examples/example-command-monitoring.c) -mongoc_add_example (example-command-with-opts TRUE ${PROJECT_SOURCE_DIR}/examples/example-command-with-opts.c) -mongoc_add_example (example-create-indexes TRUE ${PROJECT_SOURCE_DIR}/examples/example-create-indexes.c) -mongoc_add_example (example-gridfs TRUE ${PROJECT_SOURCE_DIR}/examples/example-gridfs.c) -mongoc_add_example (example-gridfs-bucket TRUE ${PROJECT_SOURCE_DIR}/examples/example-gridfs-bucket.c) -if (NOT WIN32 AND ENABLE_EXAMPLES) - mongoc_add_example (example-pool TRUE ${PROJECT_SOURCE_DIR}/examples/example-pool.c) - target_link_libraries (example-pool Threads::Threads) -endif () -mongoc_add_example (example-scram TRUE ${PROJECT_SOURCE_DIR}/examples/example-scram.c) -mongoc_add_example (example-sdam-monitoring TRUE ${PROJECT_SOURCE_DIR}/examples/example-sdam-monitoring.c) -mongoc_add_example (example-session TRUE ${PROJECT_SOURCE_DIR}/examples/example-session.c) -mongoc_add_example (example-transaction TRUE ${PROJECT_SOURCE_DIR}/examples/example-transaction.c) -mongoc_add_example (example-update TRUE ${PROJECT_SOURCE_DIR}/examples/example-update.c) -mongoc_add_example (find-and-modify TRUE ${PROJECT_SOURCE_DIR}/examples/find-and-modify.c) -mongoc_add_example (hello_mongoc TRUE ${PROJECT_SOURCE_DIR}/examples/hello_mongoc.c) -mongoc_add_example (mongoc-dump TRUE ${PROJECT_SOURCE_DIR}/examples/mongoc-dump.c) -mongoc_add_example (mongoc-ping TRUE ${PROJECT_SOURCE_DIR}/examples/mongoc-ping.c) -mongoc_add_example (mongoc-tail TRUE ${PROJECT_SOURCE_DIR}/examples/mongoc-tail.c) - -# examples/aggregation/ -mongoc_add_example (aggregation1 TRUE ${PROJECT_SOURCE_DIR}/examples/aggregation/aggregation1.c) - -# examples/basic_aggregation/ -mongoc_add_example (basic-aggregation TRUE ${PROJECT_SOURCE_DIR}/examples/basic_aggregation/basic-aggregation.c) - -# examples/bulk/ -mongoc_add_example (bulk-collation TRUE ${PROJECT_SOURCE_DIR}/examples/bulk/bulk-collation.c) -mongoc_add_example (bulk1 TRUE ${PROJECT_SOURCE_DIR}/examples/bulk/bulk1.c) -mongoc_add_example (bulk2 TRUE ${PROJECT_SOURCE_DIR}/examples/bulk/bulk2.c) -mongoc_add_example (bulk3 TRUE ${PROJECT_SOURCE_DIR}/examples/bulk/bulk3.c) -mongoc_add_example (bulk4 TRUE ${PROJECT_SOURCE_DIR}/examples/bulk/bulk4.c) -mongoc_add_example (bulk5 TRUE ${PROJECT_SOURCE_DIR}/examples/bulk/bulk5.c) -mongoc_add_example (bulk6 TRUE ${PROJECT_SOURCE_DIR}/examples/bulk/bulk6.c) - -# examples/common_operations/ -mongoc_add_example (common-operations TRUE ${PROJECT_SOURCE_DIR}/examples/common_operations/common-operations.c) - -# examples/find_and_modify_with_opts/ -mongoc_add_example (fam TRUE ${PROJECT_SOURCE_DIR}/examples/find_and_modify_with_opts/fam.c) - -file (COPY ${PROJECT_SOURCE_DIR}/tests/binary DESTINATION ${PROJECT_BINARY_DIR}/tests) -file (COPY ${PROJECT_SOURCE_DIR}/tests/json DESTINATION ${PROJECT_BINARY_DIR}/tests) -file (COPY ${PROJECT_SOURCE_DIR}/tests/x509gen DESTINATION ${PROJECT_BINARY_DIR}/tests) -file (COPY ${PROJECT_SOURCE_DIR}/tests/release_files DESTINATION ${PROJECT_BINARY_DIR}/tests) - -if (MONGOC_ENABLE_STATIC) - set (TARGETS_TO_INSTALL mongoc_shared mongoc_static) -else () - set (TARGETS_TO_INSTALL mongoc_shared) -endif () - -set (MONGOC_HEADER_INSTALL_DIR - "${CMAKE_INSTALL_INCLUDEDIR}/libmongoc-${MONGOC_API_VERSION}" -) - -install ( - TARGETS ${TARGETS_TO_INSTALL} ${EXAMPLES} - EXPORT mongoc-targets - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - INCLUDES DESTINATION ${MONGOC_HEADER_INSTALL_DIR} - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} -) - -install ( - FILES ${HEADERS} - DESTINATION "${MONGOC_HEADER_INSTALL_DIR}/mongoc" -) - -install ( - FILES ${HEADERS_FORWARDING} - DESTINATION "${MONGOC_HEADER_INSTALL_DIR}" -) - -if (ENABLE_APPLE_FRAMEWORK) - install ( - FILES "${PROJECT_BINARY_DIR}/src/mongoc/modules/module.modulemap" - DESTINATION "${CMAKE_INSTALL_BINDIR}/mongoc.framework/Modules/" - ) -endif () - -# Define pkg-config files -set (VERSION "${MONGOC_VERSION}") -set (prefix "${CMAKE_INSTALL_PREFIX}") -set (libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}") - -foreach ( - FLAG - ${SASL_LIBRARIES} ${SSL_LIBRARIES} ${SHM_LIBRARIES} ${RESOLV_LIBRARIES} - ${THREAD_LIB} ${ZLIB_LIBRARIES} ${SNAPPY_LIBRARIES} ${ZSTD_LINK_LIBRARIES} ${ICU_LIBRARIES}) - - if (IS_ABSOLUTE "${FLAG}") - get_filename_component (FLAG_DIR "${FLAG}" DIRECTORY) - get_filename_component (FLAG_FILE "${FLAG}" NAME_WE) - STRING (REGEX REPLACE "^lib" "" FLAG_FILE "${FLAG_FILE}") - set (MONGOC_LIBRARIES "${MONGOC_LIBRARIES} -L${FLAG_DIR} -l${FLAG_FILE}") - elseif (FLAG MATCHES "^-.*") - # Flag starts with dash, add it as-is. - set (MONGOC_LIBRARIES "${MONGOC_LIBRARIES} ${FLAG}") - else () - # Flag doesn't start with dash, add it with a dash. - set (MONGOC_LIBRARIES "${MONGOC_LIBRARIES} -l${FLAG}") - endif () -endforeach () - -configure_file ( - ${CMAKE_CURRENT_SOURCE_DIR}/src/libmongoc-1.0.pc.in - ${CMAKE_CURRENT_BINARY_DIR}/src/libmongoc-1.0.pc -@ONLY) -install ( - FILES ${CMAKE_CURRENT_BINARY_DIR}/src/libmongoc-1.0.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig -) -if (MONGOC_ENABLE_STATIC) - configure_file ( - ${CMAKE_CURRENT_SOURCE_DIR}/src/libmongoc-static-1.0.pc.in - ${CMAKE_CURRENT_BINARY_DIR}/src/libmongoc-static-1.0.pc - @ONLY) - install ( - FILES ${CMAKE_CURRENT_BINARY_DIR}/src/libmongoc-static-1.0.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig - ) -endif () -# Deprecated alias for libmongoc-1.0.pc, see CDRIVER-2086. -if (MONGOC_ENABLE_SSL) - configure_file ( - ${CMAKE_CURRENT_SOURCE_DIR}/src/libmongoc-ssl-1.0.pc.in - ${CMAKE_CURRENT_BINARY_DIR}/src/libmongoc-ssl-1.0.pc - @ONLY) - install ( - FILES ${CMAKE_CURRENT_BINARY_DIR}/src/libmongoc-ssl-1.0.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig - ) -endif () - -include (CMakePackageConfigHelpers) -set (INCLUDE_INSTALL_DIRS "${MONGOC_HEADER_INSTALL_DIR}") -set (LIBRARY_INSTALL_DIRS ${CMAKE_INSTALL_LIBDIR}) - -write_basic_package_version_file ( - "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-${MONGOC_API_VERSION}-config-version.cmake" - VERSION ${MONGOC_VERSION} - COMPATIBILITY AnyNewerVersion -) - -export (EXPORT mongoc-targets - NAMESPACE mongo:: - FILE "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-targets.cmake" -) - -configure_file (src/mongoc-config.cmake - "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-${MONGOC_API_VERSION}-config.cmake" - @ONLY -) - -install (EXPORT mongoc-targets - NAMESPACE mongo:: - FILE mongoc-targets.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mongoc-${MONGOC_API_VERSION} -) - -install ( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-${MONGOC_API_VERSION}-config.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-${MONGOC_API_VERSION}-config-version.cmake" - DESTINATION - ${CMAKE_INSTALL_LIBDIR}/cmake/mongoc-${MONGOC_API_VERSION} - COMPONENT - Devel -) - -if (ENABLE_MAN_PAGES STREQUAL ON OR ENABLE_HTML_DOCS STREQUAL ON) - find_package (Sphinx REQUIRED) - add_subdirectory (doc) - add_custom_target (mongoc-doc - ALL - DEPENDS - $<$<STREQUAL:"${ENABLE_MAN_PAGES}","ON">:mongoc-man> - $<$<STREQUAL:"${ENABLE_HTML_DOCS}","ON">:mongoc-html> - ) -endif () - -add_subdirectory (build) -# sub-directory 'doc' was already included above -add_subdirectory (examples) -add_subdirectory (src) -add_subdirectory (tests) - -set_local_dist (src_libmongoc_DIST_local - CMakeLists.txt - THIRD_PARTY_NOTICES -) - -set (src_libmongoc_DIST - ${src_libmongoc_DIST_local} - ${src_libmongoc_build_DIST} - ${src_libmongoc_doc_DIST} - ${src_libmongoc_examples_DIST} - ${src_libmongoc_src_DIST} - ${src_libmongoc_tests_DIST} - PARENT_SCOPE -) diff --git a/lib/mongoc/libmongoc/THIRD_PARTY_NOTICES b/lib/mongoc/libmongoc/THIRD_PARTY_NOTICES deleted file mode 100644 index 2bba00a5b0e8d9fc94757f711accff955220424e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/THIRD_PARTY_NOTICES +++ /dev/null @@ -1,56 +0,0 @@ -The MongoDB C Driver uses third-party code distributed under different licenses. - -License notice for mongoc-stream-tls-secure-channel.c -------------------------------------------------------------------------------- - -Curl License - -Significant portions of mongoc-stream-tls-secure-channel.c are from Curl. - -Copyright (C) 2012 - 2015, Marc Hoersken, <info@marc-hoersken.de> -Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> -Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. - -All rights reserved. - -Permission to use, copy, modify, and distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright -notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. - - -License notice for utlist.h -------------------------------------------------------------------------------- - -BSD 1-Clause License - -Copyright: 2007-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/mongoc/libmongoc/build/CMakeLists.txt b/lib/mongoc/libmongoc/build/CMakeLists.txt deleted file mode 100644 index be72c52c638119486498bb377a72d3fd3a0093f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/build/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_subdirectory (cmake) - -set_local_dist (src_libmongoc_build_DIST_local - CMakeLists.txt -) - -set (src_libmongoc_build_DIST - ${src_libmongoc_build_DIST_local} - ${src_libmongoc_build_cmake_DIST} - PARENT_SCOPE -) diff --git a/lib/mongoc/libmongoc/build/cmake/CMakeLists.txt b/lib/mongoc/libmongoc/build/cmake/CMakeLists.txt deleted file mode 100644 index 0267cc404f318d137fcb1ca8ec29febe4af8f781..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/build/cmake/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set_local_dist (src_libmongoc_build_cmake_DIST_local - CMakeLists.txt -) - -set (src_libmongoc_build_cmake_DIST - ${src_libmongoc_build_cmake_DIST_local} - PARENT_SCOPE -) diff --git a/lib/mongoc/libmongoc/doc/.gitignore b/lib/mongoc/libmongoc/doc/.gitignore deleted file mode 100644 index 1deef7eda0c07f07e62c6ea36bd67bf42b8ab56f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*.7 -*.pyc -.doctrees -objects.inv -html/*.html -html/*.css -html/*.js -html/*.png -html/_sources -html/_static -html/_images/ -html/.buildinfo -html/.nojekyll -man/*.3 -man/.buildinfo diff --git a/lib/mongoc/libmongoc/doc/CMakeLists.txt b/lib/mongoc/libmongoc/doc/CMakeLists.txt deleted file mode 100644 index 25fa7f6824292e269e51e17d05d4bdaa33ecd7db..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -include (SphinxBuild) - -if (ENABLE_HTML_DOCS) - sphinx_build_html (mongoc-html mongo-c-driver) - set (src_libmongoc_doc_DIST_htmls ${doc_DIST_htmls}) -endif () - -if (ENABLE_MAN_PAGES) - sphinx_build_man (mongoc-man) - set (src_libmongoc_doc_DIST_mans ${doc_DIST_mans}) -endif () - -add_subdirectory (html) -add_subdirectory (includes) -add_subdirectory (man) -add_subdirectory (static) - -file (GLOB src_libmongoc_doc_DIST_rsts RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.rst) - -extra_dist_generated ( - ${src_libmongoc_doc_DIST_htmls} - ${src_libmongoc_doc_DIST_mans} -) - -set_local_dist (src_libmongoc_doc_DIST_local - CMakeLists.txt - ${src_libmongoc_doc_DIST_rsts} - conf.py - libbson-objects.inv -) - -set (src_libmongoc_doc_DIST - ${src_libmongoc_doc_DIST_local} - ${src_libmongoc_doc_html_DIST} - ${src_libmongoc_doc_includes_DIST} - ${src_libmongoc_doc_man_DIST} - ${src_libmongoc_doc_mongoc_DIST} - ${src_libmongoc_doc_mongoc-theme_DIST} - ${src_libmongoc_doc_static_DIST} - PARENT_SCOPE -) diff --git a/lib/mongoc/libmongoc/doc/advanced-connections.rst b/lib/mongoc/libmongoc/doc/advanced-connections.rst deleted file mode 100644 index 130ed9c59cb2606902ed94da24b55a0a2d728895..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/advanced-connections.rst +++ /dev/null @@ -1,196 +0,0 @@ -:man_page: mongoc_advanced_connections - -Advanced Connections -==================== - -The following guide contains information specific to certain types of MongoDB configurations. - -For an example of connecting to a simple standalone server, see the :ref:`Tutorial <tutorial_connecting>`. To establish a connection with authentication options enabled, see the :doc:`Authentication <authentication>` page. - -Connecting to a Replica Set ---------------------------- - -Connecting to a `replica set <http://docs.mongodb.org/manual/replication/>`_ is much like connecting to a standalone MongoDB server. Simply specify the replica set name using the ``?replicaSet=myreplset`` URI option. - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - - int - main (int argc, char *argv[]) - { - mongoc_client_t *client; - - mongoc_init (); - - /* Create our MongoDB Client */ - client = mongoc_client_new ( - "mongodb://host01:27017,host02:27017,host03:27017/?replicaSet=myreplset"); - - /* Do some work */ - /* TODO */ - - /* Clean up */ - mongoc_client_destroy (client); - mongoc_cleanup (); - - return 0; - } - -.. tip:: - - Multiple hostnames can be specified in the MongoDB connection string URI, with a comma separating hosts in the seed list. - - It is recommended to use a seed list of members of the replica set to allow the driver to connect to any node. - -Connecting to a Sharded Cluster -------------------------------- - -To connect to a `sharded cluster <http://docs.mongodb.org/manual/sharding/>`_, specify the ``mongos`` nodes the client should connect to. The C Driver will automatically detect that it has connected to a ``mongos`` sharding server. - -If more than one hostname is specified, a seed list will be created to attempt failover between the ``mongos`` instances. - -.. warning:: - - Specifying the ``replicaSet`` parameter when connecting to a ``mongos`` sharding server is invalid. - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - - int - main (int argc, char *argv[]) - { - mongoc_client_t *client; - - mongoc_init (); - - /* Create our MongoDB Client */ - client = mongoc_client_new ("mongodb://myshard01:27017/"); - - /* Do something with client ... */ - - /* Free the client */ - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return 0; - } - -Connecting to an IPv6 Address ------------------------------ - -The MongoDB C Driver will automatically resolve IPv6 addresses from host names. However, to specify an IPv6 address directly, wrap the address in ``[]``. - -.. code-block:: none - - mongoc_uri_t *uri = mongoc_uri_new ("mongodb://[::1]:27017"); - -Connecting with IPv4 and IPv6 ------------------------------ - -.. include:: includes/ipv4-and-ipv6.txt - -Connecting to a UNIX Domain Socket ----------------------------------- - -On UNIX-like systems, the C Driver can connect directly to a MongoDB server using a UNIX domain socket. Pass the URL-encoded path to the socket, which *must* be suffixed with ``.sock``. For example, to connect to a domain socket at ``/tmp/mongodb-27017.sock``: - -.. code-block:: none - - mongoc_uri_t *uri = mongoc_uri_new ("mongodb://%2Ftmp%2Fmongodb-27017.sock"); - -Include username and password like so: - -.. code-block:: none - - mongoc_uri_t *uri = mongoc_uri_new ("mongodb://user:pass@%2Ftmp%2Fmongodb-27017.sock"); - -Connecting to a server over SSL -------------------------------- - -These are instructions for configuring TLS/SSL connections. - -To run a server locally (on port 27017, for example): - -.. code-block:: none - - $ mongod --port 27017 --sslMode requireSSL --sslPEMKeyFile server.pem --sslCAFile ca.pem - -Add ``/?ssl=true`` to the end of a client URI. - -.. code-block:: none - - mongoc_client_t *client = NULL; - client = mongoc_client_new ("mongodb://localhost:27017/?ssl=true"); - -MongoDB requires client certificates by default, unless the ``--sslAllowConnectionsWithoutCertificates`` is provided. The C Driver can be configured to present a client certificate using a ``mongoc_ssl_opt_t``: - -.. code-block:: none - - const mongoc_ssl_opt_t *ssl_default = mongoc_ssl_opt_get_default (); - mongoc_ssl_opt_t ssl_opts = { 0 }; - - /* optionally copy in a custom trust directory or file; otherwise the default is used. */ - memcpy (&ssl_opts, ssl_default, sizeof ssl_opts); - ssl_opts.pem_file = "client.pem" - - mongoc_client_set_ssl_opts (client, &ssl_opts); - -The client certificate provided by ``pem_file`` must be issued by one of the server trusted Certificate Authorities listed in ``--sslCAFile``, or issued by a CA in the native certificate store on the server when omitted. - -To verify the server certificate against a specific CA, provide a PEM armored file with a CA certificate, or concatenated list of CA certificates using the ``ca_file`` option, or ``c_rehash`` directory structure of CAs, pointed to using the ``ca_dir`` option. When no ``ca_file`` or ``ca_dir`` is provided, the driver will use CAs provided by the native platform certificate store. - -See :doc:`mongoc_ssl_opt_t` for more information on the various SSL related options. - -Compressing data to and from MongoDB ------------------------------------- - -MongoDB 3.4 added Snappy compression support, zlib compression in 3.6, and zstd compression in 4.2. -To enable compression support the client must be configured with which compressors to use: - -.. code-block:: none - - mongoc_client_t *client = NULL; - client = mongoc_client_new ("mongodb://localhost:27017/?compressors=snappy,zlib,zstd"); - -The ``compressors`` option specifies the priority order of compressors the -client wants to use. Messages are compressed if the client and server share any -compressors in common. - -Note that the compressor used by the server might not be the same compressor as -the client used. For example, if the client uses the connection string -``compressors=zlib,snappy`` the client will use ``zlib`` compression to send -data (if possible), but the server might still reply using ``snappy``, -depending on how the server was configured. - -The driver must be built with zlib and/or snappy and/or zstd support to enable compression -support, any unknown (or not compiled in) compressor value will be ignored. Note: to build with zstd requires cmake 3.12 or higher. - -Additional Connection Options ------------------------------ - -The full list of connection options can be found in the :symbol:`mongoc_uri_t` docs. - -Certain socket/connection related options are not configurable: - -============== ===================================================== ====================== -Option Description Value -============== ===================================================== ====================== -SO_KEEPALIVE TCP Keep Alive Enabled --------------- ----------------------------------------------------- ---------------------- -TCP_KEEPIDLE How long a connection needs to remain idle before TCP 300 seconds - starts sending keepalive probes --------------- ----------------------------------------------------- ---------------------- -TCP_KEEPINTVL The time in seconds between TCP probes 10 seconds --------------- ----------------------------------------------------- ---------------------- -TCP_KEEPCNT How many probes to send, without acknowledgement, 9 probes - before dropping the connection --------------- ----------------------------------------------------- ---------------------- -TCP_NODELAY Send packets as soon as possible or buffer small Enabled (no buffering) - packets (Nagle algorithm) -============== ===================================================== ====================== - diff --git a/lib/mongoc/libmongoc/doc/aggregate.rst b/lib/mongoc/libmongoc/doc/aggregate.rst deleted file mode 100644 index 0103a5810526e81301abec43f9ac8d6b55fd49dc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/aggregate.rst +++ /dev/null @@ -1,138 +0,0 @@ -:man_page: mongoc_aggregate - -Aggregation Framework Examples -============================== - -This document provides a number of practical examples that display the capabilities of the aggregation framework. - -The `Aggregations using the Zip Codes Data Set <https://docs.mongodb.org/manual/tutorial/aggregation-zip-code-data-set/>`_ examples uses a publicly available data set of all zipcodes and populations in the United States. These data are available at: `zips.json <http://media.mongodb.org/zips.json>`_. - -Requirements ------------- - -Let's check if everything is installed. - -Use the following command to load zips.json data set into mongod instance: - -.. code-block:: none - - $ mongoimport --drop -d test -c zipcodes zips.json - -Let's use the MongoDB shell to verify that everything was imported successfully. - -.. code-block:: none - - $ mongo test - connecting to: test - > db.zipcodes.count() - 29467 - > db.zipcodes.findOne() - { - "_id" : "35004", - "city" : "ACMAR", - "loc" : [ - -86.51557, - 33.584132 - ], - "pop" : 6055, - "state" : "AL" - } - -Aggregations using the Zip Codes Data Set ------------------------------------------ - -Each document in this collection has the following form: - -.. code-block:: json - - { - "_id" : "35004", - "city" : "Acmar", - "state" : "AL", - "pop" : 6055, - "loc" : [-86.51557, 33.584132] - } - -In these documents: - -* The ``_id`` field holds the zipcode as a string. -* The ``city`` field holds the city name. -* The ``state`` field holds the two letter state abbreviation. -* The ``pop`` field holds the population. -* The ``loc`` field holds the location as a ``[latitude, longitude]`` array. - -States with Populations Over 10 Million ---------------------------------------- - -To get all states with a population greater than 10 million, use the following aggregation pipeline: - -.. literalinclude:: ../examples/aggregation/aggregation1.c - :language: c - :caption: aggregation1.c - -You should see a result like the following: - -.. code-block:: json - - { "_id" : "PA", "total_pop" : 11881643 } - { "_id" : "OH", "total_pop" : 10847115 } - { "_id" : "NY", "total_pop" : 17990455 } - { "_id" : "FL", "total_pop" : 12937284 } - { "_id" : "TX", "total_pop" : 16986510 } - { "_id" : "IL", "total_pop" : 11430472 } - { "_id" : "CA", "total_pop" : 29760021 } - -The above aggregation pipeline is build from two pipeline operators: ``$group`` and ``$match``. - -The ``$group`` pipeline operator requires _id field where we specify grouping; remaining fields specify how to generate composite value and must use one of the group aggregation functions: ``$addToSet``, ``$first``, ``$last``, ``$max``, ``$min``, ``$avg``, ``$push``, ``$sum``. The ``$match`` pipeline operator syntax is the same as the read operation query syntax. - -The ``$group`` process reads all documents and for each state it creates a separate document, for example: - -.. code-block:: json - - { "_id" : "WA", "total_pop" : 4866692 } - -The ``total_pop`` field uses the $sum aggregation function to sum the values of all pop fields in the source documents. - -Documents created by ``$group`` are piped to the ``$match`` pipeline operator. It returns the documents with the value of ``total_pop`` field greater than or equal to 10 million. - -Average City Population by State --------------------------------- - -To get the first three states with the greatest average population per city, use the following aggregation: - -.. code-block:: c - - pipeline = BCON_NEW ("pipeline", "[", - "{", "$group", "{", "_id", "{", "state", "$state", "city", "$city", "}", "pop", "{", "$sum", "$pop", "}", "}", "}", - "{", "$group", "{", "_id", "$_id.state", "avg_city_pop", "{", "$avg", "$pop", "}", "}", "}", - "{", "$sort", "{", "avg_city_pop", BCON_INT32 (-1), "}", "}", - "{", "$limit", BCON_INT32 (3) "}", - "]"); - -This aggregate pipeline produces: - -.. code-block:: json - - { "_id" : "DC", "avg_city_pop" : 303450.0 } - { "_id" : "FL", "avg_city_pop" : 27942.29805615551 } - { "_id" : "CA", "avg_city_pop" : 27735.341099720412 } - -The above aggregation pipeline is build from three pipeline operators: ``$group``, ``$sort`` and ``$limit``. - -The first ``$group`` operator creates the following documents: - -.. code-block:: json - - { "_id" : { "state" : "WY", "city" : "Smoot" }, "pop" : 414 } - -Note, that the ``$group`` operator can't use nested documents except the ``_id`` field. - -The second ``$group`` uses these documents to create the following documents: - -.. code-block:: json - - { "_id" : "FL", "avg_city_pop" : 27942.29805615551 } - -These documents are sorted by the ``avg_city_pop`` field in descending order. Finally, the ``$limit`` pipeline operator returns the first 3 documents from the sorted set. - diff --git a/lib/mongoc/libmongoc/doc/api.rst b/lib/mongoc/libmongoc/doc/api.rst deleted file mode 100644 index 8483047f6386e51b4ffacb4cb661276fc17eb286..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/api.rst +++ /dev/null @@ -1,59 +0,0 @@ -API Reference -============= - -.. toctree:: - :titlesonly: - :maxdepth: 1 - - init-cleanup - logging - errors - lifecycle - gridfs - mongoc_auto_encryption_opts_t - mongoc_bulk_operation_t - mongoc_change_stream_t - mongoc_client_pool_t - mongoc_client_session_t - mongoc_client_session_with_transaction_cb_t - mongoc_client_t - mongoc_collection_t - mongoc_cursor_t - mongoc_database_t - mongoc_delete_flags_t - mongoc_find_and_modify_opts_t - mongoc_gridfs_file_list_t - mongoc_gridfs_file_opt_t - mongoc_gridfs_file_t - mongoc_gridfs_bucket_t - mongoc_gridfs_t - mongoc_host_list_t - mongoc_index_opt_geo_t - mongoc_index_opt_t - mongoc_index_opt_wt_t - mongoc_insert_flags_t - mongoc_iovec_t - mongoc_matcher_t - mongoc_query_flags_t - mongoc_rand - mongoc_read_concern_t - mongoc_read_mode_t - mongoc_read_prefs_t - mongoc_remove_flags_t - mongoc_reply_flags_t - mongoc_server_description_t - mongoc_session_opt_t - mongoc_socket_t - mongoc_ssl_opt_t - mongoc_stream_buffered_t - mongoc_stream_file_t - mongoc_stream_socket_t - mongoc_stream_t - mongoc_stream_tls_t - mongoc_topology_description_t - mongoc_transaction_opt_t - mongoc_transaction_state_t - mongoc_update_flags_t - mongoc_uri_t - mongoc_version - mongoc_write_concern_t diff --git a/lib/mongoc/libmongoc/doc/application-performance-monitoring.rst b/lib/mongoc/libmongoc/doc/application-performance-monitoring.rst deleted file mode 100644 index 47f4bb487c544a9d26264da3efaaa96137d70c47..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/application-performance-monitoring.rst +++ /dev/null @@ -1,160 +0,0 @@ -:man_page: mongoc_application_performance_monitoring - -Application Performance Monitoring (APM) -======================================== - -The MongoDB C Driver allows you to monitor all the MongoDB operations the driver executes. This event-notification system conforms to two MongoDB driver specs: - -* `Command Monitoring <https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst>`_: events related to all application operations. -* `SDAM Monitoring <https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst>`_: events related to the driver's Server Discovery And Monitoring logic. - -To receive notifications, create a ``mongoc_apm_callbacks_t`` with :symbol:`mongoc_apm_callbacks_new`, set callbacks on it, then pass it to :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -Command-Monitoring Example --------------------------- - -.. literalinclude:: ../examples/example-command-monitoring.c - :language: c - :caption: example-command-monitoring.c - -This example program prints: - -.. code-block:: none - - Command drop started on 127.0.0.1: - { "drop" : "test" } - - Command drop succeeded: - { "ns" : "test.test", "nIndexesWas" : 1, "ok" : 1.0 } - - Command insert started on 127.0.0.1: - { - "insert" : "test", - "ordered" : true, - "documents" : [ - { "_id" : 0 }, { "_id" : 1 } - ] - } - - Command insert succeeded: - { "n" : 2, "ok" : 1.0 } - - Command insert started on 127.0.0.1: - { - "insert" : "test", - "ordered" : true, - "documents" : [ - { "_id" : 0 } - ] - } - - Command insert succeeded: - { - "n" : 0, - "writeErrors" : [ - { "index" : 0, "code" : 11000, "errmsg" : "duplicate key" } - ], - "ok" : 1.0 - } - - started: 3 - succeeded: 3 - failed: 0 - -The output has been edited and formatted for clarity. Depending on your server configuration, messages may include metadata like database name, logical session ids, or cluster times that are not shown here. - -The final "insert" command is considered successful, despite the writeError, because the server replied to the overall command with ``"ok": 1``. - -SDAM Monitoring Example ------------------------ - -.. literalinclude:: ../examples/example-sdam-monitoring.c - :language: c - :caption: example-sdam-monitoring.c - -Start a 3-node replica set on localhost with set name "rs" and start the program: - -.. code-block:: none - - ./example-sdam-monitoring "mongodb://localhost:27017,localhost:27018/?replicaSet=rs" - -This example program prints something like: - -.. code-block:: none - - topology opening - topology changed: Unknown -> ReplicaSetNoPrimary - secondary UNAVAILABLE - primary UNAVAILABLE - server opening: localhost:27017 - server opening: localhost:27018 - localhost:27017 heartbeat started - localhost:27018 heartbeat started - localhost:27017 heartbeat succeeded: { ... reply ... } - server changed: localhost:27017 Unknown -> RSPrimary - server opening: localhost:27019 - topology changed: ReplicaSetNoPrimary -> ReplicaSetWithPrimary - new servers: - RSPrimary localhost:27017 - secondary UNAVAILABLE - primary AVAILABLE - localhost:27019 heartbeat started - localhost:27018 heartbeat succeeded: { ... reply ... } - server changed: localhost:27018 Unknown -> RSSecondary - topology changed: ReplicaSetWithPrimary -> ReplicaSetWithPrimary - previous servers: - RSPrimary localhost:27017 - new servers: - RSPrimary localhost:27017 - RSSecondary localhost:27018 - secondary AVAILABLE - primary AVAILABLE - localhost:27019 heartbeat succeeded: { ... reply ... } - server changed: localhost:27019 Unknown -> RSSecondary - topology changed: ReplicaSetWithPrimary -> ReplicaSetWithPrimary - previous servers: - RSPrimary localhost:27017 - RSSecondary localhost:27018 - new servers: - RSPrimary localhost:27017 - RSSecondary localhost:27018 - RSSecondary localhost:27019 - secondary AVAILABLE - primary AVAILABLE - topology closed - - Events: - server changed: 3 - server opening: 3 - server closed: 0 - topology changed: 4 - topology opening: 1 - topology closed: 1 - heartbeat started: 3 - heartbeat succeeded: 3 - heartbeat failed: 0 - -The driver connects to the mongods on ports 27017 and 27018, which were specified in the URI, and determines which is primary. It also discovers the third member, "localhost:27019", and adds it to the topology. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_callbacks_t - mongoc_apm_command_failed_t - mongoc_apm_command_started_t - mongoc_apm_command_succeeded_t - mongoc_apm_server_changed_t - mongoc_apm_server_closed_t - mongoc_apm_server_heartbeat_failed_t - mongoc_apm_server_heartbeat_started_t - mongoc_apm_server_heartbeat_succeeded_t - mongoc_apm_server_opening_t - mongoc_apm_topology_changed_t - mongoc_apm_topology_closed_t - mongoc_apm_topology_opening_t diff --git a/lib/mongoc/libmongoc/doc/authentication.rst b/lib/mongoc/libmongoc/doc/authentication.rst deleted file mode 100644 index 2bcefeb85215860ef3e819b895944d0848a2c71e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/authentication.rst +++ /dev/null @@ -1,205 +0,0 @@ -:man_page: mongoc_authentication - -Authentication -============== - -This guide covers the use of authentication options with the MongoDB C Driver. Ensure that the MongoDB server is also properly configured for authentication before making a connection. For more information, see the `MongoDB security documentation <https://docs.mongodb.org/manual/administration/security/>`_. - -The MongoDB C driver supports several authentication mechanisms through the use of MongoDB connection URIs. - -By default, if a username and password are provided as part of the connection string (and an optional authentication database), they are used to connect via the default authentication mechanism of the server. - -To select a specific authentication mechanism other than the default, see the list of supported mechanism below. - -.. code-block:: none - - mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authSource=mydb"); - -Currently supported values for the authMechanism connection string option are: - -* :ref:`SCRAM-SHA-1 <authentication_scram_sha_1>` -* :ref:`MONGODB-CR (deprecated) <authentication_mongodbcr>` -* :ref:`GSSAPI <authentication_kerberos>` -* :ref:`PLAIN <authentication_plain>` -* :ref:`X509 <authentication_x509>` - -.. _authentication_scram_sha_256: - -Basic Authentication (SCRAM-SHA-256) ------------------------------------- - -MongoDB 4.0 introduces support for authenticating using the SCRAM protocol -with the more secure SHA-256 hash described in `RFC 7677 -<https://tools.ietf.org/html/rfc7677>`_. Using this authentication mechanism -means that the password is never actually sent over the wire when -authenticating, but rather a computed proof that the client password is the -same as the password the server knows. In MongoDB 4.0, the C driver can -determine the correct default authentication mechanism for users with stored -SCRAM-SHA-1 and SCRAM-SHA-256 credentials: - -.. code-block:: none - - mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authSource=mydb"); - /* the correct authMechanism is negotiated between the driver and server. */ - -Alternatively, SCRAM-SHA-256 can be explicitly specified as an authMechanism. - -.. code-block:: none - - mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256&authSource=mydb"); - -Passwords for SCRAM-SHA-256 undergo the preprocessing step known as SASLPrep -specified in `RFC 4013 <https://tools.ietf.org/html/rfc4013>`_. SASLPrep will -only be performed for passwords containing non-ASCII characters. SASLPrep -requires libicu. If libicu is not available, attempting to authenticate over -SCRAM-SHA-256 with non-ASCII passwords will result in error. - -Usernames *never* undergo SASLPrep. - -By default, when building the C driver libicu is linked if available. This can -be changed with the ``ENABLE_ICU`` cmake option. To specify an installation -path of libicu, specify ``ICU_ROOT`` as a cmake option. See the -`FindICU <https://cmake.org/cmake/help/v3.7/module/FindICU.html>`_ documentation -for more information. - - -.. _authentication_scram_sha_1: - -Basic Authentication (SCRAM-SHA-1) ----------------------------------- - -The default authentication mechanism before MongoDB 4.0 is ``SCRAM-SHA-1`` (`RFC 5802 <http://tools.ietf.org/html/rfc5802>`_). Using this authentication mechanism means that the password is never actually sent over the wire when authenticating, but rather a computed proof that the client password is the same as the password the server knows. - -.. code-block:: none - - mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-1&authSource=mydb"); - -.. note:: - - ``SCRAM-SHA-1`` authenticates against the ``admin`` database by default. If the user is created in another database, then specifying the authSource is required. - -.. _authentication_mongodbcr: - -Legacy Authentication (MONGODB-CR) ----------------------------------- - -The MONGODB-CR authMechanism is deprecated and will no longer function in MongoDB 4.0. Instead, specify no authMechanism and the driver -will use an authentication mechanism compatible with your server. - -.. _authentication_kerberos: - -GSSAPI (Kerberos) Authentication --------------------------------- - -.. note:: - - Kerberos support requires compiling the driver against ``cyrus-sasl`` on UNIX-like environments. On Windows, configure the driver to build against the Windows Native SSPI. - -``GSSAPI`` (Kerberos) authentication is available in the Enterprise Edition of MongoDB. To authenticate using ``GSSAPI``, the MongoDB C driver must be installed with SASL support. - -On UNIX-like environments, run the ``kinit`` command before using the following authentication methods: - -.. code-block:: none - - $ kinit mongodbuser@EXAMPLE.COM - mongodbuser@EXAMPLE.COM's Password: - $ klistCredentials cache: FILE:/tmp/krb5cc_1000 - Principal: mongodbuser@EXAMPLE.COM - - Issued Expires Principal - Feb 9 13:48:51 2013 Feb 9 23:48:51 2013 krbtgt/EXAMPLE.COM@EXAMPLE.COM - -Now authenticate using the MongoDB URI. ``GSSAPI`` authenticates against the ``$external`` virtual database, so a database does not need to be specified in the URI. Note that the Kerberos principal *must* be URL-encoded: - -.. code-block:: none - - mongoc_client_t *client; - - client = mongoc_client_new ("mongodb://mongodbuser%40EXAMPLE.COM@mongo-server.example.com/?authMechanism=GSSAPI"); - -.. note:: - - ``GSSAPI`` authenticates against the ``$external`` database, so specifying the authSource database is not required. - -The driver supports these GSSAPI properties: - -* ``CANONICALIZE_HOST_NAME``: This might be required with Cyrus-SASL when the hosts report different hostnames than what is used in the Kerberos database. The default is "false". -* ``SERVICE_NAME``: Use a different service name than the default, "mongodb". - -Set properties in the URL: - -.. code-block:: none - - mongoc_client_t *client; - - client = mongoc_client_new ("mongodb://mongodbuser%40EXAMPLE.COM@mongo-server.example.com/?authMechanism=GSSAPI&" - "authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true"); - -If you encounter errors such as ``Invalid net address``, check if the application is behind a NAT (Network Address Translation) firewall. If so, create a ticket that uses ``forwardable`` and ``addressless`` Kerberos tickets. This can be done by passing ``-f -A`` to ``kinit``. - -.. code-block:: none - - $ kinit -f -A mongodbuser@EXAMPLE.COM - -.. _authentication_plain: - -SASL Plain Authentication -------------------------- - -.. note:: - - The MongoDB C Driver must be compiled with SASL support in order to use ``SASL PLAIN`` authentication. - -MongoDB Enterprise Edition supports the ``SASL PLAIN`` authentication mechanism, initially intended for delegating authentication to an LDAP server. Using the ``SASL PLAIN`` mechanism is very similar to the challenge response mechanism with usernames and passwords. This authentication mechanism uses the ``$external`` virtual database for ``LDAP`` support: - -.. note:: - - ``SASL PLAIN`` is a clear-text authentication mechanism. It is strongly recommended to connect to MongoDB using SSL with certificate validation when using the ``PLAIN`` mechanism. - -.. code-block:: none - - mongoc_client_t *client; - - client = mongoc_client_new ("mongodb://user:password@example.com/?authMechanism=PLAIN"); - -``PLAIN`` authenticates against the ``$external`` database, so specifying the authSource database is not required. - -.. _authentication_x509: - -X.509 Certificate Authentication --------------------------------- - -.. note:: - - The MongoDB C Driver must be compiled with SSL support for X.509 authentication support. Once this is done, start a server with the following options: - - .. code-block:: none - - $ mongod --sslMode requireSSL --sslPEMKeyFile server.pem --sslCAFile ca.pem - -The ``MONGODB-X509`` mechanism authenticates a username derived from the distinguished subject name of the X.509 certificate presented by the driver during SSL negotiation. This authentication method requires the use of SSL connections with certificate validation. - -.. code-block:: none - - mongoc_client_t *client; - mongoc_ssl_opt_t ssl_opts = { 0 }; - - ssl_opts.pem_file = "mycert.pem"; - ssl_opts.pem_pwd = "mycertpassword"; - ssl_opts.ca_file = "myca.pem"; - ssl_opts.ca_dir = "trust_dir"; - ssl_opts.weak_cert_validation = false; - - client = mongoc_client_new ("mongodb://x509_derived_username@localhost/?authMechanism=MONGODB-X509"); - mongoc_client_set_ssl_opts (client, &ssl_opts); - -``MONGODB-X509`` authenticates against the ``$external`` database, so specifying the authSource database is not required. For more information on the x509_derived_username, see the MongoDB server `x.509 tutorial <https://docs.mongodb.com/manual/tutorial/configure-x509-client-authentication/#add-x-509-certificate-subject-as-a-user>`_. - -.. note:: - - The MongoDB C Driver will attempt to determine the x509 derived username when none is provided, and as of MongoDB 3.4 providing the username is not required at all. - -.. only:: html - - .. taglist:: See Also: - :tags: authmechanism diff --git a/lib/mongoc/libmongoc/doc/basic-troubleshooting.rst b/lib/mongoc/libmongoc/doc/basic-troubleshooting.rst deleted file mode 100644 index 21e53b565c68f04a52c04415d6ad9ff1a5ab6e62..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/basic-troubleshooting.rst +++ /dev/null @@ -1,90 +0,0 @@ -:man_page: mongoc_basic_troubleshooting - -Basic Troubleshooting -===================== - -Troubleshooting Checklist -------------------------- - -The following is a short list of things to check when you have a problem. - -* Did you call ``mongoc_init()`` in ``main()``? If not, you will likely see a segfault. -* Have you leaked any clients or cursors as can be found with ``mongoc-stat <PID>``? -* Have packets been delivered to the server? See egress bytes from ``mongoc-stat <PID>``. -* Does ``valgrind`` show any leaks? Ensure you call ``mongoc_cleanup()`` at the end of your process to cleanup lingering allocations from the MongoDB C driver. -* If compiling your own copy of MongoDB C Driver, consider using the cmake option ``-DENABLE_TRACING=ON`` to enable function tracing and hex dumps of network packets to ``STDERR`` and ``STDOUT``. - -Performance Counters --------------------- - -The MongoDB C driver comes with an optional unique feature to help developers and sysadmins troubleshoot problems in production. -Performance counters are available for each process using the driver. -If available, the counters can be accessed outside of the application process via a shared memory segment. -This means that you can graph statistics about your application process easily from tools like Munin or Nagios. -Your author often uses ``watch --interval=0.5 -d mongoc-stat $PID`` to monitor an application. - -Performance counters are only available on Linux platforms supporting shared memory segments. -On supported platforms they are enabled by default. -Applications can be built without the counters by specifying the cmake option ``-DENABLE_SHM_COUNTERS=OFF``. Additionally, if -performance counters are already compiled, they can be disabled at runtime by specifying the environment variable ``MONGOC_DISABLE_SHM``. - -Performance counters keep track of the following: - -* Active and Disposed Cursors -* Active and Disposed Clients, Client Pools, and Socket Streams. -* Number of operations sent and received, by type. -* Bytes transferred and received. -* Authentication successes and failures. -* Number of wire protocol errors. - -To access counters for a given process, simply provide the process id to the ``mongoc-stat`` program installed with the MongoDB C Driver. - -.. code-block:: none - - $ mongoc-stat 22203 - Operations : Egress Total : The number of sent operations. : 13247 - Operations : Ingress Total : The number of received operations. : 13246 - Operations : Egress Queries : The number of sent Query operations. : 13247 - Operations : Ingress Queries : The number of received Query operations. : 0 - Operations : Egress GetMore : The number of sent GetMore operations. : 0 - Operations : Ingress GetMore : The number of received GetMore operations. : 0 - Operations : Egress Insert : The number of sent Insert operations. : 0 - Operations : Ingress Insert : The number of received Insert operations. : 0 - Operations : Egress Delete : The number of sent Delete operations. : 0 - Operations : Ingress Delete : The number of received Delete operations. : 0 - Operations : Egress Update : The number of sent Update operations. : 0 - Operations : Ingress Update : The number of received Update operations. : 0 - Operations : Egress KillCursors : The number of sent KillCursors operations. : 0 - Operations : Ingress KillCursors : The number of received KillCursors operations. : 0 - Operations : Egress Msg : The number of sent Msg operations. : 0 - Operations : Ingress Msg : The number of received Msg operations. : 0 - Operations : Egress Reply : The number of sent Reply operations. : 0 - Operations : Ingress Reply : The number of received Reply operations. : 13246 - Cursors : Active : The number of active cursors. : 1 - Cursors : Disposed : The number of disposed cursors. : 13246 - Clients : Active : The number of active clients. : 1 - Clients : Disposed : The number of disposed clients. : 0 - Streams : Active : The number of active streams. : 1 - Streams : Disposed : The number of disposed streams. : 0 - Streams : Egress Bytes : The number of bytes sent. : 794931 - Streams : Ingress Bytes : The number of bytes received. : 589694 - Streams : N Socket Timeouts : The number of socket timeouts. : 0 - Client Pools : Active : The number of active client pools. : 1 - Client Pools : Disposed : The number of disposed client pools. : 0 - Protocol : Ingress Errors : The number of protocol errors on ingress. : 0 - Auth : Failures : The number of failed authentication requests. : 0 - Auth : Success : The number of successful authentication requests. : 0 - -.. _basic-troubleshooting_file_bug: - -Submitting a Bug Report ------------------------ - -Think you've found a bug? Want to see a new feature in the MongoDB C driver? Please open a case in our issue management tool, JIRA: - -* `Create an account and login <https://jira.mongodb.org>`_. -* Navigate to `the CDRIVER project <https://jira.mongodb.org/browse/CDRIVER>`_. -* Click *Create Issue* - Please provide as much information as possible about the issue type and how to reproduce it. - -Bug reports in JIRA for all driver projects (i.e. CDRIVER, CSHARP, JAVA) and the Core Server (i.e. SERVER) project are *public*. - diff --git a/lib/mongoc/libmongoc/doc/bulk.rst b/lib/mongoc/libmongoc/doc/bulk.rst deleted file mode 100644 index 428d2110b3f146ceed470f592618541ca83e5fd3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/bulk.rst +++ /dev/null @@ -1,210 +0,0 @@ -:man_page: mongoc_bulk - -Bulk Write Operations -===================== - -This tutorial explains how to take advantage of MongoDB C driver bulk write operation features. Executing write operations in batches reduces the number of network round trips, increasing write throughput. - -Bulk Insert ------------ - -First we need to fetch a bulk operation handle from the :symbol:`mongoc_collection_t`. - -.. code-block:: c - - mongoc_bulk_operation_t *bulk = - mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - -We can now start inserting documents to the bulk operation. These will be buffered until we execute the operation. - -The bulk operation will coalesce insertions as a single batch for each consecutive call to :symbol:`mongoc_bulk_operation_insert()`. This creates a pipelined effect when possible. - -To execute the bulk operation and receive the result we call :symbol:`mongoc_bulk_operation_execute()`. - -.. literalinclude:: ../examples/bulk/bulk1.c - :language: c - :caption: bulk1.c - -Example ``reply`` document: - -.. code-block:: none - - {"nInserted" : 10000, - "nMatched" : 0, - "nModified" : 0, - "nRemoved" : 0, - "nUpserted" : 0, - "writeErrors" : [] - "writeConcernErrors" : [] } - -Mixed Bulk Write Operations ---------------------------- - -MongoDB C driver also supports executing mixed bulk write operations. A batch of insert, update, and remove operations can be executed together using the bulk write operations API. - -Ordered Bulk Write Operations ------------------------------ - -Ordered bulk write operations are batched and sent to the server in the order provided for serial execution. The ``reply`` document describes the type and count of operations performed. - -.. literalinclude:: ../examples/bulk/bulk2.c - :language: c - :caption: bulk2.c - -Example ``reply`` document: - -.. code-block:: none - - { "nInserted" : 3, - "nMatched" : 2, - "nModified" : 2, - "nRemoved" : 10000, - "nUpserted" : 1, - "upserted" : [{"index" : 5, "_id" : 4}], - "writeErrors" : [] - "writeConcernErrors" : [] } - -The ``index`` field in the ``upserted`` array is the 0-based index of the upsert operation; in this example, the sixth operation of the overall bulk operation was an upsert, so its index is 5. - -Unordered Bulk Write Operations -------------------------------- - -Unordered bulk write operations are batched and sent to the server in *arbitrary order* where they may be executed in parallel. Any errors that occur are reported after all operations are attempted. - -In the next example the first and third operations fail due to the unique constraint on ``_id``. Since we are doing unordered execution the second and fourth operations succeed. - -.. literalinclude:: ../examples/bulk/bulk3.c - :language: c - :caption: bulk3.c - -Example ``reply`` document: - -.. code-block:: none - - { "nInserted" : 0, - "nMatched" : 1, - "nModified" : 1, - "nRemoved" : 1, - "nUpserted" : 0, - "writeErrors" : [ - { "index" : 0, - "code" : 11000, - "errmsg" : "E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 }" }, - { "index" : 2, - "code" : 11000, - "errmsg" : "E11000 duplicate key error index: test.test.$_id_ dup key: { : 3 }" } ], - "writeConcernErrors" : [] } - - Error: E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 } - -The :symbol:`bson_error_t <errors>` domain is ``MONGOC_ERROR_COMMAND`` and its code is 11000. - -.. _bulk_operation_bypassing_document_validation: - -Bulk Operation Bypassing Document Validation --------------------------------------------- - -This feature is only available when using MongoDB 3.2 and later. - -By default bulk operations are validated against the schema, if any is defined. In certain cases however it may be necessary to bypass the document validation. - -.. literalinclude:: ../examples/bulk/bulk5.c - :language: c - :caption: bulk5.c - -Running the above example will result in: - -.. code-block:: none - - { "nInserted" : 0, - "nMatched" : 0, - "nModified" : 0, - "nRemoved" : 0, - "nUpserted" : 0, - "writeErrors" : [ - { "index" : 0, - "code" : 121, - "errmsg" : "Document failed validation" } ] } - - Error: Document failed validation - - { "nInserted" : 2, - "nMatched" : 0, - "nModified" : 0, - "nRemoved" : 0, - "nUpserted" : 0, - "writeErrors" : [] } - -The :symbol:`bson_error_t <errors>` domain is ``MONGOC_ERROR_COMMAND``. - -Bulk Operation Write Concerns ------------------------------ - -By default bulk operations are executed with the :symbol:`write_concern <mongoc_write_concern_t>` of the collection they are executed against. A custom write concern can be passed to the :symbol:`mongoc_collection_create_bulk_operation_with_opts()` method. Write concern errors (e.g. wtimeout) will be reported after all operations are attempted, regardless of execution order. - -.. literalinclude:: ../examples/bulk/bulk4.c - :language: c - :caption: bulk4.c - -Example ``reply`` document and error message: - -.. code-block:: none - - { "nInserted" : 2, - "nMatched" : 0, - "nModified" : 0, - "nRemoved" : 0, - "nUpserted" : 0, - "writeErrors" : [], - "writeConcernErrors" : [ - { "code" : 64, - "errmsg" : "waiting for replication timed out" } - ] } - - Error: waiting for replication timed out - -The :symbol:`bson_error_t <errors>` domain is ``MONGOC_ERROR_WRITE_CONCERN`` if there are write concern errors and no write errors. Write errors indicate failed operations, so they take precedence over write concern errors, which mean merely that the write concern is not satisfied *yet*. - -.. _setting_collation_order: - -Setting Collation Order ------------------------ - -This feature is only available when using MongoDB 3.4 and later. - -.. literalinclude:: ../examples/bulk/bulk-collation.c - :language: c - :caption: bulk-collation.c - -Running the above example will result in: - -.. code-block:: none - - { "nInserted" : 2, - "nMatched" : 1, - "nModified" : 1, - "nRemoved" : 0, - "nUpserted" : 0, - "writeErrors" : [ ] - } - -Unacknowledged Bulk Writes --------------------------- - -Set "w" to zero for an unacknowledged write. The driver sends unacknowledged writes using the legacy opcodes ``OP_INSERT``, ``OP_UPDATE``, and ``OP_DELETE``. - -.. literalinclude:: ../examples/bulk/bulk6.c - :language: c - :caption: bulk6.c - -The ``reply`` document is empty: - -.. code-block:: none - - { } - -Further Reading ---------------- - -See the `Driver Bulk API Spec <https://github.com/mongodb/specifications/blob/master/source/driver-bulk-update.rst>`_, which describes bulk write operations for all MongoDB drivers. - diff --git a/lib/mongoc/libmongoc/doc/conf.py b/lib/mongoc/libmongoc/doc/conf.py deleted file mode 100644 index 7000088d137caf85f2fa9ac21b28b2087f175c47..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/conf.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- -import os.path -import sys - -# Ensure we can import "mongoc" and "taglist" extension modules. -this_path = os.path.dirname(__file__) -sys.path.append(this_path) -sys.path.append(os.path.normpath(os.path.join(this_path, '../../../build/sphinx'))) - -from mongoc_common import * - -extensions = [ - 'mongoc', - 'taglist', - 'sphinx.ext.intersphinx', -] - -# General information about the project. -project = 'MongoDB C Driver' -copyright = '2017-present, MongoDB, Inc' -author = 'MongoDB, Inc' - -version_path = os.path.join( - os.path.dirname(__file__), '../../..', 'VERSION_CURRENT') -version = open(version_path).read().strip() - -# The extension requires the "base" to contain '%s' exactly once, but we never intend to use it though - -language = 'en' -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] -master_doc = 'index' - -# don't fetch libbson's inventory from mongoc.org during build - Debian and -# Fedora package builds must work offline - maintain a recent copy here -intersphinx_mapping = { - 'bson': ('http://mongoc.org/libbson/current', 'libbson-objects.inv'), -} - -# -- Options for HTML output ---------------------------------------------- - -html_theme_path = ['../../../build/sphinx'] -html_theme = 'mongoc-theme' -html_title = html_shorttitle = 'MongoDB C Driver %s' % version -# html_favicon = None - -html_sidebars = { - '**': ['globaltoc.html'], - 'errors': [], # Make more room for the big table. - 'mongoc_uri_t': [], # Make more room for the big table. -} - - -def add_canonical_link(app, pagename, templatename, context, doctree): - link = ('<link rel="canonical"' - ' href="http://mongoc.org/libbson/current/%s.html"/>' % pagename) - - context['metatags'] = context.get('metatags', '') + link - - -def setup(app): - mongoc_common_setup(app) - app.connect('html-page-context', add_canonical_link) diff --git a/lib/mongoc/libmongoc/doc/connection-pooling.rst b/lib/mongoc/libmongoc/doc/connection-pooling.rst deleted file mode 100644 index 5b3b50cce1b359c74a711fb8bad4276bc6d3fc94..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/connection-pooling.rst +++ /dev/null @@ -1,54 +0,0 @@ -:man_page: mongoc_connection_pooling - -Connection Pooling -================== - -The MongoDB C driver has two connection modes: single-threaded and pooled. Single-threaded mode is optimized for embedding the driver within languages like PHP. Multi-threaded programs should use pooled mode: this mode minimizes the total connection count, and in pooled mode a background thread monitors the MongoDB server topology, so the program need not block to scan it. - -Single Mode ------------ - -In single mode, your program creates a :symbol:`mongoc_client_t` directly: - -.. code-block:: c - - mongoc_client_t *client = mongoc_client_new ( - "mongodb://hostA,hostB/?replicaSet=my_rs"); - -The client connects on demand when your program first uses it for a MongoDB operation. Using a non-blocking socket per server, it begins a check on each server concurrently, and uses the asynchronous ``poll`` or ``select`` function to receive events from the sockets, until all have responded or timed out. Put another way, in single-threaded mode the C Driver fans out to begin all checks concurrently, then fans in once all checks have completed or timed out. Once the scan completes, the client executes your program's operation and returns. - -In single mode, the client re-scans the server topology roughly once per minute. If more than a minute has elapsed since the previous scan, the next operation on the client will block while the client completes its scan. This interval is configurable with ``heartbeatFrequencyMS`` in the connection string. (See :symbol:`mongoc_uri_t`.) - -A single client opens one connection per server in your topology: these connections are used both for scanning the topology and performing normal operations. - -Pooled Mode ------------ - -To activate pooled mode, create a :symbol:`mongoc_client_pool_t`: - -.. code-block:: c - - mongoc_uri_t *uri = mongoc_uri_new ( - "mongodb://hostA,hostB/?replicaSet=my_rs"); - - mongoc_client_pool_t *pool = mongoc_client_pool_new (uri); - -When your program first calls :symbol:`mongoc_client_pool_pop`, the pool launches a background thread for monitoring. The thread fans out and connects to all servers in the connection string, using non-blocking sockets and a simple event loop. As it receives ismaster responses from the servers, it updates its view of the server topology. Each time the thread discovers a new server it begins connecting to it, and adds the new socket to the list of non-blocking sockets in the event loop. - -Each thread that executes MongoDB operations must check out a client from the pool: - -.. code-block:: c - - mongoc_client_t *client = mongoc_client_pool_pop (pool); - - /* use the client for operations ... */ - - mongoc_client_pool_push (pool, client); - -The :symbol:`mongoc_client_t` object is not thread-safe, only the :symbol:`mongoc_client_pool_t` is. - -When the driver is in pooled mode, your program's operations are unblocked as soon as monitoring discovers a usable server. For example, if a thread in your program is waiting to execute an "insert" on the primary, it is unblocked as soon as the primary is discovered, rather than waiting for all secondaries to be checked as well. - -The pool opens one connection per server for monitoring, and each client opens its own connection to each server it uses for application operations. The background thread re-scans the server topology roughly every 10 seconds. This interval is configurable with ``heartbeatFrequencyMS`` in the connection string. (See :symbol:`mongoc_uri_t`.) - -See :ref:`connection_pool_options` to configure pool size and behavior, and see :symbol:`mongoc_client_pool_t` for an extended example of a multi-threaded program that uses the driver in pooled mode. diff --git a/lib/mongoc/libmongoc/doc/create-indexes.rst b/lib/mongoc/libmongoc/doc/create-indexes.rst deleted file mode 100644 index 4bf9f4d3807987adf95934f489776e82998e3fff..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/create-indexes.rst +++ /dev/null @@ -1,17 +0,0 @@ -:man_page: mongoc_create_indexes - -Creating Indexes -================ - -To create indexes on a MongoDB collection, execute the ``createIndexes`` command -with a command function like :symbol:`mongoc_database_write_command_with_opts` or -:symbol:`mongoc_collection_write_command_with_opts`. See `the MongoDB -Manual entry for the createIndexes command -<https://docs.mongodb.com/manual/reference/command/createIndexes/>`_ for details. - -Example -------- - -.. literalinclude:: ../examples/example-create-indexes.c - :language: c - :caption: example-create-indexes.c diff --git a/lib/mongoc/libmongoc/doc/cursors.rst b/lib/mongoc/libmongoc/doc/cursors.rst deleted file mode 100644 index 0c9a82eddc913ab22562003408f19687941271e5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/cursors.rst +++ /dev/null @@ -1,90 +0,0 @@ -:man_page: mongoc_cursors - -Cursors -======= - -Handling Cursor Failures ------------------------- - -Cursors exist on a MongoDB server. However, the ``mongoc_cursor_t`` structure gives the local process a handle to the cursor. It is possible for errors to occur on the server while iterating a cursor on the client. Even a network partition may occur. This means that applications should be robust in handling cursor failures. - -While iterating cursors, you should check to see if an error has occurred. See the following example for how to robustly check for errors. - -.. code-block:: c - - static void - print_all_documents (mongoc_collection_t *collection) - { - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - bson_t query = BSON_INITIALIZER; - char *str; - - cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - printf ("%s\n", str); - bson_free (str); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "Failed to iterate all documents: %s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - } - -Destroying Server-Side Cursors ------------------------------- - -The MongoDB C driver will automatically destroy a server-side cursor when :symbol:`mongoc_cursor_destroy()` is called. Failure to call this function when done with a cursor will leak memory client side as well as consume extra memory server side. If the cursor was configured to never timeout, it will become a memory leak on the server. - -.. _cursors_tailable: - -Tailable Cursors ----------------- - -Tailable cursors are cursors that remain open even after they've returned a final result. This way, if more documents are added to a collection (i.e., to the cursor's result set), then you can continue to call :symbol:`mongoc_cursor_next()` to retrieve those additional results. - -Here's a complete test case that demonstrates the use of tailable cursors. - -.. note:: - - Tailable cursors are for capped collections only. - -An example to tail the oplog from a replica set. - -.. literalinclude:: ../examples/mongoc-tail.c - :language: c - :caption: mongoc-tail.c - -Let's compile and run this example against a replica set to see updates as they are made. - -.. code-block:: none - - $ gcc -Wall -o mongoc-tail mongoc-tail.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./mongoc-tail mongodb://example.com/?replicaSet=myReplSet - { - "h" : -8458503739429355503, - "ns" : "test.test", - "o" : { - "_id" : { - "$oid" : "5372ab0a25164be923d10d50" - } - }, - "op" : "i", - "ts" : { - "$timestamp" : { - "i" : 1, - "t" : 1400023818 - } - }, - "v" : 2 - } - -The line of output is a sample from performing ``db.test.insert({})`` from the mongo shell on the replica set. - -See also :symbol:`mongoc_cursor_set_max_await_time_ms`. - diff --git a/lib/mongoc/libmongoc/doc/debugging.rst b/lib/mongoc/libmongoc/doc/debugging.rst deleted file mode 100644 index 8b4e38efa79fa4c711ed66dc82561b8c9bc01402..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/debugging.rst +++ /dev/null @@ -1,106 +0,0 @@ -:man_page: mongoc_debugging - -Aids for Debugging -================== - -GDB ---- - -This repository contains a ``.gdbinit`` file that contains helper functions to -aid debugging of data structures. GDB will load this file -`automatically`_ if you have added the directory which contains the `.gdbinit` file to GDB's -`auto-load safe-path`_, *and* you start GDB from the directory which holds the `.gdbinit` file. - -You can see the safe-path with ``show auto-load safe-path`` on a GDB prompt. You -can configure it by setting it in ``~/.gdbinit`` with:: - - add-auto-load-safe-path /path/to/mongo-c-driver - -If you haven't added the path to your auto-load safe-path, or start GDB in -another directory, load the file with:: - - source path/to/mongo-c-driver/.gdbinit - -The ``.gdbinit`` file defines the ``printbson`` function, which shows the contents of a ``bson_t *`` variable. -If you have a local ``bson_t``, then you must prefix the variable with a `&`. - -An example GDB session looks like:: - - (gdb) printbson bson - ALLOC [0x555556cd7310 + 0] (len=475) - { - 'bool' : true, - 'int32' : NumberInt("42"), - 'int64' : NumberLong("3000000042"), - 'string' : "Stŕìñg", - 'objectId' : ObjectID("5A1442F3122D331C3C6757E1"), - 'utcDateTime' : UTCDateTime(1511277299031), - 'arrayOfInts' : [ - '0' : NumberInt("1"), - '1' : NumberInt("2") - ], - 'embeddedDocument' : { - 'arrayOfStrings' : [ - '0' : "one", - '1' : "two" - ], - 'double' : 2.718280, - 'notherDoc' : { - 'true' : NumberInt("1"), - 'false' : false - } - }, - 'binary' : Binary("02", "3031343532333637"), - 'regex' : Regex("@[a-z]+@", "im"), - 'null' : null, - 'js' : JavaScript("print foo"), - 'jsws' : JavaScript("print foo") with scope: { - 'f' : NumberInt("42"), - 'a' : [ - '0' : 3.141593, - '1' : 2.718282 - ] - }, - 'timestamp' : Timestamp(4294967295, 4294967295), - 'double' : 3.141593 - } - -.. _automatically: https://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading.html -.. _auto-load safe-path: https://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading-safe-path.html - -LLDB ----- - -This repository also includes a script that customizes LLDB's standard ``print`` command to print a ``bson_t`` or ``bson_t *`` as JSON:: - - (lldb) print b - (bson_t) $0 = {"x": 1, "y": 2} - -The custom ``bson`` command provides more options:: - - (lldb) bson --verbose b - len=19 - flags=INLINE|STATIC - { - "x": 1, - "y": 2 - } - (lldb) bson --raw b - '\x13\x00\x00\x00\x10x\x00\x01\x00\x00\x00\x10y\x00\x02\x00\x00\x00\x00' - -Type ``help bson`` for a list of options. - -The script requires a build of libbson with debug symbols, and an installation of `PyMongo`_. Install PyMongo with:: - - python -m pip install pymongo - -If you see "No module named pip" then you must `install pip`_, then run the previous command again. - -Create a file ``~/.lldbinit`` containing:: - - command script import /path/to/mongo-c-driver/lldb_bson.py - -If you see "bson command installed by lldb_bson" at the beginning of your LLDB session, you've installed the script correctly. - -.. _PyMongo: https://pypi.python.org/pypi/pymongo -.. _install pip: https://pip.pypa.io/en/stable/installing/#installing-with-get-pip-py) diff --git a/lib/mongoc/libmongoc/doc/distinct-mapreduce.rst b/lib/mongoc/libmongoc/doc/distinct-mapreduce.rst deleted file mode 100644 index d7516d1938f070b2098b49eb93a3ad0ed43834bb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/distinct-mapreduce.rst +++ /dev/null @@ -1,93 +0,0 @@ -:man_page: mongoc_distinct_mapreduce - -"distinct" and "mapReduce" -========================== - -This document provides some practical, simple, examples to demonstrate the ``distinct`` and ``mapReduce`` commands. - -Setup ------ - -First we'll write some code to insert sample data: - -.. literalinclude:: ../examples/doc-common-insert.c - :language: c - :caption: doc-common-insert.c - -"distinct" command ------------------- - -This is how to use the ``distinct`` command to get the distinct values of ``x`` which are greater than ``1``: - -.. literalinclude:: ../examples/basic_aggregation/distinct.c - :language: c - :caption: distinct.c - -"mapReduce" - basic example ---------------------------- - -A simple example using the map reduce framework. It simply adds up the number of occurrences of each "tag". - -First define the ``map`` and ``reduce`` functions: - -.. literalinclude:: ../examples/basic_aggregation/constants.c - :language: c - :caption: constants.c - -Run the ``mapReduce`` command. Use the generic command helpers (e.g. :symbol:`mongoc_database_command_simple()`). -Do not the read command helpers (e.g. :symbol:`mongoc_database_read_command_with_opts()`) because they are considered -retryable read operations. If retryable reads are enabled, those operations will retry once on a retryable error, -giving undesirable behavior for ``mapReduce``. - -.. literalinclude:: ../examples/basic_aggregation/map-reduce-basic.c - :language: c - :caption: map-reduce-basic.c - -"mapReduce" - more complicated example --------------------------------------- - -You must have replica set running for this. - -In this example we contact a secondary in the replica set and do an "inline" map reduce, so the results are returned immediately: - -.. literalinclude:: ../examples/basic_aggregation/map-reduce-advanced.c - :language: c - :caption: map-reduce-advanced.c - -Running the Examples --------------------- - -Here's how to run the example code - -.. literalinclude:: ../examples/basic_aggregation/basic-aggregation.c - :language: c - :caption: basic-aggregation.c - -If you want to try the advanced map reduce example with a secondary, start a replica set (instructions for how to do this can be found `here <https://docs.mongodb.com/manual/tutorial/deploy-replica-set-for-testing/>`_). - -Otherwise, just start an instance of MongoDB: - -.. code-block:: none - - $ mongod - -Now compile and run the example program: - -.. code-block:: none - - $ cd examples/basic_aggregation/ - $ gcc -Wall -o agg-example basic-aggregation.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./agg-example localhost - - Inserting data - distinct - Next double: 2.000000 - Next double: 3.000000 - map reduce - { "result" : "outCollection", "timeMillis" : 155, "counts" : { "input" : 84, "emit" : 126, "reduce" : 3, "output" : 3 }, "ok" : 1 } - { "_id" : "cat", "value" : 63 } - { "_id" : "dog", "value" : 42 } - { "_id" : "mouse", "value" : 21 } - more complicated map reduce - { "results" : [ { "_id" : "cat", "value" : 63 }, { "_id" : "dog", "value" : 42 }, { "_id" : "mouse", "value" : 21 } ], "timeMillis" : 14, "counts" : { "input" : 84, "emit" : 126, "reduce" : 3, "output" : 3 }, "ok" : 1 } - diff --git a/lib/mongoc/libmongoc/doc/errors.rst b/lib/mongoc/libmongoc/doc/errors.rst deleted file mode 100644 index be37a22eb8e128760ac22e8e5c1236df70c12443..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/errors.rst +++ /dev/null @@ -1,180 +0,0 @@ -:man_page: mongoc_errors - -« :doc:`index` - -Error Reporting -=============== - -Description ------------ - -Many C Driver functions report errors by returning ``false`` or -1 and filling out a :symbol:`bson:bson_error_t` structure with an error domain, error code, and message. Use ``domain`` to determine which subsystem generated the error, and ``code`` for the specific error. ``message`` is a human-readable error description. - -See also: :doc:`Handling Errors in libbson <bson:errors>`. - -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|Domain | Code | Description | -+=========================================+=================================================================================================================================+============================================================================================================================================================================================================================================================================================================================================+ -| ``MONGOC_ERROR_CLIENT`` | ``MONGOC_ERROR_CLIENT_TOO_BIG`` | You tried to send a message larger than the server's max message size. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_CLIENT_AUTHENTICATE`` | Wrong credentials, or failure sending or receiving authentication messages. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER`` | You tried an SSL connection but the driver was not built with SSL. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_CLIENT_IN_EXHAUST`` | You began iterating an exhaust cursor, then tried to begin another operation with the same :symbol:`mongoc_client_t`. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_CLIENT_SESSION_FAILURE`` | Failure related to creating or using a logical session. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG`` | Failure related to arguments passed when initializing Client-Side Field Level Encryption. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE`` | Failure related to Client-Side Field Level Encryption. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_STREAM`` | ``MONGOC_ERROR_STREAM_NAME_RESOLUTION`` | DNS failure. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_STREAM_SOCKET`` | Timeout communicating with server, or connection closed. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_STREAM_CONNECT`` | Failed to connect to server. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_PROTOCOL`` | ``MONGOC_ERROR_PROTOCOL_INVALID_REPLY`` | Corrupt response from server. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION`` | The server version is too old or too new to communicate with the driver. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_CURSOR`` | ``MONGOC_ERROR_CURSOR_INVALID_CURSOR`` | You passed bad arguments to :symbol:`mongoc_collection_find_with_opts`, or you called :symbol:`mongoc_cursor_next` on a completed or failed cursor, or the cursor timed out on the server. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_CHANGE_STREAM_NO_RESUME_TOKEN`` | A resume token was not returned in a document found with :symbol:`mongoc_change_stream_next` | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_QUERY`` | ``MONGOC_ERROR_QUERY_FAILURE`` | :ref:`Error API Version 1 <error_api_version>`: Server error from command or query. The server error message is in ``message``. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_SERVER`` | ``MONGOC_ERROR_QUERY_FAILURE`` | :ref:`Error API Version 2 <error_api_version>`: Server error from command or query. The server error message is in ``message``. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_SASL`` | A SASL error code. | ``man sasl_errors`` for a list of codes. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_BSON`` | ``MONGOC_ERROR_BSON_INVALID`` | You passed an invalid or oversized BSON document as a parameter, or called :symbol:`mongoc_collection_create_index` with invalid keys, or the server reply was corrupt. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_NAMESPACE`` | ``MONGOC_ERROR_NAMESPACE_INVALID`` | You tried to create a collection with an invalid name. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_COMMAND`` | ``MONGOC_ERROR_COMMAND_INVALID_ARG`` | Many functions set this error code when passed bad parameters. Print the error message for details. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION`` | You tried to use a command option the server does not support. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_DUPLICATE_KEY`` | An insert or update failed because because of a duplicate ``_id`` or other unique-index violation. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_MAX_TIME_MS_EXPIRED`` | The operation failed because maxTimeMS expired. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_SERVER_SELECTION_INVALID_ID`` | The ``serverId`` option for an operation conflicts with the pinned server for that operation's client session (denoted by the ``sessionId`` option). | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_COMMAND`` | `Error code from server <https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err>`_. | :ref:`Error API Version 1 <error_api_version>`: Server error from a command. The server error message is in ``message``. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_SERVER`` | `Error code from server <https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err>`_. | :ref:`Error API Version 2 <error_api_version>`: Server error from a command. The server error message is in ``message``. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_COLLECTION`` | ``MONGOC_ERROR_COLLECTION_INSERT_FAILED``, ``MONGOC_ERROR_COLLECTION_UPDATE_FAILED``, ``MONGOC_ERROR_COLLECTION_DELETE_FAILED``.| Invalid or empty input to :symbol:`mongoc_collection_insert_one`, :symbol:`mongoc_collection_insert_bulk`, :symbol:`mongoc_collection_update_one`, :symbol:`mongoc_collection_update_many`, :symbol:`mongoc_collection_replace_one`, :symbol:`mongoc_collection_delete_one`, or :symbol:`mongoc_collection_delete_many`. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_COLLECTION`` | `Error code from server <https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err>`_. | :ref:`Error API Version 1 <error_api_version>`: Server error from :symbol:`mongoc_collection_insert_one`, :symbol:`mongoc_collection_insert_bulk`, :symbol:`mongoc_collection_update_one`, :symbol:`mongoc_collection_update_many`, :symbol:`mongoc_collection_replace_one`, | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_SERVER`` | `Error code from server <https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err>`_. | :ref:`Error API Version 2 <error_api_version>`: Server error from :symbol:`mongoc_collection_insert_one`, :symbol:`mongoc_collection_insert_bulk`, :symbol:`mongoc_collection_update_one`, :symbol:`mongoc_collection_update_many`, :symbol:`mongoc_collection_replace_one`, | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_GRIDFS`` | ``MONGOC_ERROR_GRIDFS_CHUNK_MISSING`` | The GridFS file is missing a document in its ``chunks`` collection. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_GRIDFS_CORRUPT`` | A data inconsistency was detected in GridFS. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_GRIDFS_INVALID_FILENAME`` | You passed a NULL filename to :symbol:`mongoc_gridfs_remove_by_filename`. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_GRIDFS_PROTOCOL_ERROR`` | You called :symbol:`mongoc_gridfs_file_set_id` after :symbol:`mongoc_gridfs_file_save`, or tried to write on a closed GridFS stream. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_GRIDFS_BUCKET_FILE_NOT_FOUND`` | A GridFS file is missing from ``files`` collection. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``MONGOC_ERROR_GRIDFS_BUCKET_STREAM`` | An error occurred on a stream created from a GridFS operation like :symbol:`mongoc_gridfs_bucket_upload_from_stream`. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_SCRAM`` | ``MONGOC_ERROR_SCRAM_PROTOCOL_ERROR`` | Failure in SCRAM-SHA-1 authentication. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_SERVER_SELECTION`` | ``MONGOC_ERROR_SERVER_SELECTION_FAILURE`` | No replica set member or mongos is available, or none matches your :doc:`read preference <mongoc_read_prefs_t>`, or you supplied an invalid :symbol:`mongoc_read_prefs_t`. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_WRITE_CONCERN`` | `Error code from server <https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err>`_. | There was a :doc:`write concern <mongoc_write_concern_t>` error or :doc:`timeout <mongoc_write_concern_set_wtimeout>` from the server. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_TRANSACTION`` | ``MONGOC_ERROR_TRANSACTION_INVALID`` | You attempted to start a transaction when one is already in progress, or commit or abort when there is no transaction. | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION`` | Error code produced by libmongocrypt. | An error occurred in the library responsible for Client Side Encryption | -+-----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -.. _error_labels: - -Error Labels ------------- - -In some cases your application must make decisions based on what category of error the driver has returned, but these categories do not correspond perfectly to an error domain or code. In such cases, error *labels* provide a reliable way to determine how your application should respond to an error. - -Any C Driver function that has a :symbol:`bson:bson_t` out-parameter named ``reply`` may include error labels to the reply, in the form of a BSON field named "errorLabels" containing an array of strings: - -.. code-block:: none - - { "errorLabels": [ "TransientTransactionError" ] } - -Use :symbol:`mongoc_error_has_label` to test if a reply contains a specific label. See :symbol:`mongoc_client_session_start_transaction` for example code that demonstrates the use of error labels in application logic. - -The following error labels are currently defined. Future versions of MongoDB may introduce new labels. - -TransientTransactionError -^^^^^^^^^^^^^^^^^^^^^^^^^ - -Within a multi-document transaction, certain errors can leave the transaction in an unknown or aborted state. These include write conflicts, primary stepdowns, and network errors. In response, the application should abort the transaction and try the same sequence of operations again in a new transaction. - -UnknownTransactionCommitResult -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When :symbol:`mongoc_client_session_commit_transaction` encounters a network error or certain server errors, it is not known whether the transaction was committed. Applications should attempt to commit the transaction again until: the commit succeeds, the commit fails with an error *not* labeled "UnknownTransactionCommitResult", or the application chooses to give up. - -.. _errors_error_api_version: -.. _error_api_version: - -Setting the Error API Version ------------------------------ - -The driver's error reporting began with a design flaw: when the error *domain* is ``MONGOC_ERROR_COLLECTION``, ``MONGOC_ERROR_QUERY``, or ``MONGOC_ERROR_COMMAND``, the error *code* might originate from the server or the driver. An application cannot always know where an error originated, and therefore cannot tell what the code means. - -For example, if :symbol:`mongoc_collection_update_one` sets the error's domain to ``MONGOC_ERROR_COLLECTION`` and its code to 24, the application cannot know whether 24 is the generic driver error code ``MONGOC_ERROR_COLLECTION_UPDATE_FAILED`` or the specific server error code "LockTimeout". - -To fix this flaw while preserving backward compatibility, the C Driver 1.4 introduces "Error API Versions". Version 1, the default Error API Version, maintains the flawed behavior. Version 2 adds a new error domain, ``MONGOC_ERROR_SERVER``. In Version 2, error codes originating on the server always have error domain ``MONGOC_ERROR_SERVER`` or ``MONGOC_ERROR_WRITE_CONCERN``. When the driver uses Version 2 the application can always determine the origin and meaning of error codes. New applications should use Version 2, and existing applications should be updated to use Version 2 as well. - -+------------------------------------------------------+----------------------------------------+----------------------------------------+ -| Error Source | API Version 1 | API Version 2 | -+------------------------------------------------------+----------------------------------------+----------------------------------------+ -| :symbol:`mongoc_cursor_error` | ``MONGOC_ERROR_QUERY`` | ``MONGOC_ERROR_SERVER`` | -+------------------------------------------------------+----------------------------------------+----------------------------------------+ -| :symbol:`mongoc_client_command_with_opts`, | ``MONGOC_ERROR_QUERY`` | ``MONGOC_ERROR_SERVER`` | -| :symbol:`mongoc_database_command_with_opts`, and | | | -| other command functions | | | -+------------------------------------------------------+----------------------------------------+----------------------------------------+ -| :symbol:`mongoc_collection_count_with_opts` | ``MONGOC_ERROR_QUERY`` | ``MONGOC_ERROR_SERVER`` | -| :symbol:`mongoc_client_get_database_names_with_opts`,| | | -| and other command helper functions | | | -+------------------------------------------------------+----------------------------------------+----------------------------------------+ -| :symbol:`mongoc_collection_insert_one` | ``MONGOC_ERROR_COMMAND`` | ``MONGOC_ERROR_SERVER`` | -| :symbol:`mongoc_collection_insert_bulk` | | | -| :symbol:`mongoc_collection_update_one` | | | -| :symbol:`mongoc_collection_update_many` | | | -| :symbol:`mongoc_collection_replace_one` | | | -| :symbol:`mongoc_collection_delete_one` | | | -| :symbol:`mongoc_collection_delete_many` | | | -+------------------------------------------------------+----------------------------------------+----------------------------------------+ -| :symbol:`mongoc_bulk_operation_execute` | ``MONGOC_ERROR_COMMAND`` | ``MONGOC_ERROR_SERVER`` | -+------------------------------------------------------+----------------------------------------+----------------------------------------+ -| Write-concern timeout | ``MONGOC_ERROR_WRITE_CONCERN`` | ``MONGOC_ERROR_WRITE_CONCERN`` | -+------------------------------------------------------+----------------------------------------+----------------------------------------+ - -The Error API Versions are defined with ``MONGOC_ERROR_API_VERSION_LEGACY`` and ``MONGOC_ERROR_API_VERSION_2``. Set the version with :symbol:`mongoc_client_set_error_api` or :symbol:`mongoc_client_pool_set_error_api`. - -See Also --------- - -`MongoDB Server Error Codes <https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err>`_ - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_error_has_label diff --git a/lib/mongoc/libmongoc/doc/full_index.rst b/lib/mongoc/libmongoc/doc/full_index.rst deleted file mode 100644 index 72f84479386639d6ff8985534c77fbfb7e01a8fa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/full_index.rst +++ /dev/null @@ -1,15 +0,0 @@ -:man_page: mongoc_reference -:orphan: - -.. Yes it's confusing: the home page is called "index" so this is "full_index", - and it works by including the complete Table of Contents from the homepage, - i.e., "index". - -Index -===== - -.. toctree:: - :maxdepth: 6 - :titlesonly: - - index diff --git a/lib/mongoc/libmongoc/doc/gridfs.rst b/lib/mongoc/libmongoc/doc/gridfs.rst deleted file mode 100644 index 4e5848949614e11e9516e7ba7572d65a461e430b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/gridfs.rst +++ /dev/null @@ -1,10 +0,0 @@ -GridFS -====== - -The C driver includes two APIs for GridFS. - -The older API consists of :symbol:`mongoc_gridfs_t` and its derivatives. It contains deprecated API, does not support read preferences, and is not recommended in new applications. It does not conform to the `MongoDB GridFS specification <https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst>`_. - -The newer API consists of :symbol:`mongoc_gridfs_bucket_t` and allows uploading/downloading through derived :symbol:`mongoc_stream_t` objects. It conforms to the `MongoDB GridFS specification <https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst>`_. - -There is not always a straightforward upgrade path from an application built with :symbol:`mongoc_gridfs_t` to :symbol:`mongoc_gridfs_bucket_t` (e.g. a :symbol:`mongoc_gridfs_file_t` provides functions to seek but :symbol:`mongoc_stream_t` does not). But users are encouraged to upgrade when possible. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/guides.rst b/lib/mongoc/libmongoc/doc/guides.rst deleted file mode 100644 index 43d22c2cc39e7bbccc233891f72273112c6aa4d7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/guides.rst +++ /dev/null @@ -1,20 +0,0 @@ -:man_page: mongoc_guides - -Guides -====== - -.. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc-common-task-examples - advanced-connections - connection-pooling - cursors - bulk - aggregate - distinct-mapreduce - visual-studio-guide - create-indexes - debugging - using_client_side_encryption diff --git a/lib/mongoc/libmongoc/doc/html/CMakeLists.txt b/lib/mongoc/libmongoc/doc/html/CMakeLists.txt deleted file mode 100644 index 6211f56fc6519a6b405a4680e4bf1d6bc6f5d684..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/html/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -file (GLOB_RECURSE _images_pngs - RELATIVE ${PROJECT_SOURCE_DIR}/doc/static - ${PROJECT_SOURCE_DIR}/doc/static/*.png -) -foreach (png IN LISTS _images_pngs) - extra_dist_generated (_images/${png}) -endforeach () - -# Additional generated static files -extra_dist_generated ( - .nojekyll - objects.inv - _static/ajax-loader.gif - _static/basic.css - _static/comment-bright.png - _static/comment-close.png - _static/comment.png - _static/doctools.js - _static/down-pressed.png - _static/down.png - _static/file.png - _static/jquery.js - _static/minus.png - _static/mongoc.css - _static/plus.png - _static/pygments.css - _static/searchtools.js - _static/underscore.js - _static/up-pressed.png - _static/up.png - _static/websupport.js - genindex.html - search.html - searchindex.js -) - -set_dist_list (src_libmongoc_doc_html_DIST - CMakeLists.txt -) diff --git a/lib/mongoc/libmongoc/doc/includes/CMakeLists.txt b/lib/mongoc/libmongoc/doc/includes/CMakeLists.txt deleted file mode 100644 index e59474f7d6771a77f50e63df15b96634065b5bbf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -file (GLOB src_libmongoc_doc_includes_DIST_txts - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.txt -) - -set_dist_list (src_libmongoc_doc_includes_DIST - CMakeLists.txt - ${src_libmongoc_doc_includes_DIST_txts} -) diff --git a/lib/mongoc/libmongoc/doc/includes/aggregate-opts.txt b/lib/mongoc/libmongoc/doc/includes/aggregate-opts.txt deleted file mode 100644 index 363e7bbabf15878b17a3c12692d8b019a0b73075..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/aggregate-opts.txt +++ /dev/null @@ -1,9 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``readConcern``: Construct a :symbol:`mongoc_read_concern_t` and use :symbol:`mongoc_read_concern_append` to add the read concern to ``opts``. See the example code for :symbol:`mongoc_client_read_command_with_opts`. Read concern requires MongoDB 3.2 or later, otherwise an error is returned. -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``bypassDocumentValidation``: Set to ``true`` to skip server-side schema validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``serverId``: To target a specific server, include an int32 "serverId" field. Obtain the id by calling :symbol:`mongoc_client_select_server`, then :symbol:`mongoc_server_description_id` on its return value. -* ``batchSize``: An ``int32`` representing number of documents requested to be returned on each call to :symbol:`mongoc_cursor_next` diff --git a/lib/mongoc/libmongoc/doc/includes/bulk-insert-opts.txt b/lib/mongoc/libmongoc/doc/includes/bulk-insert-opts.txt deleted file mode 100644 index 4165bcd31c755186d05a8c24762188b33df1dbd5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/bulk-insert-opts.txt +++ /dev/null @@ -1,3 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. diff --git a/lib/mongoc/libmongoc/doc/includes/bulk-opts.txt b/lib/mongoc/libmongoc/doc/includes/bulk-opts.txt deleted file mode 100644 index 1e72800eaf9f498f982abf2404030d3cb985c5e2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/bulk-opts.txt +++ /dev/null @@ -1,5 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``ordered``: set to ``false`` to attempt to insert all documents, continuing after errors. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. diff --git a/lib/mongoc/libmongoc/doc/includes/bulk-remove-many-opts.txt b/lib/mongoc/libmongoc/doc/includes/bulk-remove-many-opts.txt deleted file mode 100644 index 099c46ea578a3dbdf31615a68a42a777aa94ba81..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/bulk-remove-many-opts.txt +++ /dev/null @@ -1,3 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. diff --git a/lib/mongoc/libmongoc/doc/includes/bulk-remove-one-opts.txt b/lib/mongoc/libmongoc/doc/includes/bulk-remove-one-opts.txt deleted file mode 100644 index 099c46ea578a3dbdf31615a68a42a777aa94ba81..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/bulk-remove-one-opts.txt +++ /dev/null @@ -1,3 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. diff --git a/lib/mongoc/libmongoc/doc/includes/bulk-remove-opts.txt b/lib/mongoc/libmongoc/doc/includes/bulk-remove-opts.txt deleted file mode 100644 index 72e0f4804d97c3e63c1460ed8ffcb97edddb2b02..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/bulk-remove-opts.txt +++ /dev/null @@ -1,3 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. diff --git a/lib/mongoc/libmongoc/doc/includes/bulk-replace-one-opts.txt b/lib/mongoc/libmongoc/doc/includes/bulk-replace-one-opts.txt deleted file mode 100644 index 5935d3fd6ba6f440c44036e0316228c2a8ab623a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/bulk-replace-one-opts.txt +++ /dev/null @@ -1,5 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``upsert``: If true, insert a document if none match ``selector``. diff --git a/lib/mongoc/libmongoc/doc/includes/bulk-update-many-opts.txt b/lib/mongoc/libmongoc/doc/includes/bulk-update-many-opts.txt deleted file mode 100644 index 84819a92ec064edb076057bb8aa5071dfbad1e2c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/bulk-update-many-opts.txt +++ /dev/null @@ -1,6 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``upsert``: If true, insert a document if none match ``selector``. -* ``arrayFilters``: An array of filters specifying to which array elements an update should apply. diff --git a/lib/mongoc/libmongoc/doc/includes/bulk-update-one-opts.txt b/lib/mongoc/libmongoc/doc/includes/bulk-update-one-opts.txt deleted file mode 100644 index 84819a92ec064edb076057bb8aa5071dfbad1e2c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/bulk-update-one-opts.txt +++ /dev/null @@ -1,6 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``upsert``: If true, insert a document if none match ``selector``. -* ``arrayFilters``: An array of filters specifying to which array elements an update should apply. diff --git a/lib/mongoc/libmongoc/doc/includes/cast-away-td-const.txt b/lib/mongoc/libmongoc/doc/includes/cast-away-td-const.txt deleted file mode 100644 index 7cfb734954e0198b7adbeb938d2154662ebbb55a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/cast-away-td-const.txt +++ /dev/null @@ -1 +0,0 @@ -Use this function in a topology-changed callback registered with :symbol:`mongoc_apm_set_topology_changed_cb`. For historical reasons, the :symbol:`mongoc_topology_description_t` passed to the callback is a const pointer, you must cast away const to pass the pointer to |td-func|. diff --git a/lib/mongoc/libmongoc/doc/includes/change-stream-opts.txt b/lib/mongoc/libmongoc/doc/includes/change-stream-opts.txt deleted file mode 100644 index 5fa18365985ccd13008d11ff7aa8d89515265bf3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/change-stream-opts.txt +++ /dev/null @@ -1,8 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``batchSize``: An ``int32`` representing number of documents requested to be returned on each call to :symbol:`mongoc_change_stream_next` -* ``resumeAfter``: A ``Document`` representing the logical starting point of the change stream. The ``_id`` field of any change received from a change stream can be used here. This option is mutually exclusive with ``startAfter`` and ``startAtOperationTime``. -* ``startAfter``: A ``Document`` representing the logical starting point of the change stream. Unlike ``resumeAfter``, this can resume notifications after an "invalidate" event. The ``_id`` field of any change received from a change stream can be used here. This option is mutually exclusive with ``resumeAfter`` and ``startAtOperationTime``. -* ``startAtOperationTime``: A ``Timestamp``. The change stream only provides changes that occurred at or after the specified timestamp. Any command run against the server will return an operation time that can be used here. This option is mutually exclusive with ``resumeAfter`` and ``startAfter``. -* ``maxAwaitTimeMS``: An ``int64`` representing the maximum amount of time a call to :symbol:`mongoc_change_stream_next` will block waiting for data -* ``fullDocument``: A UTF-8 string. Set this option to "updateLookup" to direct the change stream cursor to lookup the most current majority-committed version of the document associated to an update change stream event. diff --git a/lib/mongoc/libmongoc/doc/includes/create-index-opts.txt b/lib/mongoc/libmongoc/doc/includes/create-index-opts.txt deleted file mode 100644 index cb0db1bb2c9a90d26c65205b893415b562678f56..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/create-index-opts.txt +++ /dev/null @@ -1,4 +0,0 @@ -``command_opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. diff --git a/lib/mongoc/libmongoc/doc/includes/delete-many-opts.txt b/lib/mongoc/libmongoc/doc/includes/delete-many-opts.txt deleted file mode 100644 index d075473c5f98edf0e0a6c3ad04f4cc16a7a80140..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/delete-many-opts.txt +++ /dev/null @@ -1,6 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. diff --git a/lib/mongoc/libmongoc/doc/includes/delete-one-opts.txt b/lib/mongoc/libmongoc/doc/includes/delete-one-opts.txt deleted file mode 100644 index d075473c5f98edf0e0a6c3ad04f4cc16a7a80140..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/delete-one-opts.txt +++ /dev/null @@ -1,6 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. diff --git a/lib/mongoc/libmongoc/doc/includes/generic-opts.txt b/lib/mongoc/libmongoc/doc/includes/generic-opts.txt deleted file mode 100644 index 48973aef7f2de582d4e30a99b6068262fdf4247c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/generic-opts.txt +++ /dev/null @@ -1,4 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``serverId``: To target a specific server, include an int32 "serverId" field. Obtain the id by calling :symbol:`mongoc_client_select_server`, then :symbol:`mongoc_server_description_id` on its return value. diff --git a/lib/mongoc/libmongoc/doc/includes/gridfs-bucket-opts.txt b/lib/mongoc/libmongoc/doc/includes/gridfs-bucket-opts.txt deleted file mode 100644 index 5901ee744c356b6f0defc3e69e73e12d1f39accf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/gridfs-bucket-opts.txt +++ /dev/null @@ -1,6 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``bucketName``: A UTF-8 string used as the prefix to the GridFS "chunks" and "files" collections. Defaults to "fs". The bucket name, together with the database and suffix collections must not exceed 120 characters. See the manual for `the max namespace length <https://docs.mongodb.com/manual/reference/limits/#Namespace-Length>`_. -* ``chunkSizeBytes``: An ``int32`` representing the chunk size. Defaults to 255KB. -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``readConcern``: Construct a :symbol:`mongoc_read_concern_t` and use :symbol:`mongoc_read_concern_append` to add the read concern to ``opts``. See the example code for :symbol:`mongoc_client_read_command_with_opts`. Read concern requires MongoDB 3.2 or later, otherwise an error is returned. diff --git a/lib/mongoc/libmongoc/doc/includes/gridfs-bucket-upload-opts.txt b/lib/mongoc/libmongoc/doc/includes/gridfs-bucket-upload-opts.txt deleted file mode 100644 index 7f293fc225cd667d37f5e8b7e39cb9c40f460626..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/gridfs-bucket-upload-opts.txt +++ /dev/null @@ -1,4 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``chunkSizeBytes``: An ``int32`` chunk size to use for this file. Overrides the ``chunkSizeBytes`` set on ``bucket``. -* ``metadata``: A :symbol:`bson_t` representing metadata to include with the file. diff --git a/lib/mongoc/libmongoc/doc/includes/init_cleanup.txt b/lib/mongoc/libmongoc/doc/includes/init_cleanup.txt deleted file mode 100644 index 62fc594820d716307d14e913d149df3254a42fa6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/init_cleanup.txt +++ /dev/null @@ -1,3 +0,0 @@ -Initialize the MongoDB C Driver by calling :symbol:`mongoc_init` exactly once at the beginning of your program. It is responsible for initializing global state such as process counters, SSL, and threading primitives. - -Call :symbol:`mongoc_cleanup` exactly once at the end of your program to release all memory and other resources allocated by the driver. You must not call any other MongoDB C Driver functions after :symbol:`mongoc_cleanup`. Note that :symbol:`mongoc_init` does **not** reinitialize the driver after :symbol:`mongoc_cleanup`. diff --git a/lib/mongoc/libmongoc/doc/includes/insert-many-opts.txt b/lib/mongoc/libmongoc/doc/includes/insert-many-opts.txt deleted file mode 100644 index 0564f359ca06598aef33a95dcad08fe247d5f2b6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/insert-many-opts.txt +++ /dev/null @@ -1,7 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``ordered``: set to ``false`` to attempt to insert all documents, continuing after errors. -* ``bypassDocumentValidation``: Set to ``true`` to skip server-side schema validation of the provided BSON documents. diff --git a/lib/mongoc/libmongoc/doc/includes/insert-one-opts.txt b/lib/mongoc/libmongoc/doc/includes/insert-one-opts.txt deleted file mode 100644 index 61c2153422f8869cb26d360e8b62b01b3d381cfd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/insert-one-opts.txt +++ /dev/null @@ -1,6 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``bypassDocumentValidation``: Set to ``true`` to skip server-side schema validation of the provided BSON documents. diff --git a/lib/mongoc/libmongoc/doc/includes/ipv4-and-ipv6.txt b/lib/mongoc/libmongoc/doc/includes/ipv4-and-ipv6.txt deleted file mode 100644 index e85e4b9ba43614eecf3a7903f5876c86efa7eab3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/ipv4-and-ipv6.txt +++ /dev/null @@ -1,5 +0,0 @@ -If connecting to a hostname that has both IPv4 and IPv6 DNS records, the behavior follows `RFC-6555 <https://www.ietf.org/rfc/rfc6555.txt>`_. A connection to the IPv6 address is attempted first. If IPv6 fails, then a connection is attempted to the IPv4 address. If the connection attempt to IPv6 does not complete within 250ms, then IPv4 is tried in parallel. Whichever succeeds connection first cancels the other. The successful DNS result is cached for 10 minutes. - -As a consequence, attempts to connect to a mongod only listening on IPv4 may be delayed if there are both A (IPv4) and AAAA (IPv6) DNS records associated with the host. - -To avoid a delay, configure hostnames to match the MongoDB configuration. That is, only create an A record if the mongod is only listening on IPv4. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/includes/mongoc_client_pool_call_once.txt b/lib/mongoc/libmongoc/doc/includes/mongoc_client_pool_call_once.txt deleted file mode 100644 index 12e0afed176c9db5f563e17003b3d140c0ecbb1d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/mongoc_client_pool_call_once.txt +++ /dev/null @@ -1,4 +0,0 @@ -Thread Safety -------------- - -This function can only be called once on a pool, and must be called before the first call to :symbol:`mongoc_client_pool_pop`. diff --git a/lib/mongoc/libmongoc/doc/includes/mongoc_client_pool_thread_safe.txt b/lib/mongoc/libmongoc/doc/includes/mongoc_client_pool_thread_safe.txt deleted file mode 100644 index 9a2b7dc62fd836b399363691f4560bdc15d9a9f1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/mongoc_client_pool_thread_safe.txt +++ /dev/null @@ -1,4 +0,0 @@ -Thread Safety -------------- - -This function is safe to call from multiple threads. diff --git a/lib/mongoc/libmongoc/doc/includes/not-retryable-read.txt b/lib/mongoc/libmongoc/doc/includes/not-retryable-read.txt deleted file mode 100644 index b91b6abae4704add940385d8479bd2a372246a60..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/not-retryable-read.txt +++ /dev/null @@ -1 +0,0 @@ -This function is not considered a retryable read operation. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/includes/opts-sources.txt b/lib/mongoc/libmongoc/doc/includes/opts-sources.txt deleted file mode 100644 index 4e6b7dd287fdf7a09ca93adda932cb1ee8d78186..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/opts-sources.txt +++ /dev/null @@ -1,11 +0,0 @@ -Read preferences, read and write concern, and collation can be overridden by various sources. The highest-priority sources for these options are listed first: - -================== ============== ============== ========= -Read Preferences Read Concern Write Concern Collation -================== ============== ============== ========= -``read_prefs`` ``opts`` ``opts`` ``opts`` -Transaction Transaction Transaction -================== ============== ============== ========= - -In a transaction, read concern and write concern are prohibited in ``opts`` and the read preference must be primary or NULL. -:ref:`See the example for transactions <mongoc_client_session_start_transaction_example>` and for :ref:`the "distinct" command with opts <mongoc_client_read_command_with_opts_example>`. diff --git a/lib/mongoc/libmongoc/doc/includes/read-cmd-opts-sources.txt b/lib/mongoc/libmongoc/doc/includes/read-cmd-opts-sources.txt deleted file mode 100644 index 3fafcdb1edb6c1df9ddf96b8d4b2644967512cdc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/read-cmd-opts-sources.txt +++ /dev/null @@ -1,3 +0,0 @@ -Use this function for commands that read such as "count" or "distinct". - -.. include:: includes/read-opts-sources.txt diff --git a/lib/mongoc/libmongoc/doc/includes/read-opts-sources.txt b/lib/mongoc/libmongoc/doc/includes/read-opts-sources.txt deleted file mode 100644 index e9f5f29bc4a1b4db15360cd344a5c2283d5e84da..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/read-opts-sources.txt +++ /dev/null @@ -1,11 +0,0 @@ -Read preferences, read concern, and collation can be overridden by various sources. In a transaction, read concern and write concern are prohibited in ``opts`` and the read preference must be primary or NULL. The highest-priority sources for these options are listed first in the following table. No write concern is applied. - -================== ============== ========= -Read Preferences Read Concern Collation -================== ============== ========= -``read_prefs`` ``opts`` ``opts`` -Transaction Transaction -|opts-source| -================== ============== ========= - -:ref:`See the example for transactions <mongoc_client_session_start_transaction_example>` and for :ref:`the "distinct" command with opts <mongoc_client_read_command_with_opts_example>`. diff --git a/lib/mongoc/libmongoc/doc/includes/read-opts.txt b/lib/mongoc/libmongoc/doc/includes/read-opts.txt deleted file mode 100644 index 7d596909ba4bff81607ab31c834bb1d812f4c080..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/read-opts.txt +++ /dev/null @@ -1,6 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``readConcern``: Construct a :symbol:`mongoc_read_concern_t` and use :symbol:`mongoc_read_concern_append` to add the read concern to ``opts``. See the example code for :symbol:`mongoc_client_read_command_with_opts`. Read concern requires MongoDB 3.2 or later, otherwise an error is returned. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``serverId``: To target a specific server, include an int32 "serverId" field. Obtain the id by calling :symbol:`mongoc_client_select_server`, then :symbol:`mongoc_server_description_id` on its return value. diff --git a/lib/mongoc/libmongoc/doc/includes/read-write-opts-sources.txt b/lib/mongoc/libmongoc/doc/includes/read-write-opts-sources.txt deleted file mode 100644 index 2eda77a6c208e89354919036e8a8a7fa513e2ae6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/read-write-opts-sources.txt +++ /dev/null @@ -1,13 +0,0 @@ -Use this function for commands that both read and write, such as "mapReduce" with an output collection. - -Read and write concern and collation can be overridden by various sources. In a transaction, read concern and write concern are prohibited in ``opts``. The highest-priority sources for these options are listed first in the following table. Read preferences are *not* applied. The write concern is omitted for MongoDB before 3.4. - -============== ============== ========= -Read Concern Write Concern Collation -============== ============== ========= -``opts`` ``opts`` ``opts`` -Transaction Transaction -|opts-source| |opts-source| -============== ============== ========= - -:ref:`See the example for transactions <mongoc_client_session_start_transaction_example>` and for :ref:`the "distinct" command with opts <mongoc_client_read_command_with_opts_example>`. diff --git a/lib/mongoc/libmongoc/doc/includes/read-write-opts.txt b/lib/mongoc/libmongoc/doc/includes/read-write-opts.txt deleted file mode 100644 index d3da004657f38a4413913c39c18abdfcda7801e1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/read-write-opts.txt +++ /dev/null @@ -1,7 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``readConcern``: Construct a :symbol:`mongoc_read_concern_t` and use :symbol:`mongoc_read_concern_append` to add the read concern to ``opts``. See the example code for :symbol:`mongoc_client_read_command_with_opts`. Read concern requires MongoDB 3.2 or later, otherwise an error is returned. -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``serverId``: To target a specific server, include an int32 "serverId" field. Obtain the id by calling :symbol:`mongoc_client_select_server`, then :symbol:`mongoc_server_description_id` on its return value. diff --git a/lib/mongoc/libmongoc/doc/includes/replace-one-opts.txt b/lib/mongoc/libmongoc/doc/includes/replace-one-opts.txt deleted file mode 100644 index dac15519a105f8fff175129bd5237f7b18ff6989..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/replace-one-opts.txt +++ /dev/null @@ -1,8 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``bypassDocumentValidation``: Set to ``true`` to skip server-side schema validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``upsert``: When true, creates a new document if no document matches the query. diff --git a/lib/mongoc/libmongoc/doc/includes/retryable-read-aggregate.txt b/lib/mongoc/libmongoc/doc/includes/retryable-read-aggregate.txt deleted file mode 100644 index 51c88ef95e81abe4ae460959454c449264d34f03..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/retryable-read-aggregate.txt +++ /dev/null @@ -1,3 +0,0 @@ -This function is considered a retryable read operation unless the pipeline contains a write stage like $out or $merge. -Upon a transient error (a network error, errors due to replica set failover, etc.) the operation is safely retried once. -If ``retryreads`` is false in the URI (see :symbol:`mongoc_uri_t`) the retry behavior does not apply. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/includes/retryable-read-command.txt b/lib/mongoc/libmongoc/doc/includes/retryable-read-command.txt deleted file mode 100644 index 90538bd1f840feb4ca6b05327ab5c8b6512502eb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/retryable-read-command.txt +++ /dev/null @@ -1,2 +0,0 @@ -Retry logic occurs regardless of the underlying command. Retrying ``mapReduce`` has the potential for degraded performance. -Retrying a ``getMore`` command has the potential to miss results. For those commands, use generic command helpers (like |generic-cmd|) instead. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/includes/retryable-read.txt b/lib/mongoc/libmongoc/doc/includes/retryable-read.txt deleted file mode 100644 index 7d76e75c21a9ac205518b6e70dc42b6fba3174c2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/retryable-read.txt +++ /dev/null @@ -1,3 +0,0 @@ -This function is considered a retryable read operation. -Upon a transient error (a network error, errors due to replica set failover, etc.) the operation is safely retried once. -If ``retryreads`` is false in the URI (see :symbol:`mongoc_uri_t`) the retry behavior does not apply. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/includes/session-lifecycle.txt b/lib/mongoc/libmongoc/doc/includes/session-lifecycle.txt deleted file mode 100644 index 5ba476235995af55966a4c111fb1065cc4c61879..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/session-lifecycle.txt +++ /dev/null @@ -1,9 +0,0 @@ -Start a session with :symbol:`mongoc_client_start_session`, use the session for a sequence of operations and multi-document transactions, then free it with :symbol:`mongoc_client_session_destroy()`. Any :symbol:`mongoc_cursor_t` or :symbol:`mongoc_change_stream_t` using a session must be destroyed before the session, and a session must be destroyed before the :symbol:`mongoc_client_t` it came from. - -By default, sessions are `causally consistent <http://dochub.mongodb.org/core/causal-consistency>`_. To disable causal consistency, before starting a session create a :symbol:`mongoc_session_opt_t` with :symbol:`mongoc_session_opts_new()` and call :symbol:`mongoc_session_opts_set_causal_consistency()`, then free the struct with :symbol:`mongoc_session_opts_destroy`. - -Unacknowledged writes are prohibited with sessions. - -.. the timeout warning is mandated by the Driver Sessions Spec - -A :symbol:`mongoc_client_session_t` must be used by only one thread at a time. Due to session pooling, :symbol:`mongoc_client_start_session` may return a session that has been idle for some time and is about to be closed after its idle timeout. Use the session within one minute of acquiring it to refresh the session and avoid a timeout. diff --git a/lib/mongoc/libmongoc/doc/includes/update-many-opts.txt b/lib/mongoc/libmongoc/doc/includes/update-many-opts.txt deleted file mode 100644 index 51ecd280704dadcf87e2ad673421577fd0edfd69..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/update-many-opts.txt +++ /dev/null @@ -1,9 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``bypassDocumentValidation``: Set to ``true`` to skip server-side schema validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``upsert``: When true, creates a new document if no document matches the query. -* ``arrayFilters``: An array of filters specifying to which array elements an update should apply. diff --git a/lib/mongoc/libmongoc/doc/includes/update-one-opts.txt b/lib/mongoc/libmongoc/doc/includes/update-one-opts.txt deleted file mode 100644 index 51ecd280704dadcf87e2ad673421577fd0edfd69..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/update-one-opts.txt +++ /dev/null @@ -1,9 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``validate``: Construct a bitwise-or of all desired :symbol:`bson_validate_flags_t <bson_validate_with_error>`. Set to ``false`` to skip client-side validation of the provided BSON documents. -* ``bypassDocumentValidation``: Set to ``true`` to skip server-side schema validation of the provided BSON documents. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``upsert``: When true, creates a new document if no document matches the query. -* ``arrayFilters``: An array of filters specifying to which array elements an update should apply. diff --git a/lib/mongoc/libmongoc/doc/includes/write-opts-sources.txt b/lib/mongoc/libmongoc/doc/includes/write-opts-sources.txt deleted file mode 100644 index 245ab2a58b6887d0ab87bc94ade7c79529834c20..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/write-opts-sources.txt +++ /dev/null @@ -1,11 +0,0 @@ -Use this function for commands that write such as "drop" or "createRole" (but not for "insert", "update", or "delete", see `Basic Write Operations`_). Write concern and collation can be overridden by various sources. In a transaction, read concern and write concern are prohibited in ``opts``. The highest-priority sources for these options are listed first in the following table. The write concern is omitted for MongoDB before 3.4. - -============== ========= -Write Concern Collation -============== ========= -``opts`` ``opts`` -Transaction -|opts-source| -============== ========= - -:ref:`See the example for transactions <mongoc_client_session_start_transaction_example>` and for :ref:`the "distinct" command with opts <mongoc_client_read_command_with_opts_example>`. diff --git a/lib/mongoc/libmongoc/doc/includes/write-opts.txt b/lib/mongoc/libmongoc/doc/includes/write-opts.txt deleted file mode 100644 index 8de41d31d43cf16e0b641bdd0f9320432251b3f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/includes/write-opts.txt +++ /dev/null @@ -1,6 +0,0 @@ -``opts`` may be NULL or a BSON document with additional command options: - -* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`. -* ``sessionId``: First, construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from |opts-source|, and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. -* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned. -* ``serverId``: To target a specific server, include an int32 "serverId" field. Obtain the id by calling :symbol:`mongoc_client_select_server`, then :symbol:`mongoc_server_description_id` on its return value. diff --git a/lib/mongoc/libmongoc/doc/index.rst b/lib/mongoc/libmongoc/doc/index.rst deleted file mode 100644 index eab7d486eed31c3d302969c8a098ef40175470c8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/index.rst +++ /dev/null @@ -1,48 +0,0 @@ -MongoDB C Driver -================ - -A Cross Platform MongoDB Client Library for C - -Introduction ------------- - -The MongoDB C Driver, also known as "libmongoc", is a library for using MongoDB from C applications, and for writing MongoDB drivers in higher-level languages. - -It depends on :doc:`libbson <bson:index>` to generate and parse BSON documents, the native data format of MongoDB. - -.. toctree:: - :maxdepth: 2 - - installing - -.. toctree:: - :maxdepth: 2 - - tutorial - -.. toctree:: - :maxdepth: 2 - - authentication - -.. toctree:: - :maxdepth: 2 - - basic-troubleshooting - -.. toctree:: - :maxdepth: 2 - - guides - -.. toctree:: - :titlesonly: - :maxdepth: 2 - - api - -.. toctree:: - :titlesonly: - :maxdepth: 2 - - application-performance-monitoring diff --git a/lib/mongoc/libmongoc/doc/init-cleanup.rst b/lib/mongoc/libmongoc/doc/init-cleanup.rst deleted file mode 100644 index 24fc15d0d8138caf00feda74e1fc6d58cf571147..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/init-cleanup.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_init_cleanup - -Initialization and cleanup -========================== - -Synopsis --------- - -.. include:: includes/init_cleanup.txt - -.. only:: html - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_init - mongoc_cleanup - -Deprecated feature: automatic initialization and cleanup --------------------------------------------------------- - -On some platforms the driver can automatically call :symbol:`mongoc_init` before ``main``, and call :symbol:`mongoc_cleanup` as the process exits. This is problematic in situations where related libraries also execute cleanup code on shutdown, and it creates inconsistent rules across platforms. Therefore the automatic initialization and cleanup feature is deprecated, and will be dropped in version 2.0. Meanwhile, for backward compatibility, the feature is *enabled* by default on platforms where it is available. - -For portable, future-proof code, always call :symbol:`mongoc_init` and :symbol:`mongoc_cleanup` yourself, and configure the driver like: - -.. code-block:: none - - cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=NO diff --git a/lib/mongoc/libmongoc/doc/installing.rst b/lib/mongoc/libmongoc/doc/installing.rst deleted file mode 100644 index cce831b52ab78aa0d5502d19235807e7cc6e9a8c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/installing.rst +++ /dev/null @@ -1,302 +0,0 @@ -:man_page: mongoc_installing - -Installing the MongoDB C Driver (libmongoc) and BSON library (libbson) -====================================================================== - -The following guide will step you through the process of downloading, building, and installing the current release of the MongoDB C Driver (libmongoc) and BSON library (libbson). - -Supported Platforms -------------------- - -The MongoDB C Driver is `continuously tested <https://evergreen.mongodb.com/waterfall/mongo-c-driver>`_ on variety of platforms including: - -- Archlinux -- Debian 9.2 -- macOS 10.12 -- Microsoft Windows Server 2008 -- RHEL 7.0, 7.1, 7.2 -- Ubuntu 16.04, 18.04 -- Clang 3.4, 3.5, 3.7, 3.8 -- GCC 4.6, 4.8, 4.9, 5.4, 6.3 -- MinGW-W64 -- Visual Studio 2010, 2013, 2015 -- x86, x86_64, ARM (aarch64), Power8 (ppc64le), zSeries (s390x) - -Install libmongoc with a Package Manager ----------------------------------------- - -Several Linux distributions provide packages for libmongoc and its dependencies. One advantage of installing libmongoc with a package manager is that its dependencies (including libbson) will be installed automatically. - -The libmongoc package is available on recent versions of Debian and Ubuntu. - -.. code-block:: none - - $ apt-get install libmongoc-1.0-0 - -On Fedora, a mongo-c-driver package is available in the default repositories and can be installed with: - -.. code-block:: none - - $ dnf install mongo-c-driver - -On recent Red Hat systems, such as CentOS and RHEL 7, a mongo-c-driver package is available in the `EPEL <https://fedoraproject.org/wiki/EPEL>`_ repository. To check which version is available, see `https://apps.fedoraproject.org/packages/mongo-c-driver <https://apps.fedoraproject.org/packages/mongo-c-driver>`_. The package can be installed with: - -.. code-block:: none - - $ yum install mongo-c-driver - -Install libbson with a Package Manager --------------------------------------- - -The libbson package is available on recent versions of Debian and Ubuntu. If you have installed libmongoc, then libbson will have already been installed as a dependency. It is also possible to install libbson without libmongoc. - -.. code-block:: none - - $ apt-get install libbson-1.0 - -On Fedora, a libbson package is available in the default repositories and can be installed with: - -.. code-block:: none - - $ dnf install libbson - -On recent Red Hat systems, such as CentOS and RHEL 7, a libbson package -is available in the `EPEL <https://fedoraproject.org/wiki/EPEL>`_ repository. To check -which version is available, see `https://apps.fedoraproject.org/packages/libbson <https://apps.fedoraproject.org/packages/libbson>`_. -The package can be installed with: - -.. code-block:: none - - $ yum install libbson - -Building on Unix ----------------- - -Prerequisites for libmongoc -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -OpenSSL is required for authentication or for SSL connections to MongoDB. Kerberos or LDAP support requires Cyrus SASL. - -To install all optional dependencies on RedHat / Fedora: - -.. code-block:: none - - $ sudo yum install cmake openssl-devel cyrus-sasl-devel - -On Debian / Ubuntu: - -.. code-block:: none - - $ sudo apt-get install cmake libssl-dev libsasl2-dev - -On FreeBSD: - -.. code-block:: none - - $ su -c 'pkg install cmake openssl cyrus-sasl' - -Prerequisites for libbson -^^^^^^^^^^^^^^^^^^^^^^^^^ - -The only prerequisite for building libbson is ``cmake``. The command lines above can be adjusted to install only ``cmake``. - -Building from a release tarball -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Unless you intend to contribute to mongo-c-driver and/or libbson, you will want to build from a release tarball. - -The most recent release of libmongoc and libbson, both of which are included in mongo-c-driver, can be `downloaded here <https://github.com/mongodb/mongo-c-driver/releases/latest>`_. The instructions in this document utilize ``cmake``'s out-of-source build feature to keep build artifacts separate from source files. - -The following snippet will download and extract the driver, and configure it: - -.. parsed-literal:: - - $ wget https://github.com/mongodb/mongo-c-driver/releases/download/x.y.z/mongo-c-driver-x.y.z.tar.gz - $ tar xzf mongo-c-driver-x.y.z.tar.gz - $ cd mongo-c-driver-x.y.z - $ mkdir cmake-build - $ cd cmake-build - $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF .. - -The ``-DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF`` option is recommended, see :doc:`init-cleanup`. Another useful ``cmake`` option is ``-DCMAKE_BUILD_TYPE=Release`` for a release optimized build and ``-DCMAKE_BUILD_TYPE=Debug`` for a debug build. For a list of all configure options, run ``cmake -L ..``. - -If ``cmake`` completed successfully, you will see a considerable amount of output describing your build configuration. The final line of output should look something like this: - -.. parsed-literal:: - - -- Build files have been written to: /home/user/mongo-c-driver-x.y.z/cmake-build - -If ``cmake`` concludes with anything different, then there is likely an error or some other problem with the build. Review the output to identify and correct the problem. - -mongo-c-driver contains a copy of libbson, in case your system does not already have libbson installed. The build will detect if libbson is not installed and use the bundled libbson. - -Additionally, it is possible to build only libbson by setting the ``-DENABLE_MONGOC=OFF`` option: - -.. parsed-literal:: - - $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_MONGOC=OFF .. - -A build configuration description similar to the one above will be displayed, though with fewer entries. Once the configuration is complete, the selected items can be built and installed with these commands: - -.. code-block:: none - - $ make - $ sudo make install - -There are two ways to uninstall the components that have been installed. The first is to invoke the uninstall program directly. On Linux/Unix: - -.. code-block:: none - - $ sudo /usr/local/share/mongo-c-driver/uninstall.sh - -On Windows: - -.. code-block:: none - - C:\Users\user> C:\mongo-c-driver\share\mongo-c-driver\uninstall.bat - -The second way to uninstall is from within the build directory, assuming that it is in the exact same state as when the install command was invoked: - -.. code-block:: none - - $ sudo make uninstall - -The second approach simply invokes the uninstall program referenced in the first approach. - -Building from git -^^^^^^^^^^^^^^^^^ - -Clone the repository and build the current master or a particular release tag: - -.. code-block:: none - - $ git clone https://github.com/mongodb/mongo-c-driver.git - $ cd mongo-c-driver - $ git checkout x.y.z # To build a particular release - $ python build/calc_release_version.py > VERSION_CURRENT - $ mkdir cmake-build - $ cd cmake-build - $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF .. - $ make - $ sudo make install - -Generating the documentation -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Install `Sphinx <http://www.sphinx-doc.org/>`_, then: - -.. code-block:: none - - $ cmake -DENABLE_MAN_PAGES=ON -DENABLE_HTML_DOCS=ON .. - $ make mongoc-doc - -To build only the libbson documentation: - -.. code-block:: none - - $ cmake -DENABLE_MAN_PAGES=ON -DENABLE_HTML_DOCS=ON .. - $ make bson-doc - -The ``-DENABLE_MAN_PAGES=ON`` and ``-DENABLE_HTML_DOCS=ON`` can also be added as options to a normal build from a release tarball or from git so that the documentation is built at the same time as other components. - -Building on macOS ------------------ - -Install the XCode Command Line Tools:: - - $ xcode-select --install - -The ``cmake`` utility is also required. First `install Homebrew according to its instructions <https://brew.sh/>`_, then:: - - $ brew install cmake - -Download the latest release tarball: - -.. parsed-literal:: - - $ curl -LO https://github.com/mongodb/mongo-c-driver/releases/download/x.y.z/mongo-c-driver-x.y.z.tar.gz - $ tar xzf mongo-c-driver-x.y.z.tar.gz - $ cd mongo-c-driver-x.y.z - -Build and install the driver: - -.. code-block:: none - - $ mkdir cmake-build - $ cd cmake-build - $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF .. - -All of the same variations described above (e.g., building only libbson, building documentation, etc.) are available when building on macOS. - -.. _build-on-windows: - -Building on Windows with Visual Studio --------------------------------------- - -Building on Windows requires Windows Vista or newer and Visual Studio 2010 or newer. Additionally, ``cmake`` is required to generate Visual Studio project files. - -Let's start by generating Visual Studio project files. The following assumes we are compiling for 64-bit Windows using Visual Studio 2015 Express, which can be freely downloaded from Microsoft. We will be utilizing ``cmake``'s out-of-source build feature to keep build artifacts separate from source files. - -.. parsed-literal:: - - cd mongo-c-driver-x.y.z - mkdir cmake-build - cd cmake-build - cmake -G "Visual Studio 14 2015 Win64" \\ - "-DCMAKE_INSTALL_PREFIX=C:\\mongo-c-driver" \\ - "-DCMAKE_PREFIX_PATH=C:\\mongo-c-driver" \\ - .. - -(Run ``cmake -LH ..`` for a list of other options.) - -Now that we have project files generated, we can either open the project in Visual Studio or compile from the command line. Let's build using the command line program ``msbuild.exe``: - -.. code-block:: none - - msbuild.exe /p:Configuration=RelWithDebInfo ALL_BUILD.vcxproj - -Visual Studio's default build type is ``Debug``, but we recommend a release build with debug info for production use. Now that libmongoc and libbson are compiled, let's install them using msbuild. It will be installed to the path specified by ``CMAKE_INSTALL_PREFIX``. - -.. code-block:: none - - msbuild.exe INSTALL.vcxproj - -You should now see libmongoc and libbson installed in ``C:\mongo-c-driver`` - -To use the driver libraries in your program, see :doc:`visual-studio-guide`. - -Building on Windows with MinGW-W64 and MSYS2 --------------------------------------------- - -Install MSYS2 from `msys2.github.io <http://msys2.github.io>`_. Choose the x86_64 version, not i686. - -Open the MingGW shell with ``c:\msys64\ming64.exe`` (not the msys2_shell). Install dependencies: - -.. code-block:: none - - pacman --noconfirm -Syu - pacman --noconfirm -S mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake - pacman --noconfirm -S mingw-w64-x86_64-extra-cmake-modules make tar - pacman --noconfirm -S mingw64/mingw-w64-x86_64-cyrus-sasl - -Download and untar the latest tarball, enter its directory, and build with CMake: - -.. code-block:: none - - mkdir cmake-build - cd cmake-build - CC=/mingw64/bin/gcc.exe /mingw64/bin/cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX="C:/mongo-c-driver" -DCMAKE_C_FLAGS="-D__USE_MINGW_ANSI_STDIO=1" .. - make - -Additional Options for Integrators ----------------------------------- - -In the event that you are building the BSON library and/or the C driver to embed with other components and you wish to avoid the potential for collision with components installed from a standard build or from a distribution package manager, you can make use of the ``BSON_OUTPUT_BASENAME`` and ``MONGOC_OUTPUT_BASENAME`` options to ``cmake``. - -.. code-block:: none - - mkdir cmake-build - cd cmake-build - cmake -DBSON_OUTPUT_BASENAME=custom_bson -DMONGOC_OUTPUT_BASENAME=custom_mongoc .. - -The above command would produce libraries named ``libcustom_bson.so`` and ``libcustom_mongoc.so`` (or with the extension appropriate for the build platform). Those libraries could be placed in a standard system directory or in an alternate location and could be linked to by specifying something like ``-lcustom_mongoc -lcustom_bson`` on the linker command line (possibly adjusting the specific flags to those required by your linker). diff --git a/lib/mongoc/libmongoc/doc/libbson-objects.inv b/lib/mongoc/libmongoc/doc/libbson-objects.inv deleted file mode 100644 index 5d54a170dfcfadb4e1c71fd7a0d237d98f185828..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/doc/libbson-objects.inv and /dev/null differ diff --git a/lib/mongoc/libmongoc/doc/lifecycle.rst b/lib/mongoc/libmongoc/doc/lifecycle.rst deleted file mode 100644 index 8e33c03fb91acc9c98937fb20e1b6037806ddb8a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/lifecycle.rst +++ /dev/null @@ -1,39 +0,0 @@ -Object Lifecycle -================ - -This page documents the order of creation and destruction for libmongoc's main struct types. - -Clients and pools ------------------ - -Call :symbol:`mongoc_init()` once, before calling any other libmongoc functions, and call :symbol:`mongoc_cleanup()` once before your program exits. - -A program that uses libmongoc from multiple threads should create a :symbol:`mongoc_client_pool_t` with :symbol:`mongoc_client_pool_new()`. Each thread acquires a :symbol:`mongoc_client_t` from the pool with :symbol:`mongoc_client_pool_pop()` and returns it with :symbol:`mongoc_client_pool_push()` when the thread is finished using it. To destroy the pool, first return all clients, then call :symbol:`mongoc_client_pool_destroy()`. - -If your program uses libmongoc from only one thread, create a :symbol:`mongoc_client_t` directly with :symbol:`mongoc_client_new()` or :symbol:`mongoc_client_new_from_uri()`. Destroy it with :symbol:`mongoc_client_destroy()`. - -Databases, collections, and related objects -------------------------------------------- - -You can create a :symbol:`mongoc_database_t` or :symbol:`mongoc_collection_t` from a :symbol:`mongoc_client_t`, and create a :symbol:`mongoc_cursor_t` or :symbol:`mongoc_bulk_operation_t` from a :symbol:`mongoc_collection_t`. - -Each of these objects must be destroyed before the client they were created from, but their lifetimes are otherwise independent. - -GridFS objects --------------- - -You can create a :symbol:`mongoc_gridfs_t` from a :symbol:`mongoc_client_t`, create a :symbol:`mongoc_gridfs_file_t` or :symbol:`mongoc_gridfs_file_list_t` from a :symbol:`mongoc_gridfs_t`, create a :symbol:`mongoc_gridfs_file_t` from a :symbol:`mongoc_gridfs_file_list_t`, and create a :symbol:`mongoc_stream_t` from a :symbol:`mongoc_gridfs_file_t`. - -Each of these objects depends on the object it was created from. Always destroy GridFS objects in the reverse of the order they were created. The sole exception is that a :symbol:`mongoc_gridfs_file_t` need not be destroyed before the :symbol:`mongoc_gridfs_file_list_t` it was created from. - -GridFS bucket objects ---------------------- - -Create :symbol:`mongoc_gridfs_bucket_t` with a :symbol:`mongoc_database_t` derived from a :symbol:`mongoc_client_t`. The :symbol:`mongoc_database_t` is independent from the :symbol:`mongoc_gridfs_bucket_t`. But the :symbol:`mongoc_client_t` must outlive the :symbol:`mongoc_gridfs_bucket_t`. - -A :symbol:`mongoc_stream_t` may be created from the :symbol:`mongoc_gridfs_bucket_t`. The :symbol:`mongoc_gridfs_bucket_t` must outlive the :symbol:`mongoc_stream_t`. - -Sessions --------- - -.. include:: includes/session-lifecycle.txt diff --git a/lib/mongoc/libmongoc/doc/logging.rst b/lib/mongoc/libmongoc/doc/logging.rst deleted file mode 100644 index 07d284ddbbde1670bd15b77cdb049ea90c2bcb29..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/logging.rst +++ /dev/null @@ -1,130 +0,0 @@ -:man_page: mongoc_logging - -Logging -======= - -MongoDB C driver Logging Abstraction - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_LOG_LEVEL_ERROR, - MONGOC_LOG_LEVEL_CRITICAL, - MONGOC_LOG_LEVEL_WARNING, - MONGOC_LOG_LEVEL_MESSAGE, - MONGOC_LOG_LEVEL_INFO, - MONGOC_LOG_LEVEL_DEBUG, - MONGOC_LOG_LEVEL_TRACE, - } mongoc_log_level_t; - - #define MONGOC_ERROR(...) - #define MONGOC_CRITICAL(...) - #define MONGOC_WARNING(...) - #define MONGOC_MESSAGE(...) - #define MONGOC_INFO(...) - #define MONGOC_DEBUG(...) - - typedef void (*mongoc_log_func_t) (mongoc_log_level_t log_level, - const char *log_domain, - const char *message, - void *user_data); - - void - mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data); - void - mongoc_log (mongoc_log_level_t log_level, - const char *log_domain, - const char *format, - ...) BSON_GNUC_PRINTF (3, 4); - const char * - mongoc_log_level_str (mongoc_log_level_t log_level); - void - mongoc_log_default_handler (mongoc_log_level_t log_level, - const char *log_domain, - const char *message, - void *user_data); - void - mongoc_log_trace_enable (void); - void - mongoc_log_trace_disable (void); - -The MongoDB C driver comes with an abstraction for logging that you can use in your application, or integrate with an existing logging system. - -Macros ------- - -To make logging a little less painful, various helper macros are provided. See the following example. - -.. code-block:: c - - #undef MONGOC_LOG_DOMAIN - #define MONGOC_LOG_DOMAIN "my-custom-domain" - - MONGOC_WARNING ("An error occurred: %s", strerror (errno)); - -Custom Log Handlers -------------------- - -The default log handler prints a timestamp and the log message to ``stdout``, or to ``stderr`` for warnings, critical messages, and errors. - You can override the handler with ``mongoc_log_set_handler()``. - Your handler function is called in a mutex for thread safety. - -For example, you could register a custom handler to suppress messages at INFO level and below: - -.. code-block:: c - - void - my_logger (mongoc_log_level_t log_level, - const char *log_domain, - const char *message, - void *user_data) - { - /* smaller values are more important */ - if (log_level < MONGOC_LOG_LEVEL_INFO) { - mongoc_log_default_handler (log_level, log_domain, message, user_data); - } - } - - int - main (int argc, char *argv[]) - { - mongoc_init (); - mongoc_log_set_handler (my_logger, NULL); - - /* ... your code ... */ - - mongoc_cleanup (); - return 0; - } - -To restore the default handler: - -.. code-block:: c - - mongoc_log_set_handler (mongoc_log_default_handler, NULL); - -Disable logging ---------------- - -To disable all logging, including warnings, critical messages and errors, provide an empty log handler: - -.. code-block:: c - - mongoc_log_set_handler (NULL, NULL); - -Tracing -------- - -If compiling your own copy of the MongoDB C driver, consider configuring with ``-DENABLE_TRACING=ON`` to enable function tracing and hex dumps of network packets to ``STDERR`` and ``STDOUT`` during development and debugging. - -This is especially useful when debugging what may be going on internally in the driver. - -Trace messages can be enabled and disabled by calling ``mongoc_log_trace_enable()`` and ``mongoc_log_trace_disable()`` - -.. note:: - - Compiling the driver with ``-DENABLE_TRACING=ON`` will affect its performance. Disabling tracing with ``mongoc_log_trace_disable()`` significantly reduces the overhead, but cannot remove it completely. - diff --git a/lib/mongoc/libmongoc/doc/man/CMakeLists.txt b/lib/mongoc/libmongoc/doc/man/CMakeLists.txt deleted file mode 100644 index f155c234940a1816cf732f76e76cfba0c1af69eb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/man/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -set_dist_list (src_libmongoc_doc_man_DIST - CMakeLists.txt -) diff --git a/lib/mongoc/libmongoc/doc/matcher.rst b/lib/mongoc/libmongoc/doc/matcher.rst deleted file mode 100644 index c64cffd94ba9844f341df163760ac49e2e1cea14..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/matcher.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_matcher -:orphan: - -Client Side Document Matching -============================= - -Basic Document Matching (Deprecated) ------------------------------------- - -.. warning:: - - This feature will be removed in version 2.0. - -The MongoDB C driver supports matching a subset of the MongoDB query specification on the client. - -Currently, basic numeric, string, subdocument, and array equality, ``$gt``, ``$gte``, ``$lt``, ``$lte``, ``$in``, ``$nin``, ``$ne``, ``$exists``, ``$type``, ``$and``, and ``$or`` are supported. As this is not the same implementation as the MongoDB server, some inconsistencies may occur. Please file a bug if you find such a case. - -To test this, perform a ``mongodump`` of a single collection and pipe it to the program. - -.. code-block:: none - - $ echo "db.test.insert({hello:'world'})" | mongo - connecting to: test - WriteResult({ "nInserted" : 1 }) - bye - - $ mongodump -d test -c test -o - | filter-bsondump - { "_id" : { "$oid" : "537afac9a70e5b4d556153bc" }, "hello" : "world" } - diff --git a/lib/mongoc/libmongoc/doc/mongoc-common-task-examples.rst b/lib/mongoc/libmongoc/doc/mongoc-common-task-examples.rst deleted file mode 100644 index 40a45fee4d49081948fb7c8f31e50f91787cceff..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc-common-task-examples.rst +++ /dev/null @@ -1,108 +0,0 @@ -:man_page: mongoc_common_task_examples - -Common Tasks -============ - -Drivers for some other languages provide helper functions to perform certain common tasks. In the C Driver we must explicitly build commands to send to the server. - -Setup ------ - -First we'll write some code to insert sample data: - -.. literalinclude:: ../examples/doc-common-insert.c - :language: c - :caption: doc-common-insert.c - -"explain" Command ------------------ - -This is how to use the ``explain`` command in MongoDB 3.2+: - -.. literalinclude:: ../examples/common_operations/explain.c - :language: c - :caption: explain.c - -Running the Examples --------------------- - -.. literalinclude:: ../examples/common_operations/common-operations.c - :language: c - :caption: common-operations.c - -First launch two separate instances of mongod (must be done from separate shells): - -.. code-block:: none - - $ mongod - -.. code-block:: none - - $ mkdir /tmp/db2 - $ mongod --dbpath /tmp/db2 --port 27018 # second instance - -Now compile and run the example program: - -.. code-block:: none - - $ cd examples/common_operations/$ gcc -Wall -o example common-operations.c $(pkg-config --cflags --libs libmongoc-1.0)$ ./example localhost:27017 localhost:27018 - Inserting data - explain - { - "executionStats" : { - "allPlansExecution" : [], - "executionStages" : { - "advanced" : 19, - "direction" : "forward" , - "docsExamined" : 76, - "executionTimeMillisEstimate" : 0, - "filter" : { - "x" : { - "$eq" : 1 - } - }, - "invalidates" : 0, - "isEOF" : 1, - "nReturned" : 19, - "needTime" : 58, - "needYield" : 0, - "restoreState" : 0, - "saveState" : 0, - "stage" : "COLLSCAN" , - "works" : 78 - }, - "executionSuccess" : true, - "executionTimeMillis" : 0, - "nReturned" : 19, - "totalDocsExamined" : 76, - "totalKeysExamined" : 0 - }, - "ok" : 1, - "queryPlanner" : { - "indexFilterSet" : false, - "namespace" : "test.things", - "parsedQuery" : { - "x" : { - "$eq" : 1 - } - }, - "plannerVersion" : 1, - "rejectedPlans" : [], - "winningPlan" : { - "direction" : "forward" , - "filter" : { - "x" : { - "$eq" : 1 - } - }, - "stage" : "COLLSCAN" - } - }, - "serverInfo" : { - "gitVersion" : "05552b562c7a0b3143a729aaa0838e558dc49b25" , - "host" : "MacBook-Pro-57.local", - "port" : 27017, - "version" : "3.2.6" - } - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_destroy.rst deleted file mode 100644 index 5f73f0fe8f0903c14274cff086133ae1aeeeaedd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_destroy.rst +++ /dev/null @@ -1,20 +0,0 @@ -:man_page: mongoc_apm_callbacks_destroy - -mongoc_apm_callbacks_destroy() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks); - -Free a :symbol:`mongoc_apm_callbacks_t`. Does nothing if ``callbacks`` is NULL. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_new.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_new.rst deleted file mode 100644 index 076c66ba243ba00a9429fb995cff13da4cfcf7c7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_new.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_apm_callbacks_new - -mongoc_apm_callbacks_new() -========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_apm_callbacks_t * - mongoc_apm_callbacks_new (void); - -Create a struct to hold event-notification callbacks. - -Returns -------- - -A new ``mongoc_apm_callbacks_t`` you must free with :symbol:`mongoc_apm_callbacks_destroy`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_t.rst deleted file mode 100644 index fe3949fff5bdafcc7240ac5eae4c705f2bf83532..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_callbacks_t.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_apm_callbacks_t - -mongoc_apm_callbacks_t -====================== - -Notification callbacks - -Synopsis --------- - -Used to receive notification of events, such as when a MongoDB command begins, succeeds, or fails. - -Create a ``mongoc_apm_callbacks_t`` with :symbol:`mongoc_apm_callbacks_new`, set callbacks on it, then pass it to :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_callbacks_destroy - mongoc_apm_callbacks_new - mongoc_apm_set_command_failed_cb - mongoc_apm_set_command_started_cb - mongoc_apm_set_command_succeeded_cb - mongoc_apm_set_server_changed_cb - mongoc_apm_set_server_closed_cb - mongoc_apm_set_server_heartbeat_failed_cb - mongoc_apm_set_server_heartbeat_started_cb - mongoc_apm_set_server_heartbeat_succeeded_cb - mongoc_apm_set_server_opening_cb - mongoc_apm_set_topology_changed_cb - mongoc_apm_set_topology_closed_cb - mongoc_apm_set_topology_opening_cb - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_command_name.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_command_name.rst deleted file mode 100644 index b8118c60eb61678b721c160453cc5908bce8e91c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_command_name.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_command_name - -mongoc_apm_command_failed_get_command_name() -============================================ - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_apm_command_failed_get_command_name ( - const mongoc_apm_command_failed_t *event); - -Returns this event's command name. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. - -Returns -------- - -A string that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_context.rst deleted file mode 100644 index 03b19dcd940e57423db2c5242d216a313a9e2051..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_context - -mongoc_apm_command_failed_get_context() -======================================= - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_command_failed_get_context ( - const mongoc_apm_command_failed_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_duration.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_duration.rst deleted file mode 100644 index 071a1bc051109d27f68ce07cff92ed850d49325e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_duration.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_duration - -mongoc_apm_command_failed_get_duration() -======================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_command_failed_get_duration ( - const mongoc_apm_command_failed_t *event); - -Returns this event's duration in microseconds. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. - -Returns -------- - -The event's duration. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_error.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_error.rst deleted file mode 100644 index 39a1ad083b92cbff73bf038f48f2eaade21264b3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_error.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_error - -mongoc_apm_command_failed_get_error() -===================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event, - bson_error_t *error); - -Copies this event's error info. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. -* ``error``: A :symbol:`bson:bson_error_t` to receive the event's error info. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_host.rst deleted file mode 100644 index e322bb6cc275cc8a8b5712ee2036c52ac1bcda85..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_host.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_host - -mongoc_apm_command_failed_get_host() -==================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_operation_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_operation_id.rst deleted file mode 100644 index 4256adfdeae2a3380d7038140263f16b0cb979b3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_operation_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_operation_id - -mongoc_apm_command_failed_get_operation_id() -============================================ - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_command_failed_get_operation_id ( - const mongoc_apm_command_failed_t *event); - -Returns this event's operation id. This number correlates all the commands in a bulk operation, or all the "find" and "getMore" commands required to stream a large query result. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. - -Returns -------- - -The event's operation id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_reply.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_reply.rst deleted file mode 100644 index f69b58926119550d3131f1cc0400316b0e4e5ef8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_reply.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_reply - -mongoc_apm_command_failed_get_reply() -======================================== - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_apm_command_failed_get_reply ( - const mongoc_apm_command_failed_t *event); - -Returns the server's reply to a command that failed. The reply contains details about why the command failed. If no server reply was received, such as in the event of a network error, then the reply is a valid empty BSON document. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. - -Returns -------- - -A :symbol:`bson:bson_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_request_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_request_id.rst deleted file mode 100644 index 5d238c41ea297bf21a577753cbd8186692e87fc2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_request_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_request_id - -mongoc_apm_command_failed_get_request_id() -========================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_command_failed_get_request_id ( - const mongoc_apm_command_failed_t *event); - -Returns this event's wire-protocol request id. Use this number to correlate client-side events with server log messages. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. - -Returns -------- - -The event's request id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_server_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_server_id.rst deleted file mode 100644 index 1e29c6c6d893963c99c55717045e5a73fbcd03a1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_get_server_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_failed_get_server_id - -mongoc_apm_command_failed_get_server_id() -========================================= - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_apm_command_failed_get_server_id ( - const mongoc_apm_command_failed_t *event); - -Returns this event's server id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_failed_t`. - -Returns -------- - -The event's server id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_t.rst deleted file mode 100644 index 72fc90c5583933ec88fbaf2459cc4e5605a4f84c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_failed_t.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_apm_command_failed_t - -mongoc_apm_command_failed_t -=========================== - -Command-failed event - -Synopsis --------- - -An event notification sent when the driver fails to execute a MongoDB command. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_command_failed_get_command_name - mongoc_apm_command_failed_get_context - mongoc_apm_command_failed_get_duration - mongoc_apm_command_failed_get_error - mongoc_apm_command_failed_get_host - mongoc_apm_command_failed_get_operation_id - mongoc_apm_command_failed_get_reply - mongoc_apm_command_failed_get_request_id - mongoc_apm_command_failed_get_server_id - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_command.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_command.rst deleted file mode 100644 index 504421af1e5eda7bc02320a3afde54d50ec3088e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_command.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_started_get_command - -mongoc_apm_command_started_get_command() -======================================== - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_apm_command_started_get_command ( - const mongoc_apm_command_started_t *event); - -Returns this event's command. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_started_t`. - -Returns -------- - -A :symbol:`bson:bson_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_command_name.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_command_name.rst deleted file mode 100644 index cd76fccbb5443d01135ff58413523be4169068dc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_command_name.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_started_get_command_name - -mongoc_apm_command_started_get_command_name() -============================================= - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_apm_command_started_get_command_name ( - const mongoc_apm_command_started_t *event); - -Returns this event's command name. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_started_t`. - -Returns -------- - -A string that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_context.rst deleted file mode 100644 index 923a271d430bf3a4d5261ad1bc0a891a5bd55a51..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_started_get_context - -mongoc_apm_command_started_get_context() -======================================== - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_command_started_get_context ( - const mongoc_apm_command_started_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_started_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_database_name.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_database_name.rst deleted file mode 100644 index 6c6d781844324679607fc58b16e38ac8796cc201..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_database_name.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_started_get_database_name - -mongoc_apm_command_started_get_database_name() -============================================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_apm_command_started_get_database_name ( - const mongoc_apm_command_started_t *event); - -Returns this event's database name. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_started_t`. - -Returns -------- - -A string that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_host.rst deleted file mode 100644 index 76b3a452e6f610e32f65fc0c3b6af47821063aee..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_host.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_command_started_get_host - -mongoc_apm_command_started_get_host() -===================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_started_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_operation_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_operation_id.rst deleted file mode 100644 index 694d7fd1592f348079f754ccf636d601294ea262..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_operation_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_started_get_operation_id - -mongoc_apm_command_started_get_operation_id() -============================================= - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_command_started_get_operation_id ( - const mongoc_apm_command_started_t *event); - -Returns this event's operation id. This number correlates all the commands in a bulk operation, or all the "find" and "getMore" commands required to stream a large query result. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_started_t`. - -Returns -------- - -The event's operation id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_request_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_request_id.rst deleted file mode 100644 index 15e9a4a5ac8e1dadae8bf159ebeb0ca6215f89c0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_request_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_started_get_request_id - -mongoc_apm_command_started_get_request_id() -=========================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_command_started_get_request_id ( - const mongoc_apm_command_started_t *event); - -Returns this event's wire-protocol request id. Use this number to correlate client-side events with server log messages. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_started_t`. - -Returns -------- - -The event's request id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_server_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_server_id.rst deleted file mode 100644 index ea6207c486847e595243efa01ea2b1a086ed4f4b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_get_server_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_started_get_server_id - -mongoc_apm_command_started_get_server_id() -========================================== - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_apm_command_started_get_server_id ( - const mongoc_apm_command_started_t *event); - -Returns this event's server id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_started_t`. - -Returns -------- - -The event's server id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_t.rst deleted file mode 100644 index 007d2c156cf17d5f2ad24b43b6ceaec4287b44d4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_started_t.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_apm_command_started_t - -mongoc_apm_command_started_t -============================ - -Command-started event - -Synopsis --------- - -An event notification sent when the driver begins executing a MongoDB command. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_command_started_get_command - mongoc_apm_command_started_get_command_name - mongoc_apm_command_started_get_context - mongoc_apm_command_started_get_database_name - mongoc_apm_command_started_get_host - mongoc_apm_command_started_get_operation_id - mongoc_apm_command_started_get_request_id - mongoc_apm_command_started_get_server_id - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_command_name.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_command_name.rst deleted file mode 100644 index f938ecb509930a09e56e40c0f1f8cb2fbbd0a18a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_command_name.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_get_command_name - -mongoc_apm_command_succeeded_get_command_name() -=============================================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_apm_command_succeeded_get_command_name ( - const mongoc_apm_command_succeeded_t *event); - -Returns this event's command name. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_succeeded_t`. - -Returns -------- - -A string that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_context.rst deleted file mode 100644 index d7883b97e3930055da4f23059eaa94be706655d9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_get_context - -mongoc_apm_command_succeeded_get_context() -========================================== - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_command_succeeded_get_context ( - const mongoc_apm_command_succeeded_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_succeeded_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_duration.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_duration.rst deleted file mode 100644 index 011a4456fb731515261883fe1c19786a85f64326..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_duration.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_get_duration - -mongoc_apm_command_succeeded_get_duration() -=========================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_command_succeeded_get_duration ( - const mongoc_apm_command_succeeded_t *event); - -Returns this event's duration in microseconds. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_succeeded_t`. - -Returns -------- - -The event's duration. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_host.rst deleted file mode 100644 index 582e4df69602ce99de20e696d4a4230e1e20de00..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_host.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_get_host - -mongoc_apm_command_succeeded_get_host() -======================================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_command_succeeded_get_host ( - const mongoc_apm_command_succeeded_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_succeeded_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_operation_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_operation_id.rst deleted file mode 100644 index 8002a65b77d5ee6a808b8a232b37988dbc8437b8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_operation_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_get_operation_id - -mongoc_apm_command_succeeded_get_operation_id() -=============================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_command_succeeded_get_operation_id ( - const mongoc_apm_command_succeeded_t *event); - -Returns this event's operation id. This number correlates all the commands in a bulk operation, or all the "find" and "getMore" commands required to stream a large query result. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_succeeded_t`. - -Returns -------- - -The event's operation id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_reply.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_reply.rst deleted file mode 100644 index 965299a18794093b0ec0084f31e725609a2caeae..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_reply.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_get_reply - -mongoc_apm_command_succeeded_get_reply() -======================================== - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_apm_command_succeeded_get_reply ( - const mongoc_apm_command_succeeded_t *event); - -Returns this event's reply. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_succeeded_t`. - -Returns -------- - -A :symbol:`bson:bson_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_request_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_request_id.rst deleted file mode 100644 index 08e9c13a39f517fb12fbc4cbd11b6d25932444f5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_request_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_get_request_id - -mongoc_apm_command_succeeded_get_request_id() -============================================= - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_command_succeeded_get_request_id ( - const mongoc_apm_command_succeeded_t *event); - -Returns this event's wire-protocol request id. Use this number to correlate client-side events with server log messages. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_succeeded_t`. - -Returns -------- - -The event's request id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_server_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_server_id.rst deleted file mode 100644 index b8bd0c8877b67469b0cf0d75d5df88bb44aa1922..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_get_server_id.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_get_server_id - -mongoc_apm_command_succeeded_get_server_id() -============================================ - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_apm_command_succeeded_get_server_id ( - const mongoc_apm_command_succeeded_t *event); - -Returns this event's server id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_command_succeeded_t`. - -Returns -------- - -The event's server id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_t.rst deleted file mode 100644 index 8e402410e103caabbe1798932790d6c733c4d0f0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_command_succeeded_t.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_apm_command_succeeded_t - -mongoc_apm_command_succeeded_t -============================== - -Command-succeeded event - -Synopsis --------- - -An event notification sent when the driver successfully executes a MongoDB command. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_command_succeeded_get_command_name - mongoc_apm_command_succeeded_get_context - mongoc_apm_command_succeeded_get_duration - mongoc_apm_command_succeeded_get_host - mongoc_apm_command_succeeded_get_operation_id - mongoc_apm_command_succeeded_get_reply - mongoc_apm_command_succeeded_get_request_id - mongoc_apm_command_succeeded_get_server_id - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_context.rst deleted file mode 100644 index 1d8891bad6817f329d6c7b1ac6ba77945460dcdc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_changed_get_context - -mongoc_apm_server_changed_get_context() -======================================= - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_server_changed_get_context ( - const mongoc_apm_server_changed_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_changed_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_host.rst deleted file mode 100644 index bc1469844bfd73a0eede7fcbb30332985c214a7d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_host.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_server_changed_get_host - -mongoc_apm_server_changed_get_host() -==================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_changed_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_new_description.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_new_description.rst deleted file mode 100644 index ef675b29ee806f7596d26e0014687bfa469219ff..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_new_description.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_changed_get_new_description - -mongoc_apm_server_changed_get_new_description() -=============================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_server_description_t * - mongoc_apm_server_changed_get_new_description ( - const mongoc_apm_server_changed_t *event); - -Returns this event's new description. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_changed_t`. - -Returns -------- - -A :symbol:`mongoc_server_description_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_previous_description.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_previous_description.rst deleted file mode 100644 index 4a55371eaae7e968ad7ae8c8395353d7d3c69198..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_previous_description.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_changed_get_previous_description - -mongoc_apm_server_changed_get_previous_description() -==================================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_server_description_t * - mongoc_apm_server_changed_get_previous_description ( - const mongoc_apm_server_changed_t *event); - -Returns this event's previous description. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_changed_t`. - -Returns -------- - -A :symbol:`mongoc_server_description_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_topology_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_topology_id.rst deleted file mode 100644 index 68461c399c22207983db1c99067852455c789af4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_get_topology_id.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_apm_server_changed_get_topology_id - -mongoc_apm_server_changed_get_topology_id() -=========================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_server_changed_get_topology_id ( - const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id); - -Returns this event's topology id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_changed_t`. -* ``topology_id``: A :symbol:`bson:bson_oid_t` to receive the event's topology_id. - -Returns -------- - -The event's topology id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_t.rst deleted file mode 100644 index 519725b2e73ce2dbbc81c5e427b0299a6849f742..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_changed_t.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_apm_server_changed_t - -mongoc_apm_server_changed_t -=========================== - -Server-changed event - -Synopsis --------- - -An event notification sent when the driver observes a change in status of a server it is connected to. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_server_changed_get_context - mongoc_apm_server_changed_get_host - mongoc_apm_server_changed_get_new_description - mongoc_apm_server_changed_get_previous_description - mongoc_apm_server_changed_get_topology_id - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_context.rst deleted file mode 100644 index 8fe4cc401e2e969bd605c18373028e5bb7c4b9e3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_context.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_server_closed_get_context - -mongoc_apm_server_closed_get_context() -====================================== - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_closed_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_host.rst deleted file mode 100644 index e08ce81df7b4fd2f4831df41d19b493012125f65..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_host.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_server_closed_get_host - -mongoc_apm_server_closed_get_host() -=================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_closed_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_topology_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_topology_id.rst deleted file mode 100644 index d297d8d8e076855bb1d14d3f925a659fef1fc166..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_get_topology_id.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_apm_server_closed_get_topology_id - -mongoc_apm_server_closed_get_topology_id() -========================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_server_closed_get_topology_id ( - const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id); - -Returns this event's topology id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_closed_t`. -* ``topology_id``: A :symbol:`bson:bson_oid_t` to receive the event's topology_id. - -Returns -------- - -The event's topology id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_t.rst deleted file mode 100644 index ae6271fd1611e56818dd49e37e35998bacb5cd20..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_closed_t.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_server_closed_t - -mongoc_apm_server_closed_t -========================== - -Server-closed event - -Synopsis --------- - -An event notification sent when the driver stops monitoring a server and removes its :symbol:`mongoc_server_description_t`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_server_closed_get_context - mongoc_apm_server_closed_get_host - mongoc_apm_server_closed_get_topology_id - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_context.rst deleted file mode 100644 index 66065608ddf459e4b3015ac7c8ad3903c3b39147..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_failed_get_context - -mongoc_apm_server_heartbeat_failed_get_context() -================================================ - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_server_heartbeat_failed_get_context ( - const mongoc_apm_server_heartbeat_failed_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_failed_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_duration.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_duration.rst deleted file mode 100644 index d723e7a239f7144b5edff2453370b21391388ad0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_duration.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_failed_get_duration - -mongoc_apm_server_heartbeat_failed_get_duration() -================================================= - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_server_heartbeat_failed_get_duration ( - const mongoc_apm_server_heartbeat_failed_t *event); - -Returns this event's duration in microseconds. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_failed_t`. - -Returns -------- - -The event's duration. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_error.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_error.rst deleted file mode 100644 index 3da71eee8dbd89ae558e7305a855af0c950a047d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_error.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_failed_get_error - -mongoc_apm_server_heartbeat_failed_get_error() -============================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_server_heartbeat_failed_get_error ( - const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error); - -Copies this event's error info. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_failed_t`. -* ``error``: A :symbol:`bson:bson_error_t` to receive the event's error info. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_host.rst deleted file mode 100644 index e8156aba6895253b46ca56ecc287be8247a8cfbf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_get_host.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_failed_get_host - -mongoc_apm_server_heartbeat_failed_get_host() -============================================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_server_heartbeat_failed_get_host ( - const mongoc_apm_server_heartbeat_failed_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_failed_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_t.rst deleted file mode 100644 index 7fbbe84fe9a357d71508c34d7b7358866913f49c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_failed_t.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_failed_t - -mongoc_apm_server_heartbeat_failed_t -==================================== - -Heartbeat-failed event - -Synopsis --------- - -An event notification sent when the driver failed to send an "isMaster" command to check the status of a server. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_server_heartbeat_failed_get_context - mongoc_apm_server_heartbeat_failed_get_duration - mongoc_apm_server_heartbeat_failed_get_error - mongoc_apm_server_heartbeat_failed_get_host - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_get_context.rst deleted file mode 100644 index 5a60718d4ae2225d7eb3bdd3c40f05b7439d4a97..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_started_get_context - -mongoc_apm_server_heartbeat_started_get_context() -================================================= - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_server_heartbeat_started_get_context ( - const mongoc_apm_server_heartbeat_started_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_started_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_get_host.rst deleted file mode 100644 index 86eba1727be9939166f3a3f4bf5400cfdb2e6acf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_get_host.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_started_get_host - -mongoc_apm_server_heartbeat_started_get_host() -============================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_server_heartbeat_started_get_host ( - const mongoc_apm_server_heartbeat_started_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_started_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_t.rst deleted file mode 100644 index 5fb2bfa593a003d58b1acb08de0e50af534d9e2d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_started_t.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_started_t - -mongoc_apm_server_heartbeat_started_t -===================================== - -Heartbeat-started event - -Synopsis --------- - -An event notification sent when the driver begins executing an "isMaster" command to check the status of a server. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_server_heartbeat_started_get_context - mongoc_apm_server_heartbeat_started_get_host - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_context.rst deleted file mode 100644 index f5e7ee81968eecd5394fb829b881f82f39ad3b1b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_succeeded_get_context - -mongoc_apm_server_heartbeat_succeeded_get_context() -=================================================== - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_server_heartbeat_succeeded_get_context ( - const mongoc_apm_server_heartbeat_succeeded_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_succeeded_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_duration.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_duration.rst deleted file mode 100644 index 4d69374d0b1a00f29f3862cea09262e92d62be15..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_duration.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_succeeded_get_duration - -mongoc_apm_server_heartbeat_succeeded_get_duration() -==================================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_apm_server_heartbeat_succeeded_get_duration ( - const mongoc_apm_server_heartbeat_succeeded_t *event); - -Returns this event's duration in microseconds. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_succeeded_t`. - -Returns -------- - -The event's duration. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_host.rst deleted file mode 100644 index f098a071e8c6b4d0b3ada7f04cb702de9c83f34f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_host.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_succeeded_get_host - -mongoc_apm_server_heartbeat_succeeded_get_host() -================================================ - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_server_heartbeat_succeeded_get_host ( - const mongoc_apm_server_heartbeat_succeeded_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_succeeded_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_reply.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_reply.rst deleted file mode 100644 index 4cdc28c05fda040c0f9c3a35c07c5e62fbffe9c8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_get_reply.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_succeeded_get_reply - -mongoc_apm_server_heartbeat_succeeded_get_reply() -================================================= - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_apm_server_heartbeat_succeeded_get_reply ( - const mongoc_apm_server_heartbeat_succeeded_t *event); - -Returns this event's reply. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_heartbeat_succeeded_t`. - -Returns -------- - -A :symbol:`bson:bson_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_t.rst deleted file mode 100644 index 5f7a2cfb9677a552c25b6bca6ffda8c7dc3d5813..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_heartbeat_succeeded_t.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_heartbeat_succeeded_t - -mongoc_apm_server_heartbeat_succeeded_t -======================================= - -Heartbeat-succeeded event - -Synopsis --------- - -An event notification sent when the driver completes an "isMaster" command to check the status of a server. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_server_heartbeat_succeeded_get_context - mongoc_apm_server_heartbeat_succeeded_get_duration - mongoc_apm_server_heartbeat_succeeded_get_host - mongoc_apm_server_heartbeat_succeeded_get_reply - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_context.rst deleted file mode 100644 index 5ae499661642c871449d65ac95f8e9c213970b44..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_server_opening_get_context - -mongoc_apm_server_opening_get_context() -======================================= - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_server_opening_get_context ( - const mongoc_apm_server_opening_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_opening_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_host.rst deleted file mode 100644 index d8ba5141447f98c2cd4328518254097f77e36b63..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_host.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_server_opening_get_host - -mongoc_apm_server_opening_get_host() -==================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event); - -Returns this event's host. This :symbol:`mongoc_host_list_t` is *not* part of a linked list, it is solely the server for this event. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_opening_t`. - -Returns -------- - -A :symbol:`mongoc_host_list_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_topology_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_topology_id.rst deleted file mode 100644 index e541d1457f89e479eef55edd4d8f762b36995843..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_get_topology_id.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_apm_server_opening_get_topology_id - -mongoc_apm_server_opening_get_topology_id() -=========================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_server_opening_get_topology_id ( - const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id); - -Returns this event's topology id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_server_opening_t`. -* ``topology_id``: A :symbol:`bson:bson_oid_t` to receive the event's topology_id. - -Returns -------- - -The event's topology id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_t.rst deleted file mode 100644 index 8113010323636a6ffc29c7acdba1cd0596284a40..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_server_opening_t.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_server_opening_t - -mongoc_apm_server_opening_t -=========================== - -Server-opening event - -Synopsis --------- - -An event notification sent when the driver adds a :symbol:`mongoc_server_description_t` for a new server it was not monitoring before. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_server_opening_get_context - mongoc_apm_server_opening_get_host - mongoc_apm_server_opening_get_topology_id - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_failed_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_failed_cb.rst deleted file mode 100644 index 5f9d075983b836d38da0816ca98b1b115225be20..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_failed_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_command_failed_cb - -mongoc_apm_set_command_failed_cb() -================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_command_failed_cb_t) ( - const mongoc_apm_command_failed_t *event); - - void - mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_failed_cb_t cb); - -Receive an event notification whenever the driver fails to execute a MongoDB operation. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_command_failed_t` whenever a MongoDB operation fails. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_started_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_started_cb.rst deleted file mode 100644 index a64b2b2f10e19b66897b9b71bcf0acdf20ab387f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_started_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_command_started_cb - -mongoc_apm_set_command_started_cb() -=================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_command_started_cb_t) ( - const mongoc_apm_command_started_t *event); - - void - mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_started_cb_t cb); - -Receive an event notification whenever the driver starts a MongoDB operation. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_command_started_t` whenever the driver begins a MongoDB operation. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_succeeded_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_succeeded_cb.rst deleted file mode 100644 index 2d2e9fefedd1438c9d575d69b8a4c50116be8c16..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_command_succeeded_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_command_succeeded_cb - -mongoc_apm_set_command_succeeded_cb() -===================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_command_succeeded_cb_t) ( - const mongoc_apm_command_succeeded_t *event); - - void - mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_succeeded_cb_t cb); - -Receive an event notification whenever the driver completes a MongoDB operation. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_command_succeeded_t` whenever the driver completes a MongoDB operation. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_changed_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_changed_cb.rst deleted file mode 100644 index 1aa742566738704b67efce6c1679913e566a4f9d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_changed_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_server_changed_cb - -mongoc_apm_set_server_changed_cb() -================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_server_changed_cb_t) ( - const mongoc_apm_server_changed_t *event); - - void - mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_changed_cb_t cb); - -Receive an event notification whenever the driver observes a change in status of a server it is connected to. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_server_changed_t` whenever the driver observes a change in status of a server it is connected to. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_closed_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_closed_cb.rst deleted file mode 100644 index 738968f3eeb523b50ab885a64730934ec6b28e85..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_closed_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_server_closed_cb - -mongoc_apm_set_server_closed_cb() -================================= - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_server_closed_cb_t) ( - const mongoc_apm_server_closed_t *event); - - void - mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_closed_cb_t cb); - -Receive an event notification whenever the driver stops monitoring a server and removes its :symbol:`mongoc_server_description_t`. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_server_closed_t` whenever the driver stops monitoring a server and removes its :symbol:`mongoc_server_description_t`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_failed_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_failed_cb.rst deleted file mode 100644 index 44ea1b0548d8fb84d27b73206375f92a75ec7dcc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_failed_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_server_heartbeat_failed_cb - -mongoc_apm_set_server_heartbeat_failed_cb() -=========================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_server_heartbeat_failed_cb_t) ( - const mongoc_apm_server_heartbeat_failed_t *event); - - void - mongoc_apm_set_server_heartbeat_failed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_failed_cb_t cb); - -Receive an event notification whenever the driver fails to send an "isMaster" command to check the status of a server. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_server_heartbeat_failed_t` whenever the driver fails to send an "isMaster" command to check the status of a server. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_started_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_started_cb.rst deleted file mode 100644 index 682236655e5001fc01854ff8a21f82881c7c68f7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_started_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_server_heartbeat_started_cb - -mongoc_apm_set_server_heartbeat_started_cb() -============================================ - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_server_heartbeat_started_cb_t) ( - const mongoc_apm_server_heartbeat_started_t *event); - - void - mongoc_apm_set_server_heartbeat_started_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_started_cb_t cb); - -Receive an event notification whenever the driver begins executing an "isMaster" command to check the status of a server. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_server_heartbeat_started_t` whenever the driver begins executing an "isMaster" command to check the status of a server. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_succeeded_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_succeeded_cb.rst deleted file mode 100644 index 31d0739dad42371e24872e864244ba8f4d1495b8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_heartbeat_succeeded_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_server_heartbeat_succeeded_cb - -mongoc_apm_set_server_heartbeat_succeeded_cb() -============================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_server_heartbeat_succeeded_cb_t) ( - const mongoc_apm_server_heartbeat_succeeded_t *event); - - void - mongoc_apm_set_server_heartbeat_succeeded_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_succeeded_cb_t cb); - -Receive an event notification whenever the driver completes an "isMaster" command to check the status of a server. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_server_heartbeat_succeeded_t` whenever the driver completes an "isMaster" command to check the status of a server. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_opening_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_opening_cb.rst deleted file mode 100644 index d51b6418fabe8c79fb77d2b63aca5f380ae6297d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_server_opening_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_server_opening_cb - -mongoc_apm_set_server_opening_cb() -================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_server_opening_cb_t) ( - const mongoc_apm_server_opening_t *event); - - void - mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_opening_cb_t cb); - -Receive an event notification whenever the driver adds a :symbol:`mongoc_server_description_t` for a new server it was not monitoring before. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_server_opening_t` whenever the driver adds a :symbol:`mongoc_server_description_t` for a new server it was not monitoring before. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_changed_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_changed_cb.rst deleted file mode 100644 index e5dab6fb2bfb9cd9b88c84148d9e8ed610e78734..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_changed_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_topology_changed_cb - -mongoc_apm_set_topology_changed_cb() -==================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_topology_changed_cb_t) ( - const mongoc_apm_topology_changed_t *event); - - void - mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_changed_cb_t cb); - -Receive an event notification whenever the driver observes a change in any of the servers it is connected to or a change in the overall server topology. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_topology_changed_t` whenever the driver observes a change in any of the servers it is connected to or a change in the overall server topology. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_closed_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_closed_cb.rst deleted file mode 100644 index 2f3d6dec2475d51c44026c963c000235cedac2b3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_closed_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_topology_closed_cb - -mongoc_apm_set_topology_closed_cb() -=================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_topology_closed_cb_t) ( - const mongoc_apm_topology_closed_t *event); - - void - mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_closed_cb_t cb); - -Receive an event notification whenever the driver stops monitoring a server topology and destroys its :symbol:`mongoc_topology_description_t`. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_topology_closed_t` whenever the driver stops monitoring a server topology and destroys its :symbol:`mongoc_topology_description_t`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_opening_cb.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_opening_cb.rst deleted file mode 100644 index b20f4114f949e7b8d6071db463ac9bf25c085335..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_set_topology_opening_cb.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_apm_set_topology_opening_cb - -mongoc_apm_set_topology_opening_cb() -==================================== - -Synopsis --------- - -.. code-block:: c - - typedef void (*mongoc_apm_topology_opening_cb_t) ( - const mongoc_apm_topology_opening_t *event); - - void - mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_opening_cb_t cb); - -Receive an event notification whenever the driver initializes a :symbol:`mongoc_topology_description_t`. - -Parameters ----------- - -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``cb``: A function to call with a :symbol:`mongoc_apm_topology_opening_t` whenever the driver initializes a :symbol:`mongoc_topology_description_t`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_context.rst deleted file mode 100644 index 1db2259495615a26f93e9e7cd0fc64428292a74f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_topology_changed_get_context - -mongoc_apm_topology_changed_get_context() -========================================= - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_topology_changed_get_context ( - const mongoc_apm_topology_changed_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_topology_changed_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_new_description.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_new_description.rst deleted file mode 100644 index a30e80a2b0f2a91a39f92672542195a412722455..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_new_description.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_topology_changed_get_new_description - -mongoc_apm_topology_changed_get_new_description() -================================================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_topology_description_t * - mongoc_apm_topology_changed_get_new_description ( - const mongoc_apm_topology_changed_t *event); - -Returns this event's new description. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_topology_changed_t`. - -Returns -------- - -A :symbol:`mongoc_topology_description_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_previous_description.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_previous_description.rst deleted file mode 100644 index 82accced9103a1cc2848009619d53ce9569f4c3c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_previous_description.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_topology_changed_get_previous_description - -mongoc_apm_topology_changed_get_previous_description() -====================================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_topology_description_t * - mongoc_apm_topology_changed_get_previous_description ( - const mongoc_apm_topology_changed_t *event); - -Returns this event's previous description. The data is only valid in the scope of the callback that receives this event; copy it if it will be accessed after the callback returns. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_topology_changed_t`. - -Returns -------- - -A :symbol:`mongoc_topology_description_t` that should not be modified or freed. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_topology_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_topology_id.rst deleted file mode 100644 index 47e19961d3829318d636a700b3c4634026413ac7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_get_topology_id.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_apm_topology_changed_get_topology_id - -mongoc_apm_topology_changed_get_topology_id() -============================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_topology_changed_get_topology_id ( - const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id); - -Returns this event's topology id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_topology_changed_t`. -* ``topology_id``: A :symbol:`bson:bson_oid_t` to receive the event's topology_id. - -Returns -------- - -The event's topology id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_t.rst deleted file mode 100644 index d3d4141aaa4d42450ea7880b1c49557514c63fd1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_changed_t.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_topology_changed_t - -mongoc_apm_topology_changed_t -============================= - -Topology-changed event - -Synopsis --------- - -An event notification sent when the driver observes a change in any of the servers it is connected to or a change in the overall server topology. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_topology_changed_get_context - mongoc_apm_topology_changed_get_new_description - mongoc_apm_topology_changed_get_previous_description - mongoc_apm_topology_changed_get_topology_id - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_get_context.rst deleted file mode 100644 index 8b4dbf5586272b33c34a7cbae3e11893ff652a54..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_topology_closed_get_context - -mongoc_apm_topology_closed_get_context() -======================================== - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_topology_closed_get_context ( - const mongoc_apm_topology_closed_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_topology_closed_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_get_topology_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_get_topology_id.rst deleted file mode 100644 index 20254e5ae79eed7a9ec09045cf7ff6f682728a3b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_get_topology_id.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_apm_topology_closed_get_topology_id - -mongoc_apm_topology_closed_get_topology_id() -============================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_topology_closed_get_topology_id ( - const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id); - -Returns this event's topology id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_topology_closed_t`. -* ``topology_id``: A :symbol:`bson:bson_oid_t` to receive the event's topology_id. - -Returns -------- - -The event's topology id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_t.rst deleted file mode 100644 index 534e3aa7a85eb580f8e4c8be34861aed91ba14ba..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_closed_t.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_apm_topology_closed_t - -mongoc_apm_topology_closed_t -============================ - -Topology-closed event - -Synopsis --------- - -An event notification sent when the driver stops monitoring a server topology and destroys its :symbol:`mongoc_topology_description_t`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_topology_closed_get_context - mongoc_apm_topology_closed_get_topology_id - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_get_context.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_get_context.rst deleted file mode 100644 index b0a8d9fad99242535f040ad9647e232fa5eba8e9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_get_context.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_apm_topology_opening_get_context - -mongoc_apm_topology_opening_get_context() -========================================= - -Synopsis --------- - -.. code-block:: c - - void * - mongoc_apm_topology_opening_get_context ( - const mongoc_apm_topology_opening_t *event); - -Returns this event's context. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_topology_opening_t`. - -Returns -------- - -The pointer passed with :symbol:`mongoc_client_set_apm_callbacks` or :symbol:`mongoc_client_pool_set_apm_callbacks`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_get_topology_id.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_get_topology_id.rst deleted file mode 100644 index c29ee286b06f3fef9ff13ed9bcee45db1db15d50..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_get_topology_id.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_apm_topology_opening_get_topology_id - -mongoc_apm_topology_opening_get_topology_id() -============================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_apm_topology_opening_get_topology_id ( - const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id); - -Returns this event's topology id. - -Parameters ----------- - -* ``event``: A :symbol:`mongoc_apm_topology_opening_t`. -* ``topology_id``: A :symbol:`bson:bson_oid_t` to receive the event's topology_id. - -Returns -------- - -The event's topology id. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_t.rst b/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_t.rst deleted file mode 100644 index 8d643a5f1b7a405f014f9d5293bb3eec78483bdb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_apm_topology_opening_t.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_apm_topology_opening_t - -mongoc_apm_topology_opening_t -============================= - -Topology-opening event - -Synopsis --------- - -An event notification sent when the driver initializes a :symbol:`mongoc_topology_description_t`. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_apm_topology_opening_get_context - mongoc_apm_topology_opening_get_topology_id - diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_destroy.rst deleted file mode 100644 index 5f5c018a26788ac7ecab780af76b5ee9ac648cd3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_destroy.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_destroy - -mongoc_auto_encryption_opts_destroy() -===================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_auto_encryption_opts_destroy (mongoc_auto_encryption_opts_t *opts); - -Destroy a :symbol:`mongoc_auto_encryption_opts_t`. - -Parameters ----------- - -* ``opts`` The :symbol:`mongoc_auto_encryption_opts_t` to destroy. - -See also --------- - -* :symbol:`mongoc_auto_encryption_opts_new()` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_new.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_new.rst deleted file mode 100644 index 8d091f84cd9325420650762e81dc4be3b3655a11..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_new.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_new - -mongoc_auto_encryption_opts_new() -================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_auto_encryption_opts_t * - mongoc_auto_encryption_opts_new (void); - - -Create a new :symbol:`mongoc_auto_encryption_opts_t`. - -Caller must set the required options: - -* :symbol:`mongoc_auto_encryption_opts_set_key_vault_namespace()` -* :symbol:`mongoc_auto_encryption_opts_set_kms_providers()` - -Caller may set optionally set the following: - -* :symbol:`mongoc_auto_encryption_opts_set_key_vault_client()` -* :symbol:`mongoc_auto_encryption_opts_set_schema_map()` -* :symbol:`mongoc_auto_encryption_opts_set_bypass_auto_encryption()` -* :symbol:`mongoc_auto_encryption_opts_set_extra()` - -This options struct is used to enable auto encryption with :symbol:`mongoc_client_enable_auto_encryption()`. - -Returns -------- - -A new :symbol:`mongoc_auto_encryption_opts_t`, which must be destroyed with :symbol:`mongoc_auto_encryption_opts_destroy()`. - -See also --------- - -* :symbol:`mongoc_auto_encryption_opts_destroy()` -* :symbol:`mongoc_client_enable_auto_encryption()` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_bypass_auto_encryption.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_bypass_auto_encryption.rst deleted file mode 100644 index ec85040db1e5468ed707aa876957ff87e9907806..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_bypass_auto_encryption.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_set_bypass_auto_encryption - -mongoc_auto_encryption_opts_set_bypass_auto_encryption() -======================================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_auto_encryption_opts_set_bypass_auto_encryption ( - mongoc_auto_encryption_opts_t *opts, bool bypass_auto_encryption); - - -Parameters ----------- - -* ``opts``: The :symbol:`mongoc_auto_encryption_opts_t` -* ``bypass_auto_encryption``: A boolean. If true, a :symbol:`mongoc_client_t` configured with :symbol:`mongoc_client_enable_auto_encryption()` will only perform automatic decryption (not encryption). - -See also --------- - -* :symbol:`mongoc_client_enable_auto_encryption()` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_extra.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_extra.rst deleted file mode 100644 index 81b6147f399cb34886fe597162572beb71e02742..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_extra.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_set_extra - -mongoc_auto_encryption_opts_set_extra() -======================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_auto_encryption_opts_set_extra (mongoc_auto_encryption_opts_t *opts, - const bson_t *extra); - - -Parameters ----------- - -* ``opts``: The :symbol:`mongoc_auto_encryption_opts_t` -* ``extra``: A :symbol:`bson_t` of additional options. - -``extra`` is a :symbol:`bson_t` containing any of the following optional fields: - -* ``mongocryptdURI`` set to a URI to connect to the mongocryptd process (default is "mongodb://localhost:27027"). -* ``mongocryptdBypassSpawn`` set to true to prevent the driver from spawning the mongocryptd process (default behavior is to spawn). -* ``mongocryptdSpawnPath`` set to a path (with trailing slash) to search for mongocryptd (defaults to empty string and uses default system paths). -* ``mongocryptdSpawnArgs`` set to an array of string arguments to pass to ``mongocryptd`` when spawning (defaults to ``[ "--idleShutdownTimeoutSecs=60" ]``). - -For more information, see the `Client-Side Encryption specification <https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#extraoptions>`_. - -See also --------- - -* :symbol:`mongoc_client_enable_auto_encryption()` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_key_vault_client.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_key_vault_client.rst deleted file mode 100644 index d9b7a7a26e51aa96ea8574d84cec24c345e3c9c1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_key_vault_client.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_set_key_vault_client - -mongoc_auto_encryption_opts_set_key_vault_client() -================================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_auto_encryption_opts_set_key_vault_client ( - mongoc_auto_encryption_opts_t *opts, struct _mongoc_client_t *client); - -Set an optional separate :symbol:`mongoc_client_t` to use during key lookup for automatic encryption and decryption. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_auto_encryption_opts_t`. -* ``client``: A :symbol:`mongoc_client_t` to use for key queries. This client should *not* have automatic encryption enabled, as it will only execute ``find`` commands against the key vault collection to retrieve keys for automatic encryption and decryption. This ``client`` MUST outlive any :symbol:`mongoc_client_t` which has been enabled to use it through :symbol:`mongoc_client_enable_auto_encryption()`. - -See also --------- - -* :symbol:`mongoc_client_enable_auto_encryption()` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_key_vault_namespace.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_key_vault_namespace.rst deleted file mode 100644 index dc63dd9bb96e283cc739a155a1886250ddcfd3fa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_key_vault_namespace.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_set_key_vault_namespace - -mongoc_auto_encryption_opts_set_key_vault_namespace() -===================================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_auto_encryption_opts_set_key_vault_namespace ( - mongoc_auto_encryption_opts_t *opts, const char *db, const char *coll); - -Set the database and collection name of the key vault. The key vault is the specially designated collection containing encrypted data keys for `Client-Side Field Level Encryption <https://docs.mongodb.com/manual/core/security-client-side-encryption/>`_. - -Parameters ----------- - -* ``opts``: The :symbol:`mongoc_auto_encryption_opts_t` -* ``db``: A ``const char *`` representing the database name of the key vault collection. -* ``coll``: A ``const char *`` representing the collection name of the key vault collection. - -See also --------- - -* :symbol:`mongoc_client_enable_auto_encryption()` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_kms_providers.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_kms_providers.rst deleted file mode 100644 index d1e4dc5e845c0f0b08c8032aed71baf4f2a77d4c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_kms_providers.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_set_kms_providers - -mongoc_auto_encryption_opts_set_kms_providers() -=============================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_auto_encryption_opts_set_kms_providers ( - mongoc_auto_encryption_opts_t *opts, const bson_t *kms_providers); - - -Parameters ----------- - -* ``opts``: The :symbol:`mongoc_auto_encryption_opts_t` -* ``kms_providers``: A :symbol:`bson_t` containing configuration for an external Key Management Service (KMS). - -``kms_providers`` is a BSON document containing configuration for each KMS provider. Currently ``aws`` or ``local`` are supported. At least one must be specified. The format is as follows: - -.. code-block:: js - - { - aws: { - accessKeyId: string, - secretAccessKey: string - } - - local: { - key: byte[96] // The master key used to encrypt/decrypt data keys. - } - } - - -See also --------- - -* :symbol:`mongoc_client_enable_auto_encryption()` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_schema_map.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_schema_map.rst deleted file mode 100644 index 039bd3a17831495843e58a849e60b39c2f132664..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_set_schema_map.rst +++ /dev/null @@ -1,57 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_set_schema_map - -mongoc_auto_encryption_opts_set_schema_map() -============================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_auto_encryption_opts_set_schema_map (mongoc_auto_encryption_opts_t *opts, - const bson_t *schema_map); - - -Parameters ----------- - -* ``opts``: The :symbol:`mongoc_auto_encryption_opts_t` -* ``schema_map``: A :symbol:`bson_t` where keys are collection namespaces and values are JSON schemas. - -Supplying a schema map provides more security than relying on JSON Schemas obtained from the server. It protects against a malicious server advertising a false JSON Schema, which could trick the client into sending unencrypted data that should be encrypted. - -Schemas supplied in the schema map only apply to configuring automatic encryption for client side encryption. Other validation rules in the JSON schema will not be enforced by the driver and will result in an error. - -The following is an example of a schema map which configures automatic encryption for the collection ``db.coll``: - -.. code-block:: js - - { - "db.coll": { - "properties": { - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - } - - -See also --------- - -* :symbol:`mongoc_client_enable_auto_encryption()` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` diff --git a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_t.rst b/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_t.rst deleted file mode 100644 index bbcfaec0954a23bbcdc41d8e1d5a5e63190a8a31..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_auto_encryption_opts_t.rst +++ /dev/null @@ -1,37 +0,0 @@ -:man_page: mongoc_auto_encryption_opts_t - -mongoc_auto_encryption_opts_t -============================= - -Options for enabling automatic encryption and decryption for `Client-Side Field Level Encryption <https://docs.mongodb.com/manual/core/security-client-side-encryption/>`_. - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_auto_encryption_opts_t mongoc_auto_encryption_opts_t; - -See Also --------- - -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_auto_encryption_opts_new - mongoc_auto_encryption_opts_destroy - mongoc_auto_encryption_opts_set_key_vault_client - mongoc_auto_encryption_opts_set_key_vault_namespace - mongoc_auto_encryption_opts_set_kms_providers - mongoc_auto_encryption_opts_set_schema_map - mongoc_auto_encryption_opts_set_bypass_auto_encryption - mongoc_auto_encryption_opts_set_extra - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_delete.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_delete.rst deleted file mode 100644 index 2a0068ba6698e4686c66c416e14d0c7c3dc0362d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_delete.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_bulk_operation_delete - -mongoc_bulk_operation_delete() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk, - const bson_t *selector); - -Deletes documents as part of a bulk operation. This only queues the operation. To execute it, call :symbol:`mongoc_bulk_operation_execute()`. - -Deprecated ----------- - -.. warning:: - - This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_bulk_operation_remove()` instead. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t`. - -See Also --------- - -:symbol:`mongoc_bulk_operation_remove_many_with_opts()` - -:symbol:`mongoc_bulk_operation_remove_one_with_opts()` - -Errors ------- - -Errors are propagated via :symbol:`mongoc_bulk_operation_execute()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_delete_one.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_delete_one.rst deleted file mode 100644 index cfce488f5d728522ca89ec5b6f20bfe6df71b543..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_delete_one.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_bulk_operation_delete_one - -mongoc_bulk_operation_delete_one() -================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector); - -Delete a single document as part of a bulk operation. This only queues the operation. To execute it, call :symbol:`mongoc_bulk_operation_execute()`. - -Deprecated ----------- - -.. warning:: - - This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_bulk_operation_remove_one()` instead. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t`. - -See Also --------- - -:symbol:`mongoc_bulk_operation_remove_one_with_opts()` - -:symbol:`mongoc_bulk_operation_remove_many_with_opts()` - -Errors ------- - -Errors are propagated via :symbol:`mongoc_bulk_operation_execute()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_destroy.rst deleted file mode 100644 index 73c44184dc48c805d79e0e811b5bd69e41c043d7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_destroy.rst +++ /dev/null @@ -1,20 +0,0 @@ -:man_page: mongoc_bulk_operation_destroy - -mongoc_bulk_operation_destroy() -=============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk); - -Destroys a :symbol:`mongoc_bulk_operation_t` and frees the structure. Does nothing if ``bulk`` is NULL. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_execute.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_execute.rst deleted file mode 100644 index 68b27d81a34bbee4fe9311611bc73b1fa0a7e4b3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_execute.rst +++ /dev/null @@ -1,51 +0,0 @@ -:man_page: mongoc_bulk_operation_execute - -mongoc_bulk_operation_execute() -=============================== - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, - bson_t *reply, - bson_error_t *error); - -This function executes all operations queued into the bulk operation. Unless ``ordered: false`` was specified in the ``opts`` passed to :symbol:`mongoc_collection_create_bulk_operation_with_opts()`, then forward progress will be stopped upon the first error. - -It is only valid to call :symbol:`mongoc_bulk_operation_execute()` once. The ``mongoc_bulk_operation_t`` must be destroyed afterwards. - -.. warning:: - - ``reply`` is always initialized, even upon failure. Callers *must* call :symbol:`bson:bson_destroy()` to release this potential allocation. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``reply``: An uninitialized :symbol:`bson:bson_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -See Also --------- - -:symbol:`Bulk Write Operations <bulk>` - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -On success, returns the server id used. On failure, returns 0 and sets ``error``. - -A write concern timeout or write concern error is considered a failure. - -The ``reply`` document counts operations and collects error information. See :doc:`Bulk Write Operations <bulk>` for examples. - -See also :symbol:`mongoc_bulk_operation_get_hint`, which gets the id of the server used even if the operation failed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_get_hint.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_get_hint.rst deleted file mode 100644 index 8c5e51b2d6e04474ff67f48654d7f09a1acb2709..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_get_hint.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_bulk_operation_get_hint - -mongoc_bulk_operation_get_hint() -================================ - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_bulk_operation_get_hint (const mongoc_bulk_operation_t *bulk); - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. - -Description ------------ - -Retrieves the opaque id of the server used for the operation. - -(The function name includes the old term "hint" for the sake of backward compatibility, but we now call this number a "server id".) - -This number is zero until the driver actually uses a server in :symbol:`mongoc_bulk_operation_execute`. The server id is the same number as the return value of a successful :symbol:`mongoc_bulk_operation_execute`, so ``mongoc_bulk_operation_get_hint`` is useful mainly in case :symbol:`mongoc_bulk_operation_execute` fails and returns zero. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_get_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_get_write_concern.rst deleted file mode 100644 index 172a005e6e0c223874498cb34851fe46128c6e53..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_get_write_concern.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_bulk_operation_get_write_concern - -mongoc_bulk_operation_get_write_concern() -========================================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_write_concern_t * - mongoc_bulk_operation_get_write_concern (const mongoc_bulk_operation_t *bulk); - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. - -Description ------------ - -Fetches the write concern to be used for ``bulk``. - -Returns -------- - -A :symbol:`mongoc_write_concern_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_insert.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_insert.rst deleted file mode 100644 index ce3f4d74aee05823d76c07beaad42177c2500ae0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_insert.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_bulk_operation_insert - -mongoc_bulk_operation_insert() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk, - const bson_t *document); - -Queue an insert of a single document into a bulk operation. The insert is not performed until :symbol:`mongoc_bulk_operation_execute()` is called. - -This function is superseded by :symbol:`mongoc_bulk_operation_insert_with_opts()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``document``: A :symbol:`bson:bson_t`. - -See Also --------- - -:doc:`bulk` - -Errors ------- - -Errors are propagated via :symbol:`mongoc_bulk_operation_execute()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_insert_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_insert_with_opts.rst deleted file mode 100644 index 0a67c23d3e50b01aa9fac68a1acfbfe13e8aac23..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_insert_with_opts.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_bulk_operation_insert_with_opts - -mongoc_bulk_operation_insert_with_opts() -======================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_bulk_operation_insert_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); /* OUT */ - -Queue an insert of a single document into a bulk operation. The insert is not performed until :symbol:`mongoc_bulk_operation_execute()` is called. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``document``: A :symbol:`bson:bson_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/bulk-insert-opts.txt - -Errors ------- - -Operation errors are propagated via :symbol:`mongoc_bulk_operation_execute()`, while argument validation errors are reported by the ``error`` argument. - -Returns -------- - -Returns true on success, and false if passed invalid arguments. diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove.rst deleted file mode 100644 index b0ab7dedee67364bd3976a2171250a3a5aad1859..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_bulk_operation_remove - -mongoc_bulk_operation_remove() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, - const bson_t *selector); - -Remove documents as part of a bulk operation. This only queues the operation. To execute it, call :symbol:`mongoc_bulk_operation_execute()`. - -This function is superseded by :symbol:`mongoc_bulk_operation_remove_one_with_opts()` and :symbol:`mongoc_bulk_operation_remove_many_with_opts()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t`. - -See Also --------- - -:symbol:`mongoc_bulk_operation_remove_one()` - -:symbol:`mongoc_bulk_operation_remove_one_with_opts()` - -:symbol:`mongoc_bulk_operation_remove_many_with_opts()` - -Errors ------- - -Errors are propagated via :symbol:`mongoc_bulk_operation_execute()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_many_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_many_with_opts.rst deleted file mode 100644 index f032b73b20c9598b9e3b3575d6a274d65add4b00..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_many_with_opts.rst +++ /dev/null @@ -1,44 +0,0 @@ -:man_page: mongoc_bulk_operation_remove_many_with_opts - -mongoc_bulk_operation_remove_many_with_opts() -============================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *opts, - bson_error_t *error); /* OUT */ - -Delete documents as part of a bulk operation. This only queues the operation. To execute it, call :symbol:`mongoc_bulk_operation_execute()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which document to remove. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/bulk-remove-many-opts.txt - -See Also --------- - -:symbol:`mongoc_bulk_operation_remove()` - -:symbol:`mongoc_bulk_operation_remove_one_with_opts()` - -Errors ------- - -Operation errors are propagated via :symbol:`mongoc_bulk_operation_execute()`, while argument validation errors are reported by the ``error`` argument. - -Returns -------- - -Returns true on success, and false if passed invalid arguments. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_one.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_one.rst deleted file mode 100644 index b096b8b5c07088c2e80b1826313f08ce77bc6138..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_one.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_bulk_operation_remove_one - -mongoc_bulk_operation_remove_one() -================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector); - -Remove a single document as part of a bulk operation. This only queues the operation. To execute it, call :symbol:`mongoc_bulk_operation_execute()`. - -This function is superseded by :symbol:`mongoc_bulk_operation_remove_one_with_opts()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which document to remove. - -See Also --------- - -:symbol:`mongoc_bulk_operation_remove_one_with_opts()` - -:symbol:`mongoc_bulk_operation_remove_many_with_opts()` - -Errors ------- - -Errors are propagated via :symbol:`mongoc_bulk_operation_execute()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_one_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_one_with_opts.rst deleted file mode 100644 index f0ae8faecaa30df41895960845fdd2a5cd4a262f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_remove_one_with_opts.rst +++ /dev/null @@ -1,44 +0,0 @@ -:man_page: mongoc_bulk_operation_remove_one_with_opts - -mongoc_bulk_operation_remove_one_with_opts() -============================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *opts, - bson_error_t *error); /* OUT */ - -Remove a single document as part of a bulk operation. This only queues the operation. To execute it, call :symbol:`mongoc_bulk_operation_execute()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which document to remove. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/bulk-remove-one-opts.txt - -See Also --------- - -:symbol:`mongoc_bulk_operation_remove_one()` - -:symbol:`mongoc_bulk_operation_remove_many_with_opts()` - -Errors ------- - -Operation errors are propagated via :symbol:`mongoc_bulk_operation_execute()`, while argument validation errors are reported by the ``error`` argument. - -Returns -------- - -Returns true on success, and false if passed invalid arguments. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_replace_one.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_replace_one.rst deleted file mode 100644 index 90479331439abfd1af7dbe4d54e468b1d6c0ccfa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_replace_one.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_bulk_operation_replace_one - -mongoc_bulk_operation_replace_one() -=================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert); - -Replace a single document as part of a bulk operation. This only queues the operation. To execute it, call :symbol:`mongoc_bulk_operation_execute()`. - -This function is superseded by :symbol:`mongoc_bulk_operation_replace_one_with_opts()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which document to remove. -* ``document``: A :symbol:`bson:bson_t` containing the replacement document. -* ``upsert``: ``true`` if this should be an ``upsert``. - -.. warning:: - - ``document`` may not contain fields with keys containing ``.`` or ``$``. - -See Also --------- - -:symbol:`mongoc_bulk_operation_replace_one_with_opts()` - -Errors ------- - -Errors are propagated via :symbol:`mongoc_bulk_operation_execute()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_replace_one_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_replace_one_with_opts.rst deleted file mode 100644 index 466f23348f51197b852bc4866eec4e47c24fff12..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_replace_one_with_opts.rst +++ /dev/null @@ -1,50 +0,0 @@ -:man_page: mongoc_bulk_operation_replace_one_with_opts - -mongoc_bulk_operation_replace_one_with_opts() -============================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); /* OUT */ - -Replace a single document as part of a bulk operation. This only queues the operation. To execute it, call :symbol:`mongoc_bulk_operation_execute()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which document to remove. -* ``document``: A :symbol:`bson:bson_t` containing the replacement document. -* ``error``: A :symbol:`bson:bson_error_t` any errors that may have occurred. - -.. include:: includes/bulk-replace-one-opts.txt - -.. warning:: - - ``document`` may not contain fields with keys containing ``.`` or ``$``. - -See Also --------- - -:symbol:`mongoc_bulk_operation_remove_many_with_opts()` - -:symbol:`mongoc_bulk_operation_insert()` - -Errors ------- - -Operation errors are propagated via :symbol:`mongoc_bulk_operation_execute()`, while argument validation errors are reported by the ``error`` argument. - -Returns -------- - -Returns true on success, and false if passed invalid arguments. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_set_bypass_document_validation.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_set_bypass_document_validation.rst deleted file mode 100644 index e633dde2e2d3e4bce338bbe52b97f64d00faa6c3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_set_bypass_document_validation.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_bulk_operation_set_bypass_document_validation - -mongoc_bulk_operation_set_bypass_document_validation() -====================================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_set_bypass_document_validation ( - mongoc_bulk_operation_t *bulk, bool bypass); - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``bypass``: A boolean. - -Description ------------ - -Will bypass document validation for all operations part of this :doc:`bulk <mongoc_bulk_operation_t>`. - -See Also --------- - -:ref:`bulk_operation_bypassing_document_validation` diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_set_hint.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_set_hint.rst deleted file mode 100644 index e9db67818ba670102aa96773011be840443a30bc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_set_hint.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_bulk_operation_set_hint - -mongoc_bulk_operation_set_hint() -================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_set_hint (const mongoc_bulk_operation_t *bulk, - uint32_t server_id); - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``server_id``: An opaque id identifying the server to use. - -Description ------------ - -Specifies which server to use for the operation. This function has an effect only if called before :symbol:`mongoc_bulk_operation_execute`. - -(The function name includes the old term "hint" for the sake of backward compatibility, but we now call this number a "server id".) - -Use ``mongoc_bulk_operation_set_hint`` only for building a language driver that wraps the C Driver. When writing applications in C, leave the server id unset and allow the driver to choose a suitable server for the bulk operation. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_t.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_t.rst deleted file mode 100644 index 54872f378cbc777de48f0cbbecdb77b8b03dd01b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_t.rst +++ /dev/null @@ -1,57 +0,0 @@ -:man_page: mongoc_bulk_operation_t - -mongoc_bulk_operation_t -======================= - -Bulk Write Operations - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_bulk_operation_t mongoc_bulk_operation_t; - -The opaque type ``mongoc_bulk_operation_t`` provides an abstraction for submitting multiple write operations as a single batch. - -After adding all of the write operations to the ``mongoc_bulk_operation_t``, call :symbol:`mongoc_bulk_operation_execute()` to execute the operation. - -.. warning:: - - It is only valid to call :symbol:`mongoc_bulk_operation_execute()` once. The ``mongoc_bulk_operation_t`` must be destroyed afterwards. - -See Also --------- - -:symbol:`Bulk Write Operations <bulk>` - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_bulk_operation_delete - mongoc_bulk_operation_delete_one - mongoc_bulk_operation_destroy - mongoc_bulk_operation_execute - mongoc_bulk_operation_get_hint - mongoc_bulk_operation_get_write_concern - mongoc_bulk_operation_insert - mongoc_bulk_operation_insert_with_opts - mongoc_bulk_operation_remove - mongoc_bulk_operation_remove_many_with_opts - mongoc_bulk_operation_remove_one - mongoc_bulk_operation_remove_one_with_opts - mongoc_bulk_operation_replace_one - mongoc_bulk_operation_replace_one_with_opts - mongoc_bulk_operation_set_bypass_document_validation - mongoc_bulk_operation_set_hint - mongoc_bulk_operation_update - mongoc_bulk_operation_update_many_with_opts - mongoc_bulk_operation_update_one - mongoc_bulk_operation_update_one_with_opts - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update.rst deleted file mode 100644 index 3605a18bdfc59019a8ae31d016ad3fae3fb240d2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_bulk_operation_update - -mongoc_bulk_operation_update() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert); - -This function queues an update as part of a bulk operation. This does not execute the operation. To execute the entirety of the bulk operation call :symbol:`mongoc_bulk_operation_execute()`. - -``document`` MUST only contain fields whose key starts with ``$``. See the update document specification for more details. - -This function is superseded by :symbol:`mongoc_bulk_operation_update_one_with_opts()` and :symbol:`mongoc_bulk_operation_update_many_with_opts()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which documents to remove. -* ``document``: A :symbol:`bson:bson_t` containing the update document. -* ``upsert``: ``true`` if an ``upsert`` should be performed. - -See Also --------- - -:symbol:`mongoc_bulk_operation_update_one_with_opts()` - -:symbol:`mongoc_bulk_operation_update_many_with_opts()` - -Errors ------- - -Errors are propagated via :symbol:`mongoc_bulk_operation_execute()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_many_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_many_with_opts.rst deleted file mode 100644 index 7028d060df40a2f51a25c050c0a418361909e4aa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_many_with_opts.rst +++ /dev/null @@ -1,47 +0,0 @@ -:man_page: mongoc_bulk_operation_update_many_with_opts - -mongoc_bulk_operation_update_many_with_opts() -============================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); /* OUT */ - -This function queues an update as part of a bulk operation. This does not execute the operation. To execute the entirety of the bulk operation call :symbol:`mongoc_bulk_operation_execute()`. - -.. warning:: - - ``document`` MUST only contain fields whose key starts with ``$``. See the update document specification for more details. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which documents to remove. -* ``document``: A :symbol:`bson:bson_t` containing the update document. -* ``error``: A :symbol:`bson:bson_error_t` any errors that may have occurred. - -.. include:: includes/bulk-update-many-opts.txt - -See Also --------- - -:symbol:`mongoc_bulk_operation_update_one_with_opts()` - -Errors ------- - -Operation errors are propagated via :symbol:`mongoc_bulk_operation_execute()`, while argument validation errors are reported by the ``error`` argument. - -Returns -------- - -Returns true on success, and false if there is a server or network error or if passed invalid arguments. diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_one.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_one.rst deleted file mode 100644 index 419be11f4e0dcc29d30c024f204c88cac0ade0e9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_one.rst +++ /dev/null @@ -1,39 +0,0 @@ -:man_page: mongoc_bulk_operation_update_one - -mongoc_bulk_operation_update_one() -================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert); - -This function queues an update as part of a bulk operation. It will only modify a single document on the MongoDB server. This function does not execute the operation. To execute the entirety of the bulk operation call :symbol:`mongoc_bulk_operation_execute()`. - -This function is superseded by :symbol:`mongoc_bulk_operation_update_one_with_opts()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which document to remove. -* ``document``: A :symbol:`bson:bson_t` containing the update document. -* ``upsert``: ``true`` if an ``upsert`` should be performed. - -.. warning:: - - ``document`` *must only* contain fields whose key starts with ``$``. See the update document specification for more details. - -See Also --------- - -:symbol:`mongoc_bulk_operation_update()` - -:symbol:`mongoc_bulk_operation_update_one_with_opts()` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_one_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_one_with_opts.rst deleted file mode 100644 index 2acf042451e7b7d328f5031e2649c6f33049abb8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_bulk_operation_update_one_with_opts.rst +++ /dev/null @@ -1,47 +0,0 @@ -:man_page: mongoc_bulk_operation_update_one_with_opts - -mongoc_bulk_operation_update_one_with_opts() -============================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); /* OUT */ - -This function queues an update as part of a bulk operation. It will only modify a single document on the MongoDB server. This function does not execute the operation. To execute the entirety of the bulk operation call :symbol:`mongoc_bulk_operation_execute()`. - -Parameters ----------- - -* ``bulk``: A :symbol:`mongoc_bulk_operation_t`. -* ``selector``: A :symbol:`bson:bson_t` that selects which document to remove. -* ``document``: A :symbol:`bson:bson_t` containing the update document. -* ``error``: A :symbol:`bson:bson_error_t` any errors that may have occurred. - -.. include:: includes/bulk-update-one-opts.txt - -.. warning:: - - ``document`` *must only* contain fields whose key starts with ``$``. See the update document specification for more details. - -See Also --------- - -:symbol:`mongoc_bulk_operation_update_many_with_opts()` - -Errors ------- - -Operation errors are propagated via :symbol:`mongoc_bulk_operation_execute()`, while argument validation errors are reported by the ``error`` argument. - -Returns -------- - -Returns true on success, and false if there is a server or network error or if passed invalid arguments. diff --git a/lib/mongoc/libmongoc/doc/mongoc_change_stream_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_change_stream_destroy.rst deleted file mode 100644 index 8d5d45c1641dc2df848810aa278cf38d36632513..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_change_stream_destroy.rst +++ /dev/null @@ -1,19 +0,0 @@ -:man_page: mongoc_change_stream_destroy - -mongoc_change_stream_destroy() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_change_stream_destroy (mongoc_change_stream_t *stream); - -Destroys a change stream and associated data. - -Parameters ----------- - -* ``stream``: An allocated :symbol:`mongoc_change_stream_t`. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/mongoc_change_stream_error_document.rst b/lib/mongoc/libmongoc/doc/mongoc_change_stream_error_document.rst deleted file mode 100644 index dfa995465c4b3d285ff2a8a623e898da03b83a35..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_change_stream_error_document.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_change_stream_error_document - -mongoc_change_stream_error_document() -===================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_change_stream_error_document (mongoc_change_stream_t *stream, - bson_error_t *err, - const bson_t **reply); - -Checks if an error has occurred when creating or iterating over a change stream. - -Similar to :symbol:`mongoc_cursor_error_document` if the error has occurred -client-side then the ``reply`` will be set to an empty BSON document. If the -error occurred server-side, ``reply`` is set to the server's reply document. - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_change_stream_t`. -* ``err``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. -* ``reply``: A location for a :symbol:`bson:bson_t`. - -Returns -------- -A boolean indicating if there was an error. diff --git a/lib/mongoc/libmongoc/doc/mongoc_change_stream_get_resume_token.rst b/lib/mongoc/libmongoc/doc/mongoc_change_stream_get_resume_token.rst deleted file mode 100644 index 326e5bf6aabbaaba67ffb29ae4bd62a48d0542b6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_change_stream_get_resume_token.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_change_stream_get_resume_token - -mongoc_change_stream_get_resume_token() -======================================= - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_change_stream_get_resume_token (mongoc_change_stream_t *stream); - -This function returns the cached resume token, which may be passed as either the -``resumeAfter`` or ``startAfter`` option of a ``watch`` function to start a new -change stream from the same point. - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_change_stream_t`. - -Returns -------- - -A :symbol:`bson:bson_t` that should not be modified or freed. - -Returns ``NULL`` if no resume token is available. This is possible if the change -stream has not been iterated and neither ``resumeAfter`` nor ``startAfter`` -options were specified in the ``watch`` function. - -Lifecycle ---------- - -The returned :symbol:`bson:bson_t` is valid for the lifetime of ``stream`` and -its data may be updated if :symbol:`mongoc_change_stream_next` is called after -this function. The value may be copied to extend its lifetime or preserve the -current resume token. diff --git a/lib/mongoc/libmongoc/doc/mongoc_change_stream_next.rst b/lib/mongoc/libmongoc/doc/mongoc_change_stream_next.rst deleted file mode 100644 index 9f56dab1df9aa1f71bd4ce57e8e12db19ffa380b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_change_stream_next.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_change_stream_next - -mongoc_change_stream_next() -=========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_change_stream_next (mongoc_change_stream_t *stream, - const bson_t **bson); - -This function iterates the underlying cursor, setting ``bson`` to the next -document. This will block for a maximum of ``maxAwaitTimeMS`` milliseconds as -specified in the options when created, or the default timeout if omitted. Data -may be returned before the timeout. If no data is returned this function returns -``false``. - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_change_stream_t`. -* ``bson``: The location for the resulting document. - -Returns -------- - -This function returns true if a valid bson document was read from the stream. -Otherwise, false if there was an error or no document was available. - -Errors can be determined with the :symbol:`mongoc_change_stream_error_document` -function. - -Lifecycle ---------- - -Similar to :symbol:`mongoc_cursor_next` the lifetime of ``bson`` is until the -next call to :symbol:`mongoc_change_stream_next`, so it needs to be copied to -extend the lifetime. diff --git a/lib/mongoc/libmongoc/doc/mongoc_change_stream_t.rst b/lib/mongoc/libmongoc/doc/mongoc_change_stream_t.rst deleted file mode 100644 index 31f4a021830da16f7499621ef2b0f255f3f2bd35..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_change_stream_t.rst +++ /dev/null @@ -1,65 +0,0 @@ -:man_page: mongoc_change_stream_t - -mongoc_change_stream_t -====================== - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct _mongoc_change_stream_t mongoc_change_stream_t; - -:symbol:`mongoc_change_stream_t` is a handle to a change stream. A collection -change stream can be obtained using :symbol:`mongoc_collection_watch`. - -It is recommended to use a :symbol:`mongoc_change_stream_t` and its functions instead of a raw aggregation with a ``$changeStream`` stage. For more information see the `MongoDB Manual Entry on Change Streams <http://dochub.mongodb.org/core/changestreams>`_. - -Example -------- -.. literalinclude:: ../examples/example-collection-watch.c - :language: c - :caption: example-collection-watch.c - -Starting and Resuming -````````````````````` - -All ``watch`` functions accept several options to indicate where a change stream should start returning changes from: ``resumeAfter``, ``startAfter``, and ``startAtOperationTime``. - -All changes returned by :symbol:`mongoc_change_stream_next` include a resume token in the ``_id`` field. MongoDB 4.2 also includes an additional resume token in each "aggregate" and "getMore" command response, which points to the end of that response's batch. The current token is automatically cached by libmongoc. In the event of an error, libmongoc attempts to recreate the change stream starting where it left off by passing the cached resume token. libmongoc only attempts to resume once, but client applications can access the cached resume token with :symbol:`mongoc_change_stream_get_resume_token` and use it for their own resume logic by passing it as either the ``resumeAfter`` or ``startAfter`` option. - -Additionally, change streams can start returning changes at an operation time by using the ``startAtOperationTime`` field. This can be the timestamp returned in the ``operationTime`` field of a command reply. - -``resumeAfter``, ``startAfter``, and ``startAtOperationTime`` are mutually exclusive options. Setting more than one will result in a server error. - -The following example implements custom resuming logic, persisting the resume token in a file. - -.. literalinclude:: ../examples/example-resume.c - :language: c - :caption: example-resume.c - -The following example shows using ``startAtOperationTime`` to synchronize a change stream with another operation. - -.. literalinclude:: ../examples/example-start-at-optime.c - :language: c - :caption: example-start-at-optime.c - - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_client_watch - mongoc_database_watch - mongoc_collection_watch - mongoc_change_stream_next - mongoc_change_stream_get_resume_token - mongoc_change_stream_error_document - mongoc_change_stream_destroy diff --git a/lib/mongoc/libmongoc/doc/mongoc_check_version.rst b/lib/mongoc/libmongoc/doc/mongoc_check_version.rst deleted file mode 100644 index a90eb25e771cdf6a659dad0be26705ba82943f66..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_check_version.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_check_version - -mongoc_check_version() -====================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_check_version (int required_major, - int required_minor, - int required_micro); - -Parameters ----------- - -* ``required_major``: The minimum major version required. -* ``required_minor``: The minimum minor version required. -* ``required_micro``: The minimum micro version required. - -Returns -------- - -True if libmongoc's version is greater than or equal to the required version. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cleanup.rst b/lib/mongoc/libmongoc/doc/mongoc_cleanup.rst deleted file mode 100644 index c21296d521cc36511d5f69418cd2e96beda15173..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cleanup.rst +++ /dev/null @@ -1,17 +0,0 @@ -:man_page: mongoc_cleanup - -mongoc_cleanup() -================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_cleanup (void); - -Description ------------ - -.. include:: includes/init_cleanup.txt diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_command.rst b/lib/mongoc/libmongoc/doc/mongoc_client_command.rst deleted file mode 100644 index eaa36c1eb7c3287bba6ee6412ed9a649ba21ffc5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_command.rst +++ /dev/null @@ -1,52 +0,0 @@ -:man_page: mongoc_client_command - -mongoc_client_command() -======================= - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_client_command (mongoc_client_t *client, - const char *db_name, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *query, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs); - -This function is superseded by :symbol:`mongoc_client_command_with_opts()`, :symbol:`mongoc_client_read_command_with_opts()`, :symbol:`mongoc_client_write_command_with_opts()`, and :symbol:`mongoc_client_read_write_command_with_opts()`. - -.. include:: includes/not-retryable-read.txt - -Description ------------ - -This function creates a cursor which will execute the command when :symbol:`mongoc_cursor_next` is called on it. The client's read preference, read concern, and write concern are not applied to the command, and :symbol:`mongoc_cursor_next` will not check the server response for a write concern error or write concern timeout. - -If :symbol:`mongoc_cursor_next()` returns ``false``, then retrieve error details with :symbol:`mongoc_cursor_error()` or :symbol:`mongoc_cursor_error_document()`. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db_name``: The name of the database to run the command on. -* ``flags``: Unused. -* ``skip``: Unused. -* ``limit``: Unused. -* ``batch_size``: Unused. -* ``query``: A :symbol:`bson:bson_t` containing the command specification. -* ``fields``: Unused. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. Otherwise, the command uses mode ``MONGOC_READ_PRIMARY``. - -Returns -------- - -A :symbol:`mongoc_cursor_t`. - -The cursor should be freed with :symbol:`mongoc_cursor_destroy()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_command_simple.rst b/lib/mongoc/libmongoc/doc/mongoc_client_command_simple.rst deleted file mode 100644 index 43e14309b5c6f9c0c28fbf5364e1e23f35cbda70..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_command_simple.rst +++ /dev/null @@ -1,48 +0,0 @@ -:man_page: mongoc_client_command_simple - -mongoc_client_command_simple() -============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_command_simple (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); - -This is a simplified interface to :symbol:`mongoc_client_command()`. It returns the first document from the result cursor into ``reply``. The client's read preference, read concern, and write concern are not applied to the command. - -.. warning:: - - ``reply`` is always set, and should be released with :symbol:`bson:bson_destroy()`. - -.. include:: includes/not-retryable-read.txt - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db_name``: The name of the database to run the command on. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. Otherwise, the command uses mode ``MONGOC_READ_PRIMARY``. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -This function does not check the server response for a write concern error or write concern timeout. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_command_simple_with_server_id.rst b/lib/mongoc/libmongoc/doc/mongoc_client_command_simple_with_server_id.rst deleted file mode 100644 index eedb07e5a18d05eb8871a9ea066a84aa50bff5cb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_command_simple_with_server_id.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_client_command_simple_with_server_id - -mongoc_client_command_simple_with_server_id() -============================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_command_simple_with_server_id ( - mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - uint32_t server_id, - bson_t *reply, - bson_error_t *error); - -This function executes a command on a specific server, using the database and command specification provided. - -.. include:: includes/not-retryable-read.txt - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db_name``: The name of the database to run the command on. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. -* ``server_id``: An opaque id specifying which server to use. -* ``reply``: An optional location for a :symbol:`bson:bson_t` which will store the server's reply. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or a ``NULL``. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -This function does not check the server response for a write concern error or write concern timeout. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_command_with_opts.rst deleted file mode 100644 index 77f98d02f6a4fcf8eec5d9afc6c4167272378877..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_command_with_opts.rst +++ /dev/null @@ -1,61 +0,0 @@ -:man_page: mongoc_client_command_with_opts - -mongoc_client_command_with_opts() -================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_command_with_opts ( - mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, interpreting ``opts`` according to the MongoDB server version. To send a raw command to the server without any of this logic, use :symbol:`mongoc_client_command_simple`. - -.. |opts-source| replace:: ``client`` - -.. include:: includes/opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -.. include:: includes/not-retryable-read.txt - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db_name``: The name of the database to run the command on. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -The reply is not parsed for a write concern timeout or write concern error. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_client_destroy.rst deleted file mode 100644 index fc830636d17082b8d02a476514e8a3d38fc6ea98..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_destroy.rst +++ /dev/null @@ -1,20 +0,0 @@ -:man_page: mongoc_client_destroy - -mongoc_client_destroy() -======================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_destroy (mongoc_client_t *client); - -Release all resources associated with ``client`` and free the structure. Does nothing if ``client`` is NULL. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_enable_auto_encryption.rst b/lib/mongoc/libmongoc/doc/mongoc_client_enable_auto_encryption.rst deleted file mode 100644 index 867478eb78c51602f12b287a1f8e06c18d4aa7eb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_enable_auto_encryption.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_client_enable_auto_encryption - -mongoc_client_enable_auto_encryption() -====================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_enable_auto_encryption (mongoc_client_t *client, - mongoc_auto_encryption_opts_t* opts, - bson_error_t* error); - -Enable automatic client side encryption on a :symbol:`mongoc_client_t`. Requires libmongoc to be built with support for Client-Side Field Level Encryption. See the guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>`. - -Automatic encryption is an enterprise only feature that only applies to operations on a collection. Automatic encryption is not supported for operations on a database or view, and operations that are not bypassed will result in error. To bypass automatic encryption for all operations, bypass automatic encryption with :symbol:`mongoc_auto_encryption_opts_set_bypass_auto_encryption()` in ``opts``. - -Automatic encryption requires the authenticated user to have the `listCollections privilege action <https://docs.mongodb.com/manual/reference/command/listCollections/#dbcmd.listCollections>`_. - -Enabling automatic encryption reduces the maximum message size and may have a negative performance impact. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``opts``: A required :symbol:`mongoc_auto_encryption_opts_t`. -* ``error``: A :symbol:`bson_error_t` which is set on error. - -Returns -------- - -True on success. False on error. On error, ``error`` is set. - -See also --------- - -* :symbol:`mongoc_auto_encryption_opts_t` -* The guide for :doc:`Using Client-Side Field Level Encryption <using_client_side_encryption>` for libmongoc -* The MongoDB Manual for `Client-Side Field Level Encryption <https://docs.mongodb.com/manual/core/security-client-side-encryption/>`_ diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_find_databases_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_find_databases_with_opts.rst deleted file mode 100644 index ff2304c0e3f7293bd5a8d1f62f27665cb53a6204..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_find_databases_with_opts.rst +++ /dev/null @@ -1,39 +0,0 @@ -:man_page: mongoc_client_find_databases_with_opts - -mongoc_client_find_databases_with_opts() -======================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_client_find_databases_with_opts (mongoc_client_t *client, - const bson_t *opts); - -Fetches a cursor containing documents, each corresponding to a database on this MongoDB server. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. - -.. |opts-source| replace:: ``client`` - -.. include:: includes/generic-opts.txt - -.. include:: includes/retryable-read.txt - -Errors ------- - -Use :symbol:`mongoc_cursor_error` on the returned cursor to check for errors. - -Returns -------- - -A cursor where each result corresponds to the server's representation of a database. - -The cursor functions :symbol:`mongoc_cursor_set_limit`, :symbol:`mongoc_cursor_set_batch_size`, and :symbol:`mongoc_cursor_set_max_await_time_ms` have no use on the returned cursor. diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_collection.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_collection.rst deleted file mode 100644 index e2df5f1c6c84e549c79f7c66b25f2ae0eef3bfba..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_collection.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_client_get_collection - -mongoc_client_get_collection() -============================== - -Synopsis --------- - -.. code-block:: c - - mongoc_collection_t * - mongoc_client_get_collection (mongoc_client_t *client, - const char *db, - const char *collection); - -Get a newly allocated :symbol:`mongoc_collection_t` for the collection named ``collection`` in the database named ``db``. - -.. tip:: - - Collections are automatically created on the MongoDB server upon insertion of the first document. There is no need to create a collection manually. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db``: The name of the database containing the collection. -* ``collection``: The name of the collection. - -Returns -------- - -A newly allocated :symbol:`mongoc_collection_t` that should be freed with :symbol:`mongoc_collection_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_database.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_database.rst deleted file mode 100644 index 4e1bb82b6937e52d40510975692a69c74360fd43..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_database.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_client_get_database - -mongoc_client_get_database() -============================ - -Synopsis --------- - -.. code-block:: c - - mongoc_database_t * - mongoc_client_get_database (mongoc_client_t *client, const char *name); - -Get a newly allocated :symbol:`mongoc_database_t` for the database named ``name``. - -.. tip:: - - Databases are automatically created on the MongoDB server upon insertion of the first document into a collection. There is no need to create a database manually. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``name``: The name of the database. - -Returns -------- - -A newly allocated :symbol:`mongoc_database_t <mongoc_client_t>` that should be freed with :symbol:`mongoc_database_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_database_names.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_database_names.rst deleted file mode 100644 index ba1bf2445d10fca44d3c4b281fce1ffe28d8ca86..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_database_names.rst +++ /dev/null @@ -1,44 +0,0 @@ -:man_page: mongoc_client_get_database_names - -mongoc_client_get_database_names() -================================== - -Synopsis --------- - -.. code-block:: c - - char ** - mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_client_get_database_names_with_opts()` instead. - -Description ------------ - -This function queries the MongoDB server for a list of known databases. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -A ``NULL`` terminated vector of ``NULL-byte`` terminated strings. The result should be freed with :symbol:`bson:bson_strfreev()`. - -``NULL`` is returned upon failure and ``error`` is set. diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_database_names_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_database_names_with_opts.rst deleted file mode 100644 index bbdfc1259a3d77f11d281e4502d925a0a823eab6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_database_names_with_opts.rst +++ /dev/null @@ -1,61 +0,0 @@ -:man_page: mongoc_client_get_database_names_with_opts - -mongoc_client_get_database_names_with_opts() -============================================ - -Synopsis --------- - -.. code-block:: c - - char ** - mongoc_client_get_database_names_with_opts (mongoc_client_t *client, - const bson_t *opts, - bson_error_t *error); - -This function queries the MongoDB server for a list of known databases. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``client`` - -.. include:: includes/generic-opts.txt - -.. include:: includes/retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -A ``NULL`` terminated vector of ``NULL-byte`` terminated strings. The result should be freed with :symbol:`bson:bson_strfreev()`. - -``NULL`` is returned upon failure and ``error`` is set. - -Examples --------- - -.. code-block:: c - - { - bson_error_t error; - char **strv; - unsigned i; - - if ((strv = mongoc_client_get_database_names_with_opts (client, NULL, &error))) { - for (i = 0; strv[i]; i++) - printf ("%s\n", strv[i]); - bson_strfreev (strv); - } else { - fprintf (stderr, "Command failed: %s\n", error.message); - } - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_default_database.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_default_database.rst deleted file mode 100644 index 873ec98a72229733bb73f25a60e4b936807fb334..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_default_database.rst +++ /dev/null @@ -1,50 +0,0 @@ -:man_page: mongoc_client_get_default_database - -mongoc_client_get_default_database() -==================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_database_t * - mongoc_client_get_default_database (mongoc_client_t *client); - -Get the database named in the MongoDB connection URI, or ``NULL`` if the URI specifies none. - -Useful when you want to choose which database to use based only on the URI in a configuration file. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - -Returns -------- - -A newly allocated :symbol:`mongoc_database_t <mongoc_client_t>` that should be freed with :symbol:`mongoc_database_destroy()`. - -Example -------- - -.. code-block:: c - :caption: Default Database Example - - /* default database is "db_name" */ - mongoc_client_t *client = mongoc_client_new ("mongodb://host/db_name"); - mongoc_database_t *db = mongoc_client_get_default_database (client); - - assert (!strcmp ("db_name", mongoc_database_get_name (db))); - - mongoc_database_destroy (db); - mongoc_client_destroy (client); - - /* no default database */ - client = mongoc_client_new ("mongodb://host/"); - db = mongoc_client_get_default_database (client); - - assert (!db); - - mongoc_client_destroy (client); - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_gridfs.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_gridfs.rst deleted file mode 100644 index 099e8a23dc74259f6d0e805f370cb804baca965c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_gridfs.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_client_get_gridfs - -mongoc_client_get_gridfs() -========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_t * - mongoc_client_get_gridfs (mongoc_client_t *client, - const char *db, - const char *prefix, - bson_error_t *error); - -The ``mongoc_client_get_gridfs()`` function shall create a new :symbol:`mongoc_gridfs_t`. The ``db`` parameter is the name of the database which the gridfs instance should exist in. The ``prefix`` parameter corresponds to the gridfs collection namespacing; its default is "fs", thus the default GridFS collection names are "fs.files" and "fs.chunks". - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db``: The database name. -* ``prefix``: Optional prefix for gridfs collection names or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -On success, returns a :symbol:`mongoc_gridfs_t` you must free with :symbol:`mongoc_gridfs_destroy()`. Returns ``NULL`` upon failure and sets ``error``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_max_bson_size.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_max_bson_size.rst deleted file mode 100644 index cb2090a0651cdfc287e9da5d8d371943bebd9833..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_max_bson_size.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_client_get_max_bson_size - -mongoc_client_get_max_bson_size() -================================= - -Synopsis --------- - -.. code-block:: c - - int32_t - mongoc_client_get_max_bson_size (mongoc_client_t *client); - -The :symbol:`mongoc_client_get_max_bson_size()` returns the maximum bson document size allowed by the cluster. Until a connection has been made, this will be the default of 16Mb. - -Deprecated ----------- - -.. warning:: - - This function is deprecated and should not be used in new code. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - -Returns -------- - -The server provided max bson size, or 16Mb if no connection has been established. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_max_message_size.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_max_message_size.rst deleted file mode 100644 index 1747af73483ee537d6697d25d96be89c94d62a14..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_max_message_size.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_client_get_max_message_size - -mongoc_client_get_max_message_size() -==================================== - -Synopsis --------- - -.. code-block:: c - - int32_t - mongoc_client_get_max_message_size (mongoc_client_t *client); - -The :symbol:`mongoc_client_get_max_message_size()` returns the maximum message size allowed by the cluster. Until a connection has been made, this will be the default of 40Mb. - -Deprecated ----------- - -.. warning:: - - This function is deprecated and should not be used in new code. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - -Returns -------- - -The server provided max message size, or 40Mb if no connection has been established. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_read_concern.rst deleted file mode 100644 index 6ec1a8a6ddc97cd4d3146cc31b38a56251ac3935..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_read_concern.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_client_get_read_concern - -mongoc_client_get_read_concern() -================================ - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_concern_t * - mongoc_client_get_read_concern (const mongoc_client_t *client); - -Retrieve the default read concern configured for the client instance. The result should not be modified or freed. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - -Returns -------- - -A :symbol:`mongoc_read_concern_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_read_prefs.rst deleted file mode 100644 index 47b74d89b725c9d711d365d9402d83f876be31c2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_read_prefs.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_client_get_read_prefs - -mongoc_client_get_read_prefs() -============================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_prefs_t * - mongoc_client_get_read_prefs (const mongoc_client_t *client); - -Retrieves the default read preferences configured for the client instance. The result should not be modified or freed. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - -Returns -------- - -A :symbol:`mongoc_read_prefs_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_server_description.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_server_description.rst deleted file mode 100644 index 6406b13f84bc63a8084e6c8fdc71f613bb9a6a67..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_server_description.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_client_get_server_description - -mongoc_client_get_server_description() -====================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_server_description_t * - mongoc_client_get_server_description (mongoc_client_t *client, - uint32_t server_id); - -Get information about the server specified by ``server_id``. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``server_id``: An opaque id specifying the server. - -Returns -------- - -A :symbol:`mongoc_server_description_t` that must be freed with :symbol:`mongoc_server_description_destroy`. If the server is no longer in the topology, returns NULL. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_server_descriptions.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_server_descriptions.rst deleted file mode 100644 index 4916342b696b6557cf8a9c8792f20e004444484e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_server_descriptions.rst +++ /dev/null @@ -1,55 +0,0 @@ -:man_page: mongoc_client_get_server_descriptions - -mongoc_client_get_server_descriptions() -======================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_server_description_t ** - mongoc_client_get_server_descriptions (const mongoc_client_t *client, - size_t *n); - -Fetches an array of :symbol:`mongoc_server_description_t` structs for all known servers in the topology. Returns no servers until the client connects. Returns a single server if the client is directly connected, or all members of a replica set if the client's MongoDB URI includes a "replicaSet" option, or all known mongos servers if the MongoDB URI includes a list of them. - -.. code-block:: c - - void - show_servers (const mongoc_client_t *client) - { - bson_t *b = BCON_NEW ("ping", BCON_INT32 (1)); - bson_error_t error; - bool r; - mongoc_server_description_t **sds; - size_t i, n; - - /* ensure client has connected */ - r = mongoc_client_command_simple (client, "db", b, NULL, NULL, &error); - if (!r) { - MONGOC_ERROR ("could not connect: %s\n", error.message); - return; - } - - sds = mongoc_client_get_server_descriptions (client, &n); - - for (i = 0; i < n; ++i) { - printf ("%s\n", mongoc_server_description_host (sds[i])->host_and_port); - } - - mongoc_server_descriptions_destroy_all (sds, n); - bson_destroy (&b); - } - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``n``: Receives the length of the descriptions array. - -Returns -------- - -A newly allocated array that must be freed with :symbol:`mongoc_server_descriptions_destroy_all`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_server_status.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_server_status.rst deleted file mode 100644 index 64ef8da628d82f8502d956883400b42f0e8bc9f6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_server_status.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_client_get_server_status - -mongoc_client_get_server_status() -================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_get_server_status (mongoc_client_t *client, - mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error) BSON_GNUC_DEPRECATED; - -Queries the server for the current server status. The result is stored in ``reply``. - -``reply`` is always initialized, even in the case of failure. Always call :symbol:`bson:bson_destroy()` to release it. - -Deprecated ----------- - -This helper function is deprecated and should not be used in new code. Run the `serverStatus <https://docs.mongodb.com/manual/reference/command/serverStatus/>`_ command directly with :symbol:`mongoc_client_read_command_with_opts()` instead. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. -* ``reply``: A location for the result :symbol:`bson:bson_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_uri.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_uri.rst deleted file mode 100644 index 6738b324196e3f505739892576cfdbfdf40c9e32..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_uri.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_client_get_uri - -mongoc_client_get_uri() -======================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_uri_t * - mongoc_client_get_uri (const mongoc_client_t *client); - -Fetches the :symbol:`mongoc_uri_t` used to create the client. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - -Returns -------- - -A :symbol:`mongoc_uri_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_get_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_client_get_write_concern.rst deleted file mode 100644 index 240fbc34e6b22b08534b2b4666a03f008eb958d2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_get_write_concern.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_client_get_write_concern - -mongoc_client_get_write_concern() -================================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_write_concern_t * - mongoc_client_get_write_concern (const mongoc_client_t *client); - -Retrieve the default write concern configured for the client instance. The result should not be modified or freed. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - -Returns -------- - -A :symbol:`mongoc_write_concern_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_new.rst b/lib/mongoc/libmongoc/doc/mongoc_client_new.rst deleted file mode 100644 index 09a2df54c870494cb46a77cc9252f1974b0432a4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_new.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_client_new - -mongoc_client_new() -=================== - -Synopsis --------- - -.. code-block:: c - - mongoc_client_t * - mongoc_client_new (const char *uri_string); - -Creates a new :symbol:`mongoc_client_t` using the URI string provided. - -Parameters ----------- - -* ``uri_string``: A string containing the MongoDB connection URI. - -Returns -------- - -A newly allocated :symbol:`mongoc_client_t` if the URI parsed successfully, otherwise ``NULL``. - -See Also --------- - -:symbol:`mongoc_client_new_from_uri()` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_new_from_uri.rst b/lib/mongoc/libmongoc/doc/mongoc_client_new_from_uri.rst deleted file mode 100644 index 055c1b29db49dc379821d89fd42b8760453146f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_new_from_uri.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_client_new_from_uri - -mongoc_client_new_from_uri() -============================ - -Synopsis --------- - -.. code-block:: c - - mongoc_client_t * - mongoc_client_new_from_uri (const mongoc_uri_t *uri); - -Creates a new :symbol:`mongoc_client_t` using the :symbol:`mongoc_uri_t` provided. - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Returns -------- - -A newly allocated :symbol:`mongoc_client_t` that should be freed with :symbol:`mongoc_client_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_destroy.rst deleted file mode 100644 index e03de9d597ec0faabdeb6960a688f035f1287a33..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_client_pool_destroy - -mongoc_client_pool_destroy() -============================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_pool_destroy (mongoc_client_pool_t *pool); - -Release all resources associated with ``pool``, including freeing the structure. - -This method is NOT thread safe, and must only be called by one thread. It should be called once the application is shutting down, and after all other threads that use clients have been joined. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_max_size.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_max_size.rst deleted file mode 100644 index c36f47f4f2d14bc40a31587074120c78e70fcd15..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_max_size.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_client_pool_max_size - -mongoc_client_pool_max_size() -============================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_pool_max_size (mongoc_client_pool_t *pool, - uint32_t max_pool_size); - -This function sets the maximum number of pooled connections available from a :symbol:`mongoc_client_pool_t`. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. -* ``max_pool_size``: The maximum number of connections which shall be available from the pool. - -.. include:: includes/mongoc_client_pool_thread_safe.txt diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_min_size.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_min_size.rst deleted file mode 100644 index 90908ed33fbcb94e9cc3ba6d47f2385d92d2a24d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_min_size.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_client_pool_min_size - -mongoc_client_pool_min_size() -============================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_pool_min_size (mongoc_client_pool_t *pool, - uint32_t min_pool_size) - BSON_GNUC_DEPRECATED; - -This function sets the *maximum* number of idle clients to be kept in the pool. Any idle clients in excess of the maximum are destroyed. This function is deprecated because its behavior does not match what developers expect from a "minimum pool size", and its actual behavior is likely to hurt performance. - -Applications should not call this function, they should instead accept the default behavior, which is to keep all idle clients that are pushed into the pool. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. -* ``min_pool_size``: The number of idle clients to keep in the pool. - -.. include:: includes/mongoc_client_pool_thread_safe.txt - -Subsequent calls to :symbol:`mongoc_client_pool_push` respect the new minimum size, and close the least recently used :symbol:`mongoc_client_t` if the minimum size is exceeded. diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_new.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_new.rst deleted file mode 100644 index 8605a7ccaea51dd1fafe3f588e1c4e85e63617f7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_new.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_client_pool_new - -mongoc_client_pool_new() -======================== - -Synopsis --------- - -.. code-block:: c - - mongoc_client_pool_t * - mongoc_client_pool_new (const mongoc_uri_t *uri); - -This function creates a new :symbol:`mongoc_client_pool_t` using the :symbol:`mongoc_uri_t` provided. - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Returns -------- - -A newly allocated :symbol:`mongoc_client_pool_t` that should be freed with :symbol:`mongoc_client_pool_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_pop.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_pop.rst deleted file mode 100644 index 4586baef6221676f83f60b41d0702a8810b3be6d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_pop.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_client_pool_pop - -mongoc_client_pool_pop() -======================== - -Synopsis --------- - -.. code-block:: c - - mongoc_client_t * - mongoc_client_pool_pop (mongoc_client_pool_t *pool); - -Retrieve a :symbol:`mongoc_client_t` from the client pool, or create one. The total number of clients that can be created from this pool is limited by the URI option "maxPoolSize", default 100. If this number of clients has been created and all are in use, ``mongoc_client_pool_pop`` blocks until another thread returns a client with :symbol:`mongoc_client_pool_push`. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. - -Returns -------- - -A :symbol:`mongoc_client_t`. - -.. include:: includes/mongoc_client_pool_thread_safe.txt diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_push.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_push.rst deleted file mode 100644 index baf8f67a6a92e02f530084a7ce05534a61945ff5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_push.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_client_pool_push - -mongoc_client_pool_push() -========================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client); - -This function returns a :symbol:`mongoc_client_t` back to the client pool. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. -* ``client``: A :symbol:`mongoc_client_t`. - -.. include:: includes/mongoc_client_pool_thread_safe.txt diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_apm_callbacks.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_apm_callbacks.rst deleted file mode 100644 index 6cdfd02c9f697c6c26ff2fc1e1ad8f8e35ec64fe..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_apm_callbacks.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_client_pool_set_apm_callbacks - -mongoc_client_pool_set_apm_callbacks() -====================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_pool_set_apm_callbacks (mongoc_client_pool_t *pool, - mongoc_apm_callbacks_t *callbacks, - void *context); - -Register a set of callbacks to receive Application Performance Monitoring events. - -The callbacks are copied by the pool and may be destroyed at any time after. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. -* ``callbacks``: A :symbol:`mongoc_apm_callbacks_t`. -* ``context``: Optional pointer to include with each event notification. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and logs an error. - -.. include:: includes/mongoc_client_pool_call_once.txt - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_appname.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_appname.rst deleted file mode 100644 index 8c5126ace6830116590079981f446997aa510263..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_appname.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_client_pool_set_appname - -mongoc_client_pool_set_appname() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_pool_set_appname (mongoc_client_pool_t *pool, const char *appname) - -This function is identical to :symbol:`mongoc_client_set_appname()` except for client pools. - -Also note that :symbol:`mongoc_client_set_appname()` cannot be called on a client retrieved from a client pool. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. -* ``appname``: The application name, of length at most ``MONGOC_HANDSHAKE_APPNAME_MAX``. - -Returns -------- - -Returns true if appname was set. If appname is too long, returns false and logs an error. - -.. include:: includes/mongoc_client_pool_call_once.txt diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_error_api.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_error_api.rst deleted file mode 100644 index 1111bd41026d9d1f134b14382e43476ff3080e4b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_error_api.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_client_pool_set_error_api - -mongoc_client_pool_set_error_api() -================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_pool_set_error_api (mongoc_client_pool_t *client, - int32_t version); - -Configure how the C Driver reports errors. See :ref:`Setting the Error API Version <errors_error_api_version>`. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. -* ``version``: The version of the error API, either ``MONGOC_ERROR_API_VERSION_LEGACY`` or ``MONGOC_ERROR_API_VERSION_2``. - -Returns -------- - -Returns true if the error API version was set, or logs an error message and returns false if ``version`` is invalid. - -.. include:: includes/mongoc_client_pool_call_once.txt diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_ssl_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_ssl_opts.rst deleted file mode 100644 index e156e55580cc0137a9fc82e1f644218d88df5d52..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_set_ssl_opts.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_client_pool_set_ssl_opts - -mongoc_client_pool_set_ssl_opts() -================================= - -Synopsis --------- - -.. code-block:: c - - #ifdef MONGOC_ENABLE_SSL - void - mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool, - const mongoc_ssl_opt_t *opts); - #endif - -This function is identical to :symbol:`mongoc_client_set_ssl_opts()` except for -client pools. It ensures that all clients retrieved from -:symbol:`mongoc_client_pool_pop()` or :symbol:`mongoc_client_pool_try_pop()` -are configured with the same SSL settings. - -The ``mongoc_ssl_opt_t`` struct is copied by the pool along with the strings -it points to (``pem_file``, ``pem_pwd``, ``ca_file``, ``ca_dir``, and -``crl_file``) so they don't have to remain valid after the call to -``mongoc_client_pool_set_ssl_opts``. - -A call to ``mongoc_client_pool_set_ssl_opts`` overrides all SSL options set -through the connection string with which the ``mongoc_client_pool_t`` was -constructed. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. -* ``opts``: A :symbol:`mongoc_ssl_opt_t`. - -.. include:: includes/mongoc_client_pool_call_once.txt - -Availability ------------- - -This feature requires that the MongoDB C driver was compiled with ``-DENABLE_SSL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_t.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_t.rst deleted file mode 100644 index e75b21a6c82bdf47d3efc2a379dc3cc36ead432e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_t.rst +++ /dev/null @@ -1,44 +0,0 @@ -:man_page: mongoc_client_pool_t - -mongoc_client_pool_t -==================== - -A connection pool for multi-threaded programs. See :doc:`connection-pooling`. - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_client_pool_t mongoc_client_pool_t - -``mongoc_client_pool_t`` is the basis for multi-threading in the MongoDB C driver. Since :symbol:`mongoc_client_t` structures are not thread-safe, this structure is used to retrieve a new :symbol:`mongoc_client_t` for a given thread. This structure *is thread-safe*, except for its destructor method, :symbol:`mongoc_client_pool_destroy`, which *is not thread-safe* and must only be called from one thread. - -Example -------- - -.. literalinclude:: ../examples/example-pool.c - :language: c - :caption: example-pool.c - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_client_pool_destroy - mongoc_client_pool_max_size - mongoc_client_pool_min_size - mongoc_client_pool_new - mongoc_client_pool_pop - mongoc_client_pool_push - mongoc_client_pool_set_apm_callbacks - mongoc_client_pool_set_appname - mongoc_client_pool_set_error_api - mongoc_client_pool_set_ssl_opts - mongoc_client_pool_try_pop - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_pool_try_pop.rst b/lib/mongoc/libmongoc/doc/mongoc_client_pool_try_pop.rst deleted file mode 100644 index 98ae3d7ac2dcdc5a7856e8be550c0e730b1a3a9c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_pool_try_pop.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_client_pool_try_pop - -mongoc_client_pool_try_pop() -============================ - -Synopsis --------- - -.. code-block:: c - - mongoc_client_t * - mongoc_client_pool_try_pop (mongoc_client_pool_t *pool); - -This function is identical to :symbol:`mongoc_client_pool_pop()` except it will return ``NULL`` instead of blocking for a client to become available. - -Parameters ----------- - -* ``pool``: A :symbol:`mongoc_client_pool_t`. - -Returns -------- - -A :symbol:`mongoc_client_t` if one is immediately available, otherwise ``NULL``. - -.. include:: includes/mongoc_client_pool_thread_safe.txt diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_read_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_read_command_with_opts.rst deleted file mode 100644 index 3b5de88920209fa95a14a0c524fae6e8dcfd3aa4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_read_command_with_opts.rst +++ /dev/null @@ -1,65 +0,0 @@ -:man_page: mongoc_client_read_command_with_opts - -mongoc_client_read_command_with_opts() -====================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_read_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic that is specific to commands that read, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_client_command_simple`. - -.. |opts-source| replace:: ``client`` - -.. include:: includes/read-cmd-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -.. |generic-cmd| replace:: :symbol:`mongoc_client_command_with_opts` -.. include:: includes/retryable-read.txt -.. include:: includes/retryable-read-command.txt - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db_name``: The name of the database to run the command on. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -.. _mongoc_client_read_command_with_opts_example: - -Example -------- - -.. literalinclude:: ../examples/example-command-with-opts.c - :language: c - :caption: example-command-with-opts.c - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_read_write_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_read_write_command_with_opts.rst deleted file mode 100644 index 2c5c9ef9e1a007008e60eac4b52dd9296ee762a1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_read_write_command_with_opts.rst +++ /dev/null @@ -1,62 +0,0 @@ -:man_page: mongoc_client_read_write_command_with_opts - -mongoc_client_read_write_command_with_opts() -============================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_read_write_command_with_opts ( - mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* UNUSED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic for commands that both read and write, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_client_command_simple`. - -.. |opts-source| replace:: ``client`` - -.. include:: includes/read-write-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -(The :symbol:`mongoc_read_prefs_t` parameter was included by mistake when this function was introduced in libmongoc 1.5. A command that writes must not obey a read preference.) - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db_name``: The name of the database to run the command on. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: Ignored. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_reset.rst b/lib/mongoc/libmongoc/doc/mongoc_client_reset.rst deleted file mode 100644 index a0872aa44d9fa68966f3eabffbe902ae8bebdfb4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_reset.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_client_reset - -mongoc_client_reset() -===================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_reset (mongoc_client_t *client); - -Call this method in the child after forking. - -This method causes the client to clear its session pool without sending endSessions. It also increments an internal generation counter on the given client. After this method is called, cursors from previous generations will not issue a killCursors command when they are destroyed. Client sessions from previous generations cannot be used and should be destroyed. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_select_server.rst b/lib/mongoc/libmongoc/doc/mongoc_client_select_server.rst deleted file mode 100644 index b3c81409da5dba0b480083d4d0183eb23a654d17..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_select_server.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_client_select_server - -mongoc_client_select_server() -============================= - -Synopsis --------- - -.. code-block:: c - - mongoc_server_description_t * - mongoc_client_select_server (mongoc_client_t *client, - bool for_writes, - const mongoc_read_prefs_t *prefs, - bson_error_t *error); - -Choose a server for an operation, according to the logic described in the Server Selection Spec. - -Use this function only for building a language driver that wraps the C Driver. When writing applications in C, higher-level functions automatically select a suitable server. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``for_writes``: Whether to choose a server suitable for writes or reads. -* ``prefs``: An optional :symbol:`mongoc_read_prefs_t`. If ``for_writes`` is true, ``prefs`` must be NULL. Otherwise, use ``prefs`` to customize server selection, or pass NULL to use the read preference configured on the client. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Returns -------- - -A :symbol:`mongoc_server_description_t` that must be freed with :symbol:`mongoc_server_description_destroy`. If no suitable server is found, returns NULL and ``error`` is filled out. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_abort_transaction.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_abort_transaction.rst deleted file mode 100644 index 2380a5cf4a103f2274fa1abc39b2e0670b45c40e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_abort_transaction.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_client_session_abort_transaction - -mongoc_client_session_abort_transaction() -========================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_session_abort_transaction (mongoc_client_session_t *session, - bson_error_t *error); - - -Abort a multi-document transaction. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Return ------- - -Returns true if the transaction was aborted. Returns ``false`` and sets ``error`` if there are invalid arguments, such as a session with no transaction in progress. Network or server errors are ignored. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_advance_cluster_time.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_advance_cluster_time.rst deleted file mode 100644 index 5cb630c7c31a65e53a6be268cbc41f1c505d7390..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_advance_cluster_time.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_client_session_advance_cluster_time - -mongoc_client_session_advance_cluster_time() -============================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_session_advance_cluster_time (mongoc_client_session_t *session, - const bson_t *cluster_time); - -Advance the cluster time for a session. Has an effect only if the new cluster time is greater than the session's current cluster time. - -Use :symbol:`mongoc_client_session_advance_operation_time` and :symbol:`mongoc_client_session_advance_cluster_time` to copy the operationTime and clusterTime from another session, ensuring subsequent operations in this session are causally consistent with the last operation in the other session - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. -* ``cluster_time``: The session's new cluster time, as a :symbol:`bson:bson_t` like `{"cluster time": <timestamp>}`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_advance_operation_time.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_advance_operation_time.rst deleted file mode 100644 index 8af35c6247ce7e0957dc719fde6e2f9cac28eb44..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_advance_operation_time.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_client_session_advance_operation_time - -mongoc_client_session_advance_operation_time() -============================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_session_advance_operation_time (mongoc_client_session_t *session, - uint32_t timestamp, - uint32_t increment); - -Advance the session's operation time, expressed as a BSON Timestamp with timestamp and increment components. Has an effect only if the new operation time is greater than the session's current operation time. - -Use :symbol:`mongoc_client_session_advance_operation_time` and :symbol:`mongoc_client_session_advance_cluster_time` to copy the operationTime and clusterTime from another session, ensuring subsequent operations in this session are causally consistent with the last operation in the other session - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. -* ``timestamp``: The new operationTime's timestamp component. -* ``increment``: The new operationTime's increment component. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_append.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_append.rst deleted file mode 100644 index 90ac20a1ea79639367f5a48964490b9b0b6a5ee7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_append.rst +++ /dev/null @@ -1,39 +0,0 @@ -:man_page: mongoc_client_session_append - -mongoc_client_session_append() -============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_session_append (const mongoc_client_session_t *client_session, - bson_t *opts, - bson_error_t *error); - -Parameters ----------- - -* ``client_session``: A pointer to a :symbol:`mongoc_client_session_t`. -* ``opts``: A pointer to a :symbol:`bson:bson_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function appends a logical session id to command options. Use it to configure a session for any function that takes an options document, such as :symbol:`mongoc_client_write_command_with_opts`. - -It is an error to use a session for unacknowledged writes. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and fills out ``error``. - -Example -------- - -See the example code for :symbol:`mongoc_client_session_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_commit_transaction.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_commit_transaction.rst deleted file mode 100644 index aeef767343b7acdd36ae5971b4ca3f7343e9c3c7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_commit_transaction.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_client_session_commit_transaction - -mongoc_client_session_commit_transaction() -========================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_session_commit_transaction (mongoc_client_session_t *session, - bson_t *reply, - bson_error_t *error); - - -Commit a multi-document transaction. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. -* ``reply``: An optional uninitialized :symbol:`bson:bson_t` to receive the server reply, or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Return ------- - -Returns true if the transaction was committed. Returns ``false`` and sets ``error`` if there are invalid arguments, such as a session with no transaction in progress, or if there is a server or network error. - -If a ``reply`` is supplied, it is always initialized and must be freed with :symbol:`bson:bson_destroy`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_destroy.rst deleted file mode 100644 index 57b0da5ecdb0bc6fb5f09febf6afeceb2ac288d7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_destroy.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_client_session_destroy - -mongoc_client_session_destroy() -=============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_session_destroy (mongoc_client_session_t *session); - -End a session, returning its session id to the pool, and free all client resources associated with the session. If a multi-document transaction is in progress, abort it. Does nothing if ``session`` is NULL. - -See the example code for :symbol:`mongoc_client_session_t`. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_client.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_get_client.rst deleted file mode 100644 index 64e4e8429b2bbf939cb8ab0b214552edbb69773d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_client.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_client_session_get_client - -mongoc_client_session_get_client() -================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_client_t * - mongoc_client_session_get_client (const mongoc_client_session_t *session); - -Returns the :symbol:`mongoc_client_t` from which this session was created with :symbol:`mongoc_client_start_session()`. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_cluster_time.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_get_cluster_time.rst deleted file mode 100644 index ce39bde55aba6e1841764cd50db602537c180ad5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_cluster_time.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_client_session_get_cluster_time - -mongoc_client_session_get_cluster_time() -======================================== - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_client_session_get_cluster_time (const mongoc_client_session_t *session); - -Get the session's clusterTime, as a BSON document. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -Returns -------- - -A :symbol:`bson:bson_t` you must not modify or free. If the session has not been used for any operation and you have not called :symbol:`mongoc_client_session_advance_cluster_time`, then the returned value is NULL. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_lsid.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_get_lsid.rst deleted file mode 100644 index 18a08ec83cc9d4d417a6b9d720a47f43b1e67635..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_lsid.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_client_session_get_lsid - -mongoc_client_session_get_lsid() -================================ - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_client_session_get_lsid (mongoc_client_session_t *session); - -Get the server-side "logical session ID" associated with this :symbol:`mongoc_client_session_t`, as a BSON document. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -Returns -------- - -A :symbol:`bson:bson_t` you must not modify or free. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_operation_time.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_get_operation_time.rst deleted file mode 100644 index 9ae63142a19b20223fb45b69f6b655e3516c1a2b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_operation_time.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_client_session_get_operation_time - -mongoc_client_session_get_operation_time() -========================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_session_get_operation_time (const mongoc_client_session_t *session, - uint32_t *timestamp, - uint32_t *increment); - -Get the session's operationTime, expressed as a BSON Timestamp with timestamp and increment components. If the session has not been used for any operations, the timestamp and increment are 0. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. -* ``timestamp``: A pointer to a ``uint32_t`` to receive the timestamp component. -* ``increment``: A pointer to a ``uint32_t`` to receive the increment component. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_get_opts.rst deleted file mode 100644 index db4825411399da8976499f6d2595861bd6475fbd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_opts.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_client_session_get_opts - -mongoc_client_session_get_opts() -================================ - -Synopsis --------- - -.. code-block:: c - - const mongoc_session_opt_t * - mongoc_client_session_get_opts (const mongoc_client_session_t *session); - -Get a reference to the :symbol:`mongoc_session_opt_t` with which this session was configured. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -Returns -------- - -A :symbol:`mongoc_session_opt_t` you must not modify or free. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_server_id.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_get_server_id.rst deleted file mode 100644 index a18a0de55a37d11037b146bb0b0eb0a50ab25a23..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_server_id.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_client_session_get_server_id - -mongoc_client_session_get_server_id() -===================================== - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_client_session_get_server_id (const mongoc_client_session_t *session); - -Get the "server ID" of the ``mongos`` this :symbol:`mongoc_client_session_t` is pinned to. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -Returns -------- - -A server ID or ``0`` if this :symbol:`mongoc_client_session_t` is not pinned. - -.. only:: html - - .. taglist:: See Also: - :tags: session - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_transaction_state.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_get_transaction_state.rst deleted file mode 100644 index b1430e208b28b780661df03fc5c1150d8f6ff133..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_get_transaction_state.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_client_session_get_transaction_state - -mongoc_client_session_get_transaction_state() -============================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_transaction_state_t - mongoc_client_session_get_transaction_state (const mongoc_client_session_t *session); - -Returns the current transaction state for this session. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -Return ------- - -Returns a :symbol:`mongoc_transaction_state_t` that represents the current transaction state. diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_in_transaction.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_in_transaction.rst deleted file mode 100644 index 858f30bc4046194153f4ae7b528058f160f07382..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_in_transaction.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_client_session_in_transaction - -mongoc_client_session_in_transaction() -====================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_session_in_transaction (const mongoc_client_session_t *session); - -Check whether a multi-document transaction is in progress for this session. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -Return ------- - -Returns true if a transaction was started and has not been committed or aborted, otherwise ``false``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_start_transaction.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_start_transaction.rst deleted file mode 100644 index 99a72e42ea781c3fc5480b924711b7d949bd27fe..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_start_transaction.rst +++ /dev/null @@ -1,47 +0,0 @@ -:man_page: mongoc_client_session_start_transaction - -mongoc_client_session_start_transaction() -========================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_session_start_transaction (mongoc_client_session_t *session, - const mongoc_transaction_opt_t *opts, - bson_error_t *error); - - -Start a multi-document transaction for all following operations in this session. Any options provided in ``opts`` override options passed to :symbol:`mongoc_session_opts_set_default_transaction_opts`, and options inherited from the :symbol:`mongoc_client_t`. The ``opts`` argument is copied and can be freed after calling this function. - -The transaction must be completed with :symbol:`mongoc_client_session_commit_transaction` or :symbol:`mongoc_client_session_abort_transaction`. An in-progress transaction is automatically aborted by :symbol:`mongoc_client_session_destroy`. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. -* ``opts``: A :symbol:`mongoc_transaction_opt_t` or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Return ------- - -Returns true if the transaction was started. Returns ``false`` and sets ``error`` if there are invalid arguments, such as a session with a transaction already in progress. - -.. _mongoc_client_session_start_transaction_example: - -Example -------- - -The following example demonstrates how to use :ref:`error labels <error_labels>` to reliably execute a multi-document transaction despite network errors and other transient failures. - -.. literalinclude:: ../examples/example-transaction.c - :language: c - :caption: example-transaction.c - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_t.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_t.rst deleted file mode 100644 index 924e56d584a7604241af5b5557608c9346baf796..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_t.rst +++ /dev/null @@ -1,45 +0,0 @@ -:man_page: mongoc_client_session_t -:tags: session - -mongoc_client_session_t -======================= - -Use a session for a sequence of operations, optionally with causal consistency. See `the MongoDB Manual Entry for Causal Consistency <http://dochub.mongodb.org/core/causal-consistency>`_. - -Synopsis --------- - -.. include:: includes/session-lifecycle.txt - -Example -------- - -.. literalinclude:: ../examples/example-session.c - :language: c - :caption: example-session.c - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_client_session_start_transaction - mongoc_client_session_in_transaction - mongoc_client_session_get_transaction_state - mongoc_client_session_commit_transaction - mongoc_client_session_abort_transaction - mongoc_client_session_advance_cluster_time - mongoc_client_session_advance_operation_time - mongoc_client_session_with_transaction - mongoc_client_session_append - mongoc_client_session_get_client - mongoc_client_session_get_cluster_time - mongoc_client_session_get_operation_time - mongoc_client_session_get_opts - mongoc_client_session_get_lsid - mongoc_client_session_get_server_id - mongoc_client_session_destroy diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_with_transaction.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_with_transaction.rst deleted file mode 100644 index cd72991da75126fdfc78a159e0a38974c018a912..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_with_transaction.rst +++ /dev/null @@ -1,47 +0,0 @@ -:man_page: mongoc_client_session_with_transaction - -mongoc_client_session_with_transaction() -======================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_session_with_transaction (mongoc_client_session_t *session, - mongoc_client_session_with_transaction_cb_t cb, - const mongoc_transaction_opt_t *opts, - void *ctx, - bson_t *reply, - bson_error_t *error); - -This method will start a new transaction on ``session``, run ``cb``, and then commit the transaction. If it cannot commit the transaction, the entire sequence may be retried, and ``cb`` may be run multiple times. ``ctx`` will be passed to ``cb`` each time it is called. - -This method has an internal time limit of 120 seconds, and will retry until that time limit is reached. This timeout is not configurable. - -``cb`` should not attempt to start new transactions, but should simply run operations meant to be contained within a transaction. The ``cb`` does not need to commit transactions; this is handled by the :symbol:`mongoc_client_session_with_transaction`. If ``cb`` does commit or abort a transaction, however, this method will return without taking further action. - -The parameter ``reply`` is initialized even upon failure to simplify memory management. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. -* ``cb``: A :symbol:`mongoc_client_session_with_transaction_cb_t` callback, which will run inside of a new transaction on the session. See example below. -* ``opts``: An optional :symbol:`mongoc_transaction_opt_t`. -* ``ctx``: A ``void*``. This user-provided data will be passed to ``cb``. -* ``reply``: An optional location to initialize a :symbol:`bson_t` or ``NULL``. This should be on the stack. -* ``error``: An optional location for a :symbol:`bson_error_t` or ``NULL``. - -Return ------- - -Returns ``true`` if the transaction was completed successfully. Otherwise, returns ``false`` in case of failure. In cases of failure ``error`` will also be set, except if the passed-in ``cb`` fails without setting ``error``. If a non-NULL ``reply`` is passed in, ``reply`` will be set to the value of the last server response, except if the passed-in ``cb`` fails without setting a ``reply``. - -Example -------- - -.. literalinclude:: ../examples/example-with-transaction-cb.c - :language: c - :caption: Use with_transaction() to run a callback within a transaction diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_session_with_transaction_cb_t.rst b/lib/mongoc/libmongoc/doc/mongoc_client_session_with_transaction_cb_t.rst deleted file mode 100644 index 198b6ee708aa55e2175dedc19f0eee729b7b9b54..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_session_with_transaction_cb_t.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_client_session_with_transaction_cb_t - -mongoc_client_session_with_transaction_cb_t -=========================================== - -Synopsis --------- - -.. code-block:: c - - typedef bool (*mongoc_client_session_with_transaction_cb_t) ( - mongoc_client_session_t *session, - void *ctx, - bson_t **reply, - bson_error_t *error); - -Provide this callback to :symbol:`mongoc_client_session_with_transaction`. The callback should run a sequence of operations meant to be contained within a transaction. The callback should not attempt to start or commit transactions. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. -* ``ctx``: A ``void*`` set to the the user-provided ``ctx`` passed to :symbol:`mongoc_client_session_with_transaction`. -* ``reply``: An optional location for a :symbol:`bson_t` or ``NULL``. The callback should set this if it runs any operations against the server and receives replies. -* ``error``: A :symbol:`bson_error_t`. The callback should set this if it receives any errors while running operations against the server. - -Return ------- - -Returns ``true`` for success and ``false`` on failure. If ``cb`` returns ``false`` then it should also set ``error``. - -See Also --------- - -:symbol:`mongoc_client_session_with_transaction` diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_set_apm_callbacks.rst b/lib/mongoc/libmongoc/doc/mongoc_client_set_apm_callbacks.rst deleted file mode 100644 index 253d94c576a149b4f22bb174cbf46834bda4231d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_set_apm_callbacks.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_client_set_apm_callbacks - -mongoc_client_set_apm_callbacks() -================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_set_apm_callbacks (mongoc_client_t *client, - mongoc_apm_callbacks_t *callbacks, - void *context); - -Register a set of callbacks to receive Application Performance Monitoring events. - -The callbacks are copied by the client and may be destroyed at any time after. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``callbacks``: Optional :symbol:`mongoc_apm_callbacks_t`. Pass NULL to clear all callbacks. -* ``context``: Optional pointer to include with each event notification. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and logs an error. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_set_appname.rst b/lib/mongoc/libmongoc/doc/mongoc_client_set_appname.rst deleted file mode 100644 index 85818c22bf838ed671a25b0e02eb5554de644b3b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_set_appname.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_client_set_appname - -mongoc_client_set_appname() -=========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_set_appname (mongoc_client_t *client, const char *appname) - -Sets the application name for this client. This string, along with other internal driver details, is sent to the server as part of the initial connection handshake (`"isMaster" <https://docs.mongodb.org/manual/reference/command/isMaster/>`_). - -``appname`` is copied, and doesn't have to remain valid after the call to ``mongoc_client_set_appname()``. - -This function will log an error and return false in the following cases: - -* ``appname`` is longer than ``MONGOC_HANDSHAKE_APPNAME_MAX`` -* ``client`` has already initiated a handshake -* ``client`` is from a :symbol:`mongoc_client_pool_t` - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``appname``: The application name, of length at most ``MONGOC_HANDSHAKE_APPNAME_MAX``. - -Returns -------- - -true if the appname is set successfully. Otherwise, false. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_set_error_api.rst b/lib/mongoc/libmongoc/doc/mongoc_client_set_error_api.rst deleted file mode 100644 index 96b381c1b99f794bd89a5b654d107e65f1727e96..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_set_error_api.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_client_set_error_api - -mongoc_client_set_error_api() -============================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_set_error_api (mongoc_client_t *client, int32_t version); - -Configure how the C Driver reports errors. See :ref:`Setting the Error API Version <errors_error_api_version>`. - -Do not use this function with pooled clients, see :symbol:`mongoc_client_pool_set_error_api`. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``version``: The version of the error API, either ``MONGOC_ERROR_API_VERSION_LEGACY`` or ``MONGOC_ERROR_API_VERSION_2``. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and logs an error. diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_set_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_client_set_read_concern.rst deleted file mode 100644 index 2f62f5136c7124852c8707e3b186faf903f666bd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_set_read_concern.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_client_set_read_concern - -mongoc_client_set_read_concern() -================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_set_read_concern (mongoc_client_t *client, - const mongoc_read_concern_t *read_concern); - -Sets the read concern for the client. This only affects future operations, collections, and databases inheriting from ``client``. - -The default read concern is MONGOC_READ_CONCERN_LEVEL_LOCAL. This is the correct read concern for the great majority of applications. - -It is a programming error to call this function on a client from a :symbol:`mongoc_client_pool_t`. For pooled clients, set the read concern with the :ref:`MongoDB URI <mongoc_uri_t_read_concern_options>` instead. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``read_concern``: A :symbol:`mongoc_read_concern_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_set_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_client_set_read_prefs.rst deleted file mode 100644 index 3ae38a67b8582c38f22c5ce2844145c9626db803..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_set_read_prefs.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_client_set_read_prefs - -mongoc_client_set_read_prefs() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_set_read_prefs (mongoc_client_t *client, - const mongoc_read_prefs_t *read_prefs); - -Sets the default read preferences to use with future operations upon ``client``. - -The global default is to read from the replica set primary. - -It is a programming error to call this function on a client from a :symbol:`mongoc_client_pool_t`. For pooled clients, set the read preferences with the :ref:`MongoDB URI <mongoc_uri_t_read_prefs_options>` instead. - -Please see the MongoDB website for a description of `Read Preferences <http://docs.mongodb.org/manual/core/read-preference/>`_. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_set_ssl_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_set_ssl_opts.rst deleted file mode 100644 index e5510fb5019beb369c637e83fa1d48bd49dbd334..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_set_ssl_opts.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_client_set_ssl_opts - -mongoc_client_set_ssl_opts() -============================ - -Synopsis --------- - -.. code-block:: c - - #ifdef MONGOC_ENABLE_SSL - void - mongoc_client_set_ssl_opts (mongoc_client_t *client, - const mongoc_ssl_opt_t *opts); - #endif - -Sets the SSL options to use when connecting to SSL enabled MongoDB servers. - -The ``mongoc_ssl_opt_t`` struct is copied by the client along with the strings -it points to (``pem_file``, ``pem_pwd``, ``ca_file``, ``ca_dir``, and -``crl_file``) so they don't have to remain valid after the call to -``mongoc_client_set_ssl_opts``. - -A call to ``mongoc_client_set_ssl_opts`` overrides all SSL options set through -the connection string with which the ``mongoc_client_t`` was constructed. - -It is a programming error to call this function on a client from a -:symbol:`mongoc_client_pool_t`. Instead, call -:symbol:`mongoc_client_pool_set_ssl_opts` on the pool before popping any -clients. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``opts``: A :symbol:`mongoc_ssl_opt_t`. - -Availability ------------- - -This feature requires that the MongoDB C driver was compiled with ``-DENABLE_SSL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_set_stream_initiator.rst b/lib/mongoc/libmongoc/doc/mongoc_client_set_stream_initiator.rst deleted file mode 100644 index 15bdbf86583c74eea4529ba85c0f564acd5d8d49..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_set_stream_initiator.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_client_set_stream_initiator - -mongoc_client_set_stream_initiator() -==================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_set_stream_initiator (mongoc_client_t *client, - mongoc_stream_initiator_t initiator, - void *user_data); - -The :symbol:`mongoc_client_set_stream_initiator()` function shall associate a given :symbol:`mongoc_client_t` with a new stream initiator. This will completely replace the default transport (buffered TCP, possibly with TLS). The ``initiator`` should fulfill the :symbol:`mongoc_stream_t` contract. ``user_data`` is passed through to the ``initiator`` callback and may be used for whatever run time customization is necessary. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``initiator``: A :symbol:`mongoc_stream_initiator_t <mongoc_client_t>`. -* ``user_data``: User supplied pointer for callback function. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_set_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_client_set_write_concern.rst deleted file mode 100644 index df822301cdf47012c611f1b9dec81b5bb7abf84a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_set_write_concern.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_client_set_write_concern - -mongoc_client_set_write_concern() -================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_client_set_write_concern (mongoc_client_t *client, - const mongoc_write_concern_t *write_concern); - -Sets the write concern for the client. This only affects future operations, collections, and databases inheriting from ``client``. - -The default write concern is MONGOC_WRITE_CONCERN_W_DEFAULT: the driver blocks awaiting basic acknowledgement of write operations from MongoDB. This is the correct write concern for the great majority of applications. - -It is a programming error to call this function on a client from a :symbol:`mongoc_client_pool_t`. For pooled clients, set the write concern with the :ref:`MongoDB URI <mongoc_uri_t_write_concern_options>` instead. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_start_session.rst b/lib/mongoc/libmongoc/doc/mongoc_client_start_session.rst deleted file mode 100644 index b49cf8e495df67aa6cce78025998b88100fe6f5a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_start_session.rst +++ /dev/null @@ -1,40 +0,0 @@ -:man_page: mongoc_client_start_session - -mongoc_client_start_session() -============================= - -Synopsis --------- - -.. code-block:: c - - mongoc_client_session_t * - mongoc_client_start_session (mongoc_client_t *client, - mongoc_session_opt_t *opts, - bson_error_t *error) - -Create a session for a sequence of operations. - -.. include:: includes/session-lifecycle.txt - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``opts``: An optional :symbol:`mongoc_session_opt_t`. -* ``error``: A :symbol:`bson:bson_error_t`. - -Returns -------- - -If successful, this function returns a newly allocated :symbol:`mongoc_client_session_t` that should be freed with :symbol:`mongoc_client_session_destroy()` when no longer in use. On error, returns NULL and sets ``error``. - -Errors ------- - -This function can fail if the driver is not built with crypto support, if ``opts`` is misconfigured, or if the session is configured with options that the server does not support. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_t.rst b/lib/mongoc/libmongoc/doc/mongoc_client_t.rst deleted file mode 100644 index fec929c23374a4823eb8d9fc537b5e41383eae66..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_t.rst +++ /dev/null @@ -1,90 +0,0 @@ -:man_page: mongoc_client_t - -mongoc_client_t -=============== - -A single-threaded MongoDB connection. See :doc:`connection-pooling`. - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_client_t mongoc_client_t; - - typedef mongoc_stream_t *(*mongoc_stream_initiator_t) ( - const mongoc_uri_t *uri, - const mongoc_host_list_t *host, - void *user_data, - bson_error_t *error); - -``mongoc_client_t`` is an opaque type that provides access to a MongoDB server, -replica set, or sharded cluster. It maintains management of underlying sockets -and routing to individual nodes based on :symbol:`mongoc_read_prefs_t` or :symbol:`mongoc_write_concern_t`. - -Streams -------- - -The underlying transport for a given client can be customized, wrapped or replaced by any implementation that fulfills :symbol:`mongoc_stream_t`. A custom transport can be set with :symbol:`mongoc_client_set_stream_initiator()`. - -Thread Safety -------------- - -``mongoc_client_t`` is *NOT* thread-safe and should only be used from one thread at a time. When used in multi-threaded scenarios, it is recommended that you use the thread-safe :symbol:`mongoc_client_pool_t` to retrieve a ``mongoc_client_t`` for your thread. - -Example -------- - -.. literalinclude:: ../examples/example-client.c - :language: c - :caption: example-client.c - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_client_command - mongoc_client_command_simple - mongoc_client_command_simple_with_server_id - mongoc_client_command_with_opts - mongoc_client_destroy - mongoc_client_enable_auto_encryption - mongoc_client_find_databases_with_opts - mongoc_client_get_collection - mongoc_client_get_database - mongoc_client_get_database_names - mongoc_client_get_database_names_with_opts - mongoc_client_get_default_database - mongoc_client_get_gridfs - mongoc_client_get_max_bson_size - mongoc_client_get_max_message_size - mongoc_client_get_read_concern - mongoc_client_get_read_prefs - mongoc_client_get_server_description - mongoc_client_get_server_descriptions - mongoc_client_get_server_status - mongoc_client_get_uri - mongoc_client_get_write_concern - mongoc_client_new - mongoc_client_new_from_uri - mongoc_client_read_command_with_opts - mongoc_client_read_write_command_with_opts - mongoc_client_reset - mongoc_client_select_server - mongoc_client_set_apm_callbacks - mongoc_client_set_appname - mongoc_client_set_error_api - mongoc_client_set_read_concern - mongoc_client_set_read_prefs - mongoc_client_set_ssl_opts - mongoc_client_set_stream_initiator - mongoc_client_set_write_concern - mongoc_client_start_session - mongoc_client_watch - mongoc_client_write_command_with_opts - diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_watch.rst b/lib/mongoc/libmongoc/doc/mongoc_client_watch.rst deleted file mode 100644 index cd97569a943ed0d5549ff266a97d6853442d9d09..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_watch.rst +++ /dev/null @@ -1,50 +0,0 @@ -:man_page: mongoc_client_watch - -mongoc_client_watch() -===================== - -Synopsis --------- - -.. code-block:: c - - mongoc_change_stream_t* - mongoc_client_watch (mongoc_client_t *client, - const bson_t *pipeline, - const bson_t *opts); - -A helper function to create a change stream. It is preferred to call this -function over using a raw aggregation to create a change stream. - -This function uses the read preference and read concern of the client. If -the change stream needs to re-establish connection, the same read preference -will be used. This may happen if the change stream encounters a resumable error. - -.. warning:: - - A change stream is only supported with majority read concern. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``db``: A :symbol:`mongoc_client_t` specifying the client which the change stream listens to. -* ``pipeline``: A :symbol:`bson:bson_t` representing an aggregation pipeline appended to the change stream. This may be an empty document. -* ``opts``: A :symbol:`bson:bson_t` containing change stream options. - -.. include:: includes/change-stream-opts.txt - -Returns -------- -A newly allocated :symbol:`mongoc_change_stream_t` which must be freed with -:symbol:`mongoc_change_stream_destroy` when no longer in use. The returned -:symbol:`mongoc_change_stream_t` is never ``NULL``. If there is an error, it can -be retrieved with :symbol:`mongoc_change_stream_error_document`, and subsequent -calls to :symbol:`mongoc_change_stream_next` will return ``false``. - -See Also --------- -:doc:`mongoc_database_watch` - -:doc:`mongoc_collection_watch` diff --git a/lib/mongoc/libmongoc/doc/mongoc_client_write_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_client_write_command_with_opts.rst deleted file mode 100644 index e1c4d6a5c1abcf1dca0e194322e31d51bc51fc6c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_client_write_command_with_opts.rst +++ /dev/null @@ -1,64 +0,0 @@ -:man_page: mongoc_client_write_command_with_opts - -mongoc_client_write_command_with_opts() -======================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_client_write_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic that is specific to commands that write, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_client_command_simple`. - -.. |opts-source| replace:: ``client`` - -.. include:: includes/write-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``db_name``: The name of the database to run the command on. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - -Basic Write Operations ----------------------- - -Do not use this function to call the basic write commands "insert", "update", and "delete". Those commands require special logic not implemented in ``mongoc_client_write_command_with_opts``. For basic write operations use CRUD functions such as :symbol:`mongoc_collection_insert_one` and the others described in :ref:`the CRUD tutorial <tutorial_crud_operations>`, or use the :doc:`Bulk API <bulk>`. - -Example -------- - -.. literalinclude:: ../examples/example-command-with-opts.c - :language: c - :caption: example-command-with-opts.c - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_aggregate.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_aggregate.rst deleted file mode 100644 index 2084544d21d81b285b9865e8c237b1e6fff1d3c4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_aggregate.rst +++ /dev/null @@ -1,121 +0,0 @@ -:man_page: mongoc_collection_aggregate - -mongoc_collection_aggregate() -============================= - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_collection_aggregate (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - const bson_t *pipeline, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A :symbol:`mongoc_query_flags_t`. -* ``pipeline``: A :symbol:`bson:bson_t`, either a BSON array or a BSON document containing an array field named "pipeline". -* ``opts``: A :symbol:`bson:bson_t` containing options for the command, or ``NULL``. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/aggregate-opts.txt - -For a list of all options, see `the MongoDB Manual entry on the aggregate command <http://docs.mongodb.org/manual/reference/command/aggregate/>`_. - - -.. include:: includes/retryable-read-aggregate.txt - -Description ------------ - -This function creates a cursor which sends the aggregate command on the underlying collection upon the first call to :symbol:`mongoc_cursor_next()`. For more information on building aggregation pipelines, see `the MongoDB Manual entry on the aggregate command <http://docs.mongodb.org/manual/reference/command/aggregate/>`_. - -Read preferences, read and write concern, and collation can be overridden by various sources. The highest-priority sources for these options are listed first in the following table. In a transaction, read concern and write concern are prohibited in ``opts`` and the read preference must be primary or NULL. Write concern is applied from ``opts``, or if ``opts`` has no write concern and the aggregation pipeline includes "$out", the write concern is applied from ``collection``. The write concern is omitted for MongoDB before 3.4. - -================== ============== ============== ========= -Read Preferences Read Concern Write Concern Collation -================== ============== ============== ========= -``read_prefs`` ``opts`` ``opts`` ``opts`` -Transaction Transaction Transaction -``collection`` ``collection`` ``collection`` -================== ============== ============== ========= - -:ref:`See the example for transactions <mongoc_client_session_start_transaction_example>` and for :ref:`the "distinct" command with opts <mongoc_client_read_command_with_opts_example>`. - -Returns -------- - -This function returns a newly allocated :symbol:`mongoc_cursor_t` that should be freed with :symbol:`mongoc_cursor_destroy()` when no longer in use. The returned :symbol:`mongoc_cursor_t` is never ``NULL``; if the parameters are invalid, the :symbol:`bson:bson_error_t` in the :symbol:`mongoc_cursor_t` is filled out, and the :symbol:`mongoc_cursor_t` is returned before the server is selected. The user must call :symbol:`mongoc_cursor_next()` on the returned :symbol:`mongoc_cursor_t` to execute the aggregation pipeline. - -.. warning:: - - Failure to handle the result of this function is a programming error. - -Example -------- - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - - static mongoc_cursor_t * - pipeline_query (mongoc_collection_t *collection) - { - mongoc_cursor_t *cursor; - bson_t *pipeline; - - pipeline = BCON_NEW ("pipeline", - "[", - "{", - "$match", - "{", - "foo", - BCON_UTF8 ("A"), - "}", - "}", - "{", - "$match", - "{", - "bar", - BCON_BOOL (false), - "}", - "}", - "]"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - - bson_destroy (pipeline); - - return cursor; - } - -Other Parameters ----------------- - -When using ``$out``, the pipeline stage that writes, the write_concern field of the :symbol:`mongoc_cursor_t` will be set to the :symbol:`mongoc_write_concern_t` parameter, if it is valid, and applied to the write command when :symbol:`mongoc_cursor_next()` is called. Pass any other parameters to the ``aggregate`` command, besides ``pipeline``, as fields in ``opts``: - -.. code-block:: c - - mongoc_write_concern_t *write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_w (write_concern, 3); - - pipeline = - BCON_NEW ("pipeline", "[", "{", "$out", BCON_UTF8 ("collection2"), "}", "]"); - - opts = BCON_NEW ("bypassDocumentValidation", BCON_BOOL (true)); - mongoc_write_concern_append (write_concern, opts); - - cursor = mongoc_collection_aggregate ( - collection1, MONGOC_QUERY_NONE, pipeline, opts, NULL); - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_command.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_command.rst deleted file mode 100644 index d08806c3fe5e1505ab11f19b44fcb469dda26a90..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_command.rst +++ /dev/null @@ -1,44 +0,0 @@ -:man_page: mongoc_collection_command - -mongoc_collection_command() -=========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_collection_command (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *command, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_WARN_UNUSED_RESULT; - -This function is superseded by :symbol:`mongoc_collection_command_with_opts()`, :symbol:`mongoc_collection_read_command_with_opts()`, :symbol:`mongoc_collection_write_command_with_opts()`, and :symbol:`mongoc_collection_read_write_command_with_opts()`. - -.. include:: includes/not-retryable-read.txt - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A :symbol:`mongoc_query_flags_t`. -* ``skip``: A uint32_t with the number of documents to skip or zero. -* ``limit``: A uint32_t with the max number of documents to return or zero. -* ``batch_size``: A uint32_t with the number of documents in each batch or zero. Default is 100. -* ``command``: A :symbol:`bson:bson_t` containing the command to execute. -* ``fields``: A :symbol:`bson:bson_t` containing the fields to return or ``NULL``. Not all commands support this option. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. Otherwise, the command uses mode ``MONGOC_READ_PRIMARY``. - -Returns -------- - -A :symbol:`mongoc_cursor_t`. - -The cursor should be freed with :symbol:`mongoc_cursor_destroy()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_command_simple.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_command_simple.rst deleted file mode 100644 index 7765201de545a3980befb0356279ced4ee1f6a26..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_command_simple.rst +++ /dev/null @@ -1,82 +0,0 @@ -:man_page: mongoc_collection_command_simple - -mongoc_collection_command_simple() -================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_command_simple (mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command to execute. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. Otherwise, the command uses mode ``MONGOC_READ_PRIMARY``. -* ``reply``: A location to initialize a :symbol:`bson:bson_t`. This should be on the stack. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This is a simplified version of :symbol:`mongoc_collection_command()` that returns the first result document in ``reply``. The collection's read preference, read concern, and write concern are not applied to the command. The parameter ``reply`` is initialized even upon failure to simplify memory management. - -This function tries to unwrap an embedded error in the command when possible. The unwrapped error will be propagated via the ``error`` parameter. Additionally, the result document is set in ``reply``. - -.. include:: includes/not-retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -This function does not check the server response for a write concern error or write concern timeout. - -Example -------- - -The following is an example of executing the collection stats command. - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - static void - print_collection_stats (mongoc_collection_t *collection) - { - bson_error_t error; - const char *name; - bson_t *cmd; - bson_t reply; - - name = mongoc_collection_get_name (collection); - cmd = BCON_NEW ("collStats", BCON_UTF8 (name)); - - if (mongoc_collection_command_simple ( - collection, cmd, NULL, &reply, &error)) { - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - } else { - fprintf (stderr, "%s\n", error.message); - } - - bson_destroy (&reply); - bson_destroy (cmd); - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_command_with_opts.rst deleted file mode 100644 index ea79ae01f1216cf06a15989677ddfb8a365e32cc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_command_with_opts.rst +++ /dev/null @@ -1,60 +0,0 @@ -:man_page: mongoc_collection_command_with_opts - -mongoc_collection_command_with_opts() -===================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_command_with_opts ( - mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, interpreting ``opts`` according to the MongoDB server version. To send a raw command to the server without any of this logic, use :symbol:`mongoc_client_command_simple`. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -.. include:: includes/not-retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -The reply is not parsed for a write concern timeout or write concern error. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_copy.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_copy.rst deleted file mode 100644 index 2505150bbe4a2629602c77e444e8e89c52f3cb79..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_copy.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_collection_copy - -mongoc_collection_copy() -======================== - -Synopsis --------- - -.. code-block:: c - - mongoc_collection_t * - mongoc_collection_copy (mongoc_collection_t *collection); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. - -Description ------------ - -Performs a deep copy of the ``collection`` struct and its configuration. Useful if you intend to call :symbol:`mongoc_collection_set_write_concern`, :symbol:`mongoc_collection_set_read_prefs`, or :symbol:`mongoc_collection_set_read_concern`, and want to preserve an unaltered copy of the struct. - -This function does *not* copy the contents of the collection on the MongoDB server. - -Returns -------- - -A newly allocated :symbol:`mongoc_collection_t` that should be freed with :symbol:`mongoc_collection_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_count.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_count.rst deleted file mode 100644 index 0b4111b5b730ddc27b4c99459932b88a10dbeead..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_count.rst +++ /dev/null @@ -1,88 +0,0 @@ -:man_page: mongoc_collection_count - -mongoc_collection_count() -========================= - -Deprecated ----------- - -This function is deprecated and should not be used in new code. -Use :symbol:`mongoc_collection_count_documents` or :symbol:`mongoc_collection_estimated_document_count` instead. - -:symbol:`mongoc_collection_count_documents` has similar performance to calling :symbol:`mongoc_collection_count` with a non-NULL ``query``, and is guaranteed to retrieve an accurate collection count. See :ref:`migrating from deprecated count functions <migrating-from-deprecated-count>` for details. - -:symbol:`mongoc_collection_estimated_document_count` has the same performance as calling :symbol:`mongoc_collection_count` with a NULL ``query``, but is not guaranteed to retrieve an accurate collection count. - -.. include:: includes/retryable-read.txt - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_collection_count (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - const bson_t *query, - int64_t skip, - int64_t limit, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_count_documents or - mongoc_collection_estimated_document_count); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A :symbol:`mongoc_query_flags_t`. -* ``query``: A :symbol:`bson:bson_t` containing the query. -* ``skip``: A int64_t, zero to ignore. -* ``limit``: A int64_t, zero to ignore. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function shall execute a count query on the underlying 'collection'. The bson 'query' is not validated, simply passed along as appropriate to the server. As such, compatibility and errors should be validated in the appropriate server documentation. - -For more information, see the `query reference <http://docs.mongodb.org/manual/reference/operator/query/>`_ at the MongoDB website. - -The :symbol:`mongoc_read_concern_t` specified on the :symbol:`mongoc_collection_t` will be used, if any. If ``read_prefs`` is NULL, the collection's read preferences are used. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - --1 on failure, otherwise the number of documents counted. - -Example -------- - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - static void - print_query_count (mongoc_collection_t *collection, bson_t *query) - { - bson_error_t error; - int64_t count; - - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, query, 0, 0, NULL, &error); - - if (count < 0) { - fprintf (stderr, "Count failed: %s\n", error.message); - } else { - printf ("%" PRId64 " documents counted.\n", count); - } - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_count_documents.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_count_documents.rst deleted file mode 100644 index 6313337fedeea2ef8656421b4794c321c076682c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_count_documents.rst +++ /dev/null @@ -1,106 +0,0 @@ -:man_page: mongoc_collection_count_documents - -mongoc_collection_count_documents() -=================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_collection_count_documents (mongoc_collection_t *collection, - const bson_t *filter, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``filter``: A :symbol:`bson:bson_t` containing the filter. -* ``opts``: A :symbol:`bson:bson_t`, ``NULL`` to ignore. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` or ``NULL``. -* ``reply``: A location for an uninitialized :symbol:`bson:bson_t` to store the command reply, ``NULL`` to ignore. If not ``NULL``, ``reply`` will be initialized. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/read-opts.txt -* ``skip``: An int specifying how many documents matching the ``query`` should be skipped before counting. -* ``limit``: An int specifying the maximum number of documents to count. - -Description ------------ - -This functions executes a count query on ``collection``. In contrast with :symbol:`mongoc_collection_estimated_document_count()`, the count returned is guaranteed to be accurate. - -.. include:: includes/retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - --1 on failure, otherwise the number of documents counted. - -Example -------- - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - static void - print_count (mongoc_collection_t *collection, bson_t *filter) - { - bson_error_t error; - int64_t count; - bson_t* opts = BCON_NEW ("skip", BCON_INT64(5)); - - count = mongoc_collection_count_documents ( - collection, filter, opts, NULL, NULL, &error); - bson_destroy (opts); - - if (count < 0) { - fprintf (stderr, "Count failed: %s\n", error.message); - } else { - printf ("%" PRId64 " documents counted.\n", count); - } - } - -.. _migrating-from-deprecated-count: - -Migrating from deprecated count functions ------------------------------------------ - -When migrating to :symbol:`mongoc_collection_count_documents` from the deprecated :symbol:`mongoc_collection_count` or :symbol:`mongoc_collection_count_with_opts`, the following query operators in the filter must be replaced: - -+-------------+-------------------------------------+ -| Operator | Replacement | -+=============+=====================================+ -| $where | `$expr`_ | -+-------------+-------------------------------------+ -| $near | `$geoWithin`_ with `$center`_ | -+-------------+-------------------------------------+ -| $nearSphere | `$geoWithin`_ with `$centerSphere`_ | -+-------------+-------------------------------------+ - -$expr requires MongoDB 3.6+ - -.. _$expr: https://docs.mongodb.com/manual/reference/operator/query/expr/ -.. _$geoWithin: https://docs.mongodb.com/manual/reference/operator/query/geoWithin/ -.. _$center: https://docs.mongodb.com/manual/reference/operator/query/center/#op._S_center -.. _$centerSphere: https://docs.mongodb.com/manual/reference/operator/query/centerSphere/#op._S_centerSphere - -See Also --------- - -:symbol:`mongoc_collection_estimated_document_count()` diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_count_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_count_with_opts.rst deleted file mode 100644 index 94a274a42404a50dd3de7f54e7d26d22022be47d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_count_with_opts.rst +++ /dev/null @@ -1,142 +0,0 @@ -:man_page: mongoc_collection_count_with_opts - -mongoc_collection_count_with_opts() -=================================== - -Deprecated ----------- - -This function is deprecated and should not be used in new code. -Use :symbol:`mongoc_collection_count_documents` or :symbol:`mongoc_collection_estimated_document_count` instead. - -:symbol:`mongoc_collection_count_documents` has similar performance to calling :symbol:`mongoc_collection_count` with a non-NULL ``query``, and is guaranteed to retrieve an accurate collection count. See :ref:`migrating from deprecated count functions <migrating-from-deprecated-count>` for details. - -:symbol:`mongoc_collection_estimated_document_count` has the same performance as calling :symbol:`mongoc_collection_count` with a NULL ``query``, but is not guaranteed to retrieve an accurate collection count. - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_collection_count_with_opts (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - const bson_t *query, - int64_t skip, - int64_t limit, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_count_documents or - mongoc_collection_estimated_document_count); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A :symbol:`mongoc_query_flags_t`. -* ``query``: A :symbol:`bson:bson_t` containing the query. -* ``skip``: A int64_t, zero to ignore. -* ``limit``: A int64_t, zero to ignore. -* ``opts``: A :symbol:`bson:bson_t`, ``NULL`` to ignore. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`, otherwise uses the collection's read preference. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/read-opts.txt - -Description ------------ - -This function shall execute a count query on the underlying 'collection'. The bson 'query' is not validated, simply passed along as appropriate to the server. As such, compatibility and errors should be validated in the appropriate server documentation. - -The :symbol:`mongoc_read_concern_t` specified on the :symbol:`mongoc_collection_t` will be used, if any. If ``read_prefs`` is NULL, the collection's read preferences are used. - -In addition to the standard functionality available from mongoc_collection_count, this function allows the user to add arbitrary extra keys to the count. This pass through enables features such as hinting for counts. - -For more information, see the `query reference <http://docs.mongodb.org/manual/reference/operator/query/>`_ at the MongoDB website. - -.. include:: includes/retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - --1 on failure, otherwise the number of documents counted. - -Examples --------- - -.. code-block:: c - :caption: Basic Counting - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - static void - print_query_count (mongoc_collection_t *collection, bson_t *query) - { - bson_error_t error; - int64_t count; - bson_t opts; - - bson_init (&opts); - BSON_APPEND_UTF8 (&opts, "hint", "_id_"); - - count = mongoc_collection_count_with_opts ( - collection, MONGOC_QUERY_NONE, query, 0, 0, &opts, NULL, &error); - - bson_destroy (&opts); - - if (count < 0) { - fprintf (stderr, "Count failed: %s\n", error.message); - } else { - printf ("%" PRId64 " documents counted.\n", count); - } - } - -.. code-block:: c - :caption: Counting with Collation - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - static void - print_query_count (mongoc_collection_t *collection, bson_t *query) - { - bson_t *selector; - bson_t *opts; - bson_error_t error; - int64_t count; - - selector = BCON_NEW ("_id", "{", "$gt", BCON_UTF8 ("one"), "}"); - - /* "One" normally sorts before "one"; make "one" come first */ - opts = BCON_NEW ("collation", - "{", - "locale", - BCON_UTF8 ("en_US"), - "caseFirst", - BCON_UTF8 ("lower"), - "}"); - - count = mongoc_collection_count_with_opts ( - collection, MONGOC_QUERY_NONE, query, 0, 0, opts, NULL, &error); - - bson_destroy (selector); - bson_destroy (opts); - - if (count < 0) { - fprintf (stderr, "Count failed: %s\n", error.message); - } else { - printf ("%" PRId64 " documents counted.\n", count); - } - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_create_bulk_operation.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_create_bulk_operation.rst deleted file mode 100644 index bc2325c9e51e7296c6ae615527324263f93c0399..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_create_bulk_operation.rst +++ /dev/null @@ -1,65 +0,0 @@ -:man_page: mongoc_collection_create_bulk_operation - -mongoc_collection_create_bulk_operation() -========================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_bulk_operation_t * - mongoc_collection_create_bulk_operation ( - mongoc_collection_t *collection, - bool ordered, - const mongoc_write_concern_t *write_concern) BSON_GNUC_WARN_UNUSED_RESULT - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_create_bulk_operation_with_opts); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_collection_create_bulk_operation_with_opts()` instead. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``ordered``: If the operations must be performed in order. -* ``write_concern``: An optional :symbol:`mongoc_write_concern_t` or ``NULL``. - -Description ------------ - -This function shall begin a new bulk operation. After creating this you may call various functions such as :symbol:`mongoc_bulk_operation_update()`, :symbol:`mongoc_bulk_operation_insert()` and others. - -After calling :symbol:`mongoc_bulk_operation_execute()` the commands will be executed in as large as batches as reasonable by the client. - -If ``ordered`` is true, then processing will stop at the first error. - -If ``ordered`` is not true, then the bulk operation will attempt to continue processing even after the first failure. - -``write_concern`` contains the write concern for all operations in the bulk operation. If ``NULL``, the collection's write concern is used. The global default is acknowledged writes: MONGOC_WRITE_CONCERN_W_DEFAULT. - -See Also --------- - -:symbol:`Bulk Write Operations <bulk>` - -:symbol:`mongoc_bulk_operation_t` - -Errors ------- - -Errors are propagated when executing the bulk operation. - -Returns -------- - -A newly allocated :symbol:`mongoc_bulk_operation_t` that should be freed with :symbol:`mongoc_bulk_operation_destroy()` when no longer in use. - -.. warning:: - - Failure to handle the result of this function is a programming error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_create_bulk_operation_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_create_bulk_operation_with_opts.rst deleted file mode 100644 index e9b94870fb45cd6deee3ecb4dfdb069638270edf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_create_bulk_operation_with_opts.rst +++ /dev/null @@ -1,52 +0,0 @@ -:man_page: mongoc_collection_create_bulk_operation_with_opts - -mongoc_collection_create_bulk_operation_with_opts() -=================================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_bulk_operation_t * - mongoc_collection_create_bulk_operation_with_opts ( - mongoc_collection_t *collection, - const bson_t *opts) BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/bulk-opts.txt - -Description ------------ - -This function shall begin a new bulk operation. After creating this you may call various functions such as :symbol:`mongoc_bulk_operation_update()`, :symbol:`mongoc_bulk_operation_insert()` and others. - -After calling :symbol:`mongoc_bulk_operation_execute()` the commands will be executed in as large as batches as reasonable by the client. - -See Also --------- - -:symbol:`Bulk Write Operations <bulk>` - -:symbol:`mongoc_bulk_operation_t` - -Errors ------- - -Errors are propagated when executing the bulk operation. - -Returns -------- - -A newly allocated :symbol:`mongoc_bulk_operation_t` that should be freed with :symbol:`mongoc_bulk_operation_destroy()` when no longer in use. - -.. warning:: - - Failure to handle the result of this function is a programming error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_create_index.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_create_index.rst deleted file mode 100644 index 27c1a86e2ed557a3237aa7fc9499b543286cc010..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_create_index.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_collection_create_index - -mongoc_collection_create_index() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_create_index (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *opt, - bson_error_t *error); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. See :doc:`create-indexes`. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``keys``: A :symbol:`bson:bson_t`. -* ``opt``: A mongoc_index_opt_t. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_create_index_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_create_index_with_opts.rst deleted file mode 100644 index b52be6e13208647a6522a8287848d2a66410cf5e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_create_index_with_opts.rst +++ /dev/null @@ -1,60 +0,0 @@ -:man_page: mongoc_collection_create_index_with_opts - -mongoc_collection_create_index_with_opts() -========================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *index_opts, - const bson_t *command_opts, - bson_t *reply, - bson_error_t *error); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. See :doc:`create-indexes`. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``keys``: A :symbol:`bson:bson_t`. -* ``index_opts``: A mongoc_index_opt_t. -* ``reply``: An optional location for a :symbol:`bson:bson_t` which will store the server's reply. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/create-index-opts.txt - -Description ------------ - -This function will request the creation of a new index. - -This function will use the ``createIndexes`` command. -The server's reply is stored in ``reply``. - -If no write concern is provided in ``command_opts``, the collection's write concern is used. - -See :symbol:`mongoc_index_opt_t` for options on creating indexes. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -``reply`` is always initialized and must be destroyed with :symbol:`bson:bson_destroy()`. If the server is running an obsolete version of MongoDB then ``reply`` may be empty, though it will still be initialized. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_delete.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_delete.rst deleted file mode 100644 index 53d44373f7b099637db12dbfc7da2ee396462a2d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_delete.rst +++ /dev/null @@ -1,52 +0,0 @@ -:man_page: mongoc_collection_delete - -mongoc_collection_delete() -========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_delete (mongoc_collection_t *collection, - mongoc_delete_flags_t flags, - const bson_t *selector, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_delete_one or - mongoc_collection_delete_many); - -Deprecated ----------- - -Please use :symbol:`mongoc_collection_delete_one()` or :symbol:`mongoc_collection_delete_many()` instead. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A :symbol:`mongoc_delete_flags_t`. -* ``selector``: A :symbol:`bson:bson_t` containing the query to match documents. -* ``write_concern``: A :symbol:`mongoc_write_concern_t` or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function shall delete documents in the given ``collection`` that match ``selector``. The bson ``selector`` is not validated, simply passed along as appropriate to the server. As such, compatibility and errors should be validated in the appropriate server documentation. - -If you want to limit deletes to a single document, provide ``MONGOC_DELETE_SINGLE_REMOVE`` in ``flags``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_delete_many.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_delete_many.rst deleted file mode 100644 index fa8aa071f7593c6f8225ec26418b92ad02f392c4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_delete_many.rst +++ /dev/null @@ -1,47 +0,0 @@ -:man_page: mongoc_collection_delete_many - -mongoc_collection_delete_many() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_delete_many (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``selector``: A :symbol:`bson:bson_t` containing the query to match documents. -* ``reply``: Optional. An uninitialized :symbol:`bson:bson_t` populated with the delete result, or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/delete-many-opts.txt - -Description ------------ - -This function removes all documents in the given ``collection`` that match ``selector``. - -To delete at most one matching document, use :symbol:`mongoc_collection_delete_one`. - -If you pass a non-NULL ``reply``, it is filled out with the field "deletedCount". If there is a server error then ``reply`` contains either a "writeErrors" array with one subdocument or a "writeConcernErrors" array. The reply must be freed with :symbol:`bson:bson_destroy`. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_delete_one.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_delete_one.rst deleted file mode 100644 index 144e470fad63852883ac58299a30adc57fa02fcc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_delete_one.rst +++ /dev/null @@ -1,47 +0,0 @@ -:man_page: mongoc_collection_delete_one - -mongoc_collection_delete_one() -============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_delete_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``selector``: A :symbol:`bson:bson_t` containing the query to match documents. -* ``reply``: Optional. An uninitialized :symbol:`bson:bson_t` populated with the delete result, or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/delete-one-opts.txt - -Description ------------ - -This function removes at most one document in the given ``collection`` that matches ``selector``. - -To delete all matching documents, use :symbol:`mongoc_collection_delete_many`. - -If you pass a non-NULL ``reply``, it is filled out with the field "deletedCount". If there is a server error then ``reply`` contains either a "writeErrors" array with one subdocument or a "writeConcernErrors" array. The reply must be freed with :symbol:`bson:bson_destroy`. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_destroy.rst deleted file mode 100644 index d40c6c5357cada9616e10edbb441ca3eaacc370d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_destroy.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_collection_destroy - -mongoc_collection_destroy() -=========================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_collection_destroy (mongoc_collection_t *collection); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. - -Description ------------ - -This function shall destroy a :symbol:`mongoc_collection_t` and its associated resources. Does nothing if ``collection`` is NULL. - -.. warning:: - - Always destroy a :symbol:`mongoc_cursor_t` created from a collection before destroying the collection. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_drop.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_drop.rst deleted file mode 100644 index aef54660ac67515a659b9153ee5df8f4957e69d3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_drop.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_collection_drop - -mongoc_collection_drop() -======================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_drop (mongoc_collection_t *collection, bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -For more information, see :symbol:`mongoc_collection_drop_with_opts()`. This function is a thin wrapper, passing ``NULL`` in as :symbol:`opts <bson:bson_t>` parameter. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_drop_index.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_drop_index.rst deleted file mode 100644 index d113fe94084363376aa2bd12d9eb385b7546b982..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_drop_index.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_collection_drop_index - -mongoc_collection_drop_index() -============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_drop_index (mongoc_collection_t *collection, - const char *index_name, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``index_name``: A string containing the name of the index. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -For more information, see :symbol:`mongoc_collection_drop_with_opts() <mongoc_collection_drop_index_with_opts>`. This function is a thin wrapper, passing ``NULL`` in as :symbol:`opts <bson:bson_t>` parameter. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_drop_index_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_drop_index_with_opts.rst deleted file mode 100644 index 71b60a59ff5db8244331de9162387e43e3a92f5e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_drop_index_with_opts.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_collection_drop_index_with_opts - -mongoc_collection_drop_index_with_opts() -======================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_drop_index_with_opts (mongoc_collection_t *collection, - const char *index_name, - const bson_t *opts, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``index_name``: A string containing the name of the index. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/write-opts.txt - -Description ------------ - -This function requests than an index on ``collection`` be dropped. - -If no write concern is provided in ``opts``, the collection's write concern is used. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_drop_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_drop_with_opts.rst deleted file mode 100644 index 428e9b4f292a4929be212ace5ecd19bcc2966298..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_drop_with_opts.rst +++ /dev/null @@ -1,71 +0,0 @@ -:man_page: mongoc_collection_drop_with_opts - -mongoc_collection_drop_with_opts() -================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_drop_with_opts (mongoc_collection_t *collection, - bson_t *opts, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/write-opts.txt - -Description ------------ - -This function requests that a ``collection`` be dropped, including all indexes associated with the ``collection``. - -If no write concern is provided in ``opts``, the collection's write concern is used. - -If the collection does not exist, the server responds with an "ns not found" error. It is safe to ignore this error; set the :ref:`Error API Version <error_api_version>` to 2 and ignore server error code 26: - -.. code-block:: c - - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - bool r; - - client = mongoc_client_new (NULL); - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "db", "collection"); - r = mongoc_collection_drop_with_opts (collection, NULL /* opts */, &error); - if (r) { - printf ("Dropped.\n"); - } else { - printf ("Error message: %s\n", error.message); - if (error.domain == MONGOC_ERROR_SERVER && error.code == 26) { - printf ("Ignoring 'ns not found' error\n"); - } else { - fprintf (stderr, "Unrecognized error!\n"); - } - } - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - -In MongoDB 3.0 and older, the "ns not found" error code is the generic MONGOC_ERROR_QUERY_FAILURE; in this case check whether the error message is equal to the string "ns not found". - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns true if the collection was successfully dropped. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_ensure_index.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_ensure_index.rst deleted file mode 100644 index 15056a8d2f04e526a62671c8b434027dbe622381..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_ensure_index.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_collection_ensure_index - -mongoc_collection_ensure_index() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_ensure_index (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *opt, - bson_error_t *error) - BSON_GNUC_DEPRECATED; - -Deprecated ----------- - -This function is deprecated and should not be used in new code. See :doc:`create-indexes`. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``keys``: A :symbol:`bson:bson_t`. -* ``opt``: A mongoc_index_opt_t. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_estimated_document_count.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_estimated_document_count.rst deleted file mode 100644 index 8444fd5780f067faa5cd043e797c58dd34d954d0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_estimated_document_count.rst +++ /dev/null @@ -1,80 +0,0 @@ -:man_page: mongoc_collection_estimated_document_count - -mongoc_collection_estimated_document_count() -============================================ - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_collection_estimated_document_count (mongoc_collection_t *collection, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``opts``: A :symbol:`bson:bson_t`, ``NULL`` to ignore. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` or ``NULL``. -* ``reply``: A location for an uninitialized :symbol:`bson:bson_t` to store the command reply, ``NULL`` to ignore. If not ``NULL``, ``reply`` will be initialized. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/read-opts.txt -* ``skip``: An int specifying how many documents matching the ``query`` should be skipped before counting. -* ``limit``: An int specifying the maximum number of documents to count. - -Description ------------ - -This functions executes a count query on ``collection``. In contrast with :symbol:`mongoc_collection_count_documents()`, the count returned is *not* guaranteed to be accurate. - -.. include:: includes/retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - --1 on failure, otherwise the number of documents counted. - -Example -------- - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - static void - print_count (mongoc_collection_t *collection, bson_t *query) - { - bson_error_t error; - int64_t count; - bson_t* opts = BCON_NEW ("skip", BCON_INT64(5)); - - count = mongoc_collection_estimated_document_count ( - collection, opts, NULL, NULL, &error); - bson_destroy (opts); - - if (count < 0) { - fprintf (stderr, "Count failed: %s\n", error.message); - } else { - printf ("%" PRId64 " documents counted.\n", count); - } - } - -See Also --------- - -:symbol:`mongoc_collection_count_documents()` \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_find.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_find.rst deleted file mode 100644 index 12c8b06ef755b7e6132848fe80ba742b375ef896..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_find.rst +++ /dev/null @@ -1,165 +0,0 @@ -:man_page: mongoc_collection_find - -mongoc_collection_find() -======================== - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Use the more convenient :symbol:`mongoc_collection_find_with_opts` instead. - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_collection_find (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *query, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_find_with_opts) - BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A :symbol:`mongoc_query_flags_t`. -* ``skip``: A uint32_t of number of documents to skip or 0. -* ``limit``: A uint32_t of max number of documents to return or 0. -* ``batch_size``: A uint32_t containing batch size of document result sets or 0 for default. Default is 100. -* ``query``: A :symbol:`bson:bson_t` containing the query and options to execute. -* ``fields``: A :symbol:`bson:bson_t` containing fields to return or ``NULL``. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` or ``NULL`` for default read preferences. - -Description ------------ - -This function shall execute a query on the underlying ``collection``. - -If no options are necessary, ``query`` can simply contain a query such as ``{a:1}``. If you would like to specify options such as a sort order, the query must be placed inside of ``{"$query": {}}``. See the example below for how to properly specify additional options to ``query``. - -.. include:: includes/retryable-read.txt - -Returns -------- - -A newly allocated :symbol:`mongoc_cursor_t` that should be freed with :symbol:`mongoc_cursor_destroy()` when no longer in use. - -Example -------- - -.. code-block:: c - :caption: Print All Documents in a Collection - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - static void - print_all_documents (mongoc_collection_t *collection) - { - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - char *str; - bson_t *query; - - query = BCON_NEW ("$query", - "{", - "foo", - BCON_INT32 (1), - "}", - "$orderby", - "{", - "bar", - BCON_INT32 (-1), - "}"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - printf ("%s\n", str); - bson_free (str); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "An error occurred: %s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - bson_destroy (query); - } - -The "find" command ------------------- - -Queries have historically been sent as OP_QUERY wire protocol messages, but beginning in MongoDB 3.2 queries use `the "find" command <https://docs.mongodb.org/master/reference/command/find/>`_ instead. - -The driver automatically converts queries to the new "find" command syntax if needed, so this change is typically invisible to C Driver users. However, an application written exclusively for MongoDB 3.2 and later can choose to use the new syntax directly instead of relying on the driver to convert from the old syntax: - -.. code-block:: c - - /* MongoDB 3.2+ "find" command syntax */ - query = BCON_NEW ("filter", - "{", - "foo", - BCON_INT32 (1), - "}", - "sort", - "{", - "bar", - BCON_INT32 (-1), - "}"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL); - -The "find" command takes different options from the traditional OP_QUERY message. - -==================== ================== ================= -Query ``$query`` ``filter`` -Sort ``$orderby`` ``sort`` -Show record location ``$showDiskLoc`` ``showRecordId`` -Other $-options ``$<option name>`` ``<option name>`` -==================== ================== ================= - -Most applications should use the OP_QUERY syntax, with "$query", "$orderby", and so on, and rely on the driver to convert to the new syntax if needed. - -See Also --------- - -`The "find" command <https://docs.mongodb.org/master/reference/command/find/>`_ in the MongoDB Manual. - -The "explain" command ---------------------- - -With MongoDB before 3.2, a query with option ``$explain: true`` returns information about the query plan, instead of the query results. Beginning in MongoDB 3.2, there is a separate "explain" command. The driver will not convert "$explain" queries to "explain" commands, you must call the "explain" command explicitly: - -.. code-block:: c - - /* MongoDB 3.2+, "explain" command syntax */ - command = BCON_NEW ("explain", - "{", - "find", - BCON_UTF8 ("collection_name"), - "filter", - "{", - "foo", - BCON_INT32 (1), - "}", - "}"); - mongoc_collection_command_simple (collection, command, NULL, &reply, &error); - -See Also --------- - -`The "explain" command <https://docs.mongodb.org/master/reference/command/explain/>`_ in the MongoDB Manual. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_find_and_modify.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_find_and_modify.rst deleted file mode 100644 index 6f78d18b36654a40c6fc638fe9dce35928913c2c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_find_and_modify.rst +++ /dev/null @@ -1,68 +0,0 @@ -:man_page: mongoc_collection_find_and_modify - -mongoc_collection_find_and_modify() -=================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_find_and_modify (mongoc_collection_t *collection, - const bson_t *query, - const bson_t *sort, - const bson_t *update, - const bson_t *fields, - bool _remove, - bool upsert, - bool _new, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``query``: A :symbol:`bson:bson_t` containing the query to locate target document(s). -* ``sort``: A :symbol:`bson:bson_t` containing the sort order for ``query``. -* ``update``: A :symbol:`bson:bson_t` containing an update spec. -* ``fields``: An optional :symbol:`bson:bson_t` containing the fields to return or ``NULL``. -* ``_remove``: If the matching documents should be removed. -* ``upsert``: If an upsert should be performed. -* ``_new``: If the new version of the document should be returned. -* ``reply``: Optional pointer to an *uninitialized* :symbol:`bson:bson_t` that will be initialized with the result. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Update and return an object. - -This is a thin wrapper around the ``findAndModify`` command. Either ``update`` or ``_remove`` arguments are required. - -See also: :symbol:`mongoc_collection_find_and_modify_with_opts`. - -As of MongoDB 3.2, the :symbol:`mongoc_write_concern_t` specified on the :symbol:`mongoc_collection_t` will be used, if any. - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns either the document before or after modification based on the ``_new`` parameter. - -A write concern timeout or write concern error is considered a failure. - -Example -------- - -.. literalinclude:: ../examples/find-and-modify.c - :language: c - :caption: find-and-modify.c - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_find_and_modify_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_find_and_modify_with_opts.rst deleted file mode 100644 index 8c00a2bdaffc592fc1ad5ccda82b40e413552994..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_find_and_modify_with_opts.rst +++ /dev/null @@ -1,51 +0,0 @@ -:man_page: mongoc_collection_find_and_modify_with_opts - -mongoc_collection_find_and_modify_with_opts() -============================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_find_and_modify_with_opts ( - mongoc_collection_t *collection, - const bson_t *query, - const mongoc_find_and_modify_opts_t *opts, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``query``: A :symbol:`bson:bson_t` containing the query to locate target document(s). -* ``opts``: A :symbol:`find and modify options <mongoc_find_and_modify_opts_t>`. Must not be NULL. -* ``reply``: An optional location for a :symbol:`bson:bson_t` that will be initialized with the result or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Update and return an object. - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - -Example -------- - -See the example code for :ref:`mongoc_find_and_modify_opts_t <mongoc_collection_find_and_modify_with_opts_example>`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_find_indexes.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_find_indexes.rst deleted file mode 100644 index 6c9f83c284fb82d3449843e0ab39925a44897617..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_find_indexes.rst +++ /dev/null @@ -1,40 +0,0 @@ -:man_page: mongoc_collection_find_indexes - -mongoc_collection_find_indexes() -================================ - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_collection_find_indexes (mongoc_collection_t *collection, - bson_error_t *error); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_collection_find_indexes_with_opts()` instead. - -Fetches a cursor containing documents, each corresponding to an index on this collection. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -A cursor where each result corresponds to the server's representation of an index on this collection. If the collection does not exist on the server, the cursor will be empty. diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_find_indexes_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_find_indexes_with_opts.rst deleted file mode 100644 index 0e194bc31fcb0942a8c09803190bdd05a71fad50..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_find_indexes_with_opts.rst +++ /dev/null @@ -1,40 +0,0 @@ -:man_page: mongoc_collection_find_indexes_with_opts - -mongoc_collection_find_indexes_with_opts() -========================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_collection_find_indexes_with_opts (mongoc_collection_t *collection, - const bson_t *opts); - -Fetches a cursor containing documents, each corresponding to an index on this collection. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/generic-opts.txt - -Errors ------- - -Use :symbol:`mongoc_cursor_error` on the returned cursor to check for errors. - -Returns -------- - -A cursor where each result corresponds to the server's representation of an index on this collection. If the collection does not exist on the server, the cursor will be empty. - -The cursor functions :symbol:`mongoc_cursor_set_limit`, :symbol:`mongoc_cursor_set_batch_size`, and :symbol:`mongoc_cursor_set_max_await_time_ms` have no use on the returned cursor. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_find_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_find_with_opts.rst deleted file mode 100644 index 0fd078cd74f3bbe269c5838c32f1f2df99cdaea2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_find_with_opts.rst +++ /dev/null @@ -1,178 +0,0 @@ -:man_page: mongoc_collection_find_with_opts - -mongoc_collection_find_with_opts() -================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_collection_find_with_opts (mongoc_collection_t *collection, - const bson_t *filter, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``filter``: A :symbol:`bson:bson_t` containing the query to execute. -* ``opts``: A :symbol:`bson:bson_t` query options, including sort order and which fields to return. Can be ``NULL``. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` or ``NULL``. - -Description ------------ - -Query on ``collection``, passing arbitrary query options to the server in ``opts``. - -To target a specific server, include an integer "serverId" field in ``opts`` with an id obtained first by calling :symbol:`mongoc_client_select_server`, then :symbol:`mongoc_server_description_id` on its return value. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/read-opts-sources.txt - -.. include:: includes/retryable-read.txt - -Returns -------- - -A newly allocated :symbol:`mongoc_cursor_t` that must be freed with :symbol:`mongoc_cursor_destroy()`. - -Examples --------- - -.. code-block:: c - :caption: Print First Ten Documents in a Collection - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - static void - print_ten_documents (mongoc_collection_t *collection) - { - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - char *str; - - /* filter by "foo": 1, order by "bar" descending */ - filter = BCON_NEW ("foo", BCON_INT32 (1)); - opts = BCON_NEW ( - "limit", BCON_INT64 (10), "sort", "{", "bar", BCON_INT32 (-1), "}"); - - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - printf ("%s\n", str); - bson_free (str); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "An error occurred: %s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - bson_destroy (opts); - } - -.. code-block:: c - :caption: More examples of modifying the query with ``opts``: - - bson_t *filter; - bson_t *opts; - mongoc_read_prefs_t *read_prefs; - - filter = BCON_NEW ("foo", BCON_INT32 (1)); - - /* Include "field_name_one" and "field_name_two" in "projection", omit - * others. "_id" must be specifically removed or it is included by default. - */ - opts = BCON_NEW ("projection", "{", - "field_name_one", BCON_BOOL (true), - "field_name_two", BCON_BOOL (true), - "_id", BCON_BOOL (false), - "}", - "tailable", BCON_BOOL (true), - "awaitData", BCON_BOOL (true), - "sort", "{", "bar", BCON_INT32 (-1), "}", - "collation", "{", - "locale", BCON_UTF8("en_US"), - "caseFirst", BCON_UTF8 ("lower"), - "}"); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - cursor = - mongoc_collection_find_with_opts (collection, filter, opts, read_prefs); - -The following options are supported. - -======================= ================== =================== ================== -Option BSON type Option BSON type -======================= ================== =================== ================== -``projection`` document ``max`` document -``sort`` document ``maxTimeMS`` non-negative int64 -``skip`` non-negative int64 ``maxAwaitTimeMS`` non-negative int64 -``limit`` non-negative int64 ``min`` document -``batchSize`` non-negative int64 ``noCursorTimeout`` bool -``exhaust`` bool ``oplogReplay`` bool -``hint`` string or document ``readConcern`` document -``allowPartialResults`` bool ``returnKey`` bool -``awaitData`` bool ``sessionId`` (none) -``collation`` document ``showRecordId`` bool -``comment`` string ``singleBatch`` bool -======================= ================== =================== ================== - -All options are documented in the reference page for `the "find" command`_ in the MongoDB server manual, except for "maxAwaitTimeMS" and "sessionId". - -"maxAwaitTimeMS" is the maximum amount of time for the server to wait on new documents to satisfy a query, if "tailable" and "awaitData" are both true. -If no new documents are found, the tailable cursor receives an empty batch. The "maxAwaitTimeMS" option is ignored for MongoDB older than 3.4. - -To add a "sessionId", construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session`. You can begin a transaction with :symbol:`mongoc_client_session_start_transaction`, optionally with a :symbol:`mongoc_transaction_opt_t` that overrides the options inherited from ``collection``. Then use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`. - -To add a "readConcern", construct a :symbol:`mongoc_read_concern_t` with :symbol:`mongoc_read_concern_new` and configure it with :symbol:`mongoc_read_concern_set_level`. Then use :symbol:`mongoc_read_concern_append` to add the read concern to ``opts``. - -For some options like "collation", the driver returns an error if the server version is too old to support the feature. -Any fields in ``opts`` that are not listed here are passed to the server unmodified. - -Deprecated Options ------------------- - -The ``snapshot`` boolean option is removed in MongoDB 4.0. The ``maxScan`` option, a non-negative int64, is deprecated in MongoDB 4.0 and will be removed in a future MongoDB version. Both options are supported by the C Driver with older MongoDB versions. - -See Also --------- - -`The "find" command`_ in the MongoDB Manual. All options listed there are supported by the C Driver. -For MongoDB servers before 3.2, or for exhaust queries, the driver transparently converts the query to a legacy OP_QUERY message. - -.. _the "find" command: https://docs.mongodb.org/master/reference/command/find/ - -The "explain" command ---------------------- - -With MongoDB before 3.2, a query with option ``$explain: true`` returns information about the query plan, instead of the query results. Beginning in MongoDB 3.2, there is a separate "explain" command. The driver will not convert "$explain" queries to "explain" commands, you must call the "explain" command explicitly: - -.. code-block:: c - - /* MongoDB 3.2+, "explain" command syntax */ - command = BCON_NEW ("explain", "{", - "find", BCON_UTF8 ("collection_name"), - "filter", "{", "foo", BCON_INT32 (1), "}", - "}"); - - mongoc_collection_command_simple (collection, command, NULL, &reply, &error); - -See Also --------- - -`The "explain" command <https://docs.mongodb.org/master/reference/command/explain/>`_ in the MongoDB Manual. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_get_last_error.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_get_last_error.rst deleted file mode 100644 index 33cb3d8ff5b2a1f58344f8cc17b05616bb106289..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_get_last_error.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_collection_get_last_error - -mongoc_collection_get_last_error() -================================== - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_collection_get_last_error (const mongoc_collection_t *collection); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. - -Description ------------ - -The mongoc_collection_get_last_error() function returns a bulk result. See :doc:`Bulk Write Operations <bulk>` for examples of bulk results. - -A write_concern must be at least ``MONGOC_WRITE_CONCERN_W_DEFAULT`` in last command execution for this to be available. - -Returns -------- - -A :symbol:`bson:bson_t` that should not be modified or ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_get_name.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_get_name.rst deleted file mode 100644 index 6ea341f73336038ca51ccbd46d5eba166ff3275c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_get_name.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_collection_get_name - -mongoc_collection_get_name() -============================ - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_collection_get_name (mongoc_collection_t *collection); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. - -Description ------------ - -Fetches the name of ``collection``. - -Returns -------- - -A string which should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_get_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_get_read_concern.rst deleted file mode 100644 index 1e02f597f4dd6220b39156ceda332375c7884486..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_get_read_concern.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_collection_get_read_concern - -mongoc_collection_get_read_concern() -==================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_concern_t * - mongoc_collection_get_read_concern (const mongoc_collection_t *collection); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. - -Description ------------ - -Fetches the default read concern to be used on read operations originating from ``collection``. - -Returns -------- - -A :symbol:`mongoc_read_concern_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_get_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_get_read_prefs.rst deleted file mode 100644 index 564da1bd769789f11d880de5f9de2f87987cee6e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_get_read_prefs.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_collection_get_read_prefs - -mongoc_collection_get_read_prefs() -================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_prefs_t * - mongoc_collection_get_read_prefs (const mongoc_collection_t *collection); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. - -Description ------------ - -Fetches the default read preferences to use for ``collection``. Operations without specified read-preferences will default to this. - -Returns -------- - -A :symbol:`mongoc_read_prefs_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_get_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_get_write_concern.rst deleted file mode 100644 index 1cd79b3c06f3def9e718463229be7190ebe4327c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_get_write_concern.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_collection_get_write_concern - -mongoc_collection_get_write_concern() -===================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_write_concern_t * - mongoc_collection_get_write_concern (const mongoc_collection_t *collection); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. - -Description ------------ - -Fetches the default write concern to be used on write operations originating from ``collection`` and not specifying a write concern. - -Returns -------- - -A :symbol:`mongoc_write_concern_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_insert.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_insert.rst deleted file mode 100644 index 81be909eeac5c31e82bb9549486c93244a74a967..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_insert.rst +++ /dev/null @@ -1,47 +0,0 @@ -:man_page: mongoc_collection_insert - -mongoc_collection_insert() -========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_insert (mongoc_collection_t *collection, - mongoc_insert_flags_t flags, - const bson_t *document, - const mongoc_write_concern_t *write_concern, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A :symbol:`mongoc_insert_flags_t`. -* ``document``: A :symbol:`bson:bson_t`. -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Superseded by :symbol:`mongoc_collection_insert_one()` and :symbol:`mongoc_collection_insert_many()`. - -This function shall insert ``document`` into ``collection``. - -If no ``_id`` element is found in ``document``, then a :symbol:`bson:bson_oid_t` will be generated locally and added to the document. If you must know the inserted document's ``_id``, generate it in your code and include it in the ``document``. The ``_id`` you generate can be a :symbol:`bson:bson_oid_t` or any other non-array BSON type. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_insert_bulk.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_insert_bulk.rst deleted file mode 100644 index 429e0c94846de1b44d4d4c9df787afde416871d9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_insert_bulk.rst +++ /dev/null @@ -1,53 +0,0 @@ -:man_page: mongoc_collection_insert_bulk - -mongoc_collection_insert_bulk() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_insert_bulk (mongoc_collection_t *collection, - mongoc_insert_flags_t flags, - const bson_t **documents, - uint32_t n_documents, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_insert_many); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_collection_insert_many()` instead. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A bitwise or of :symbol:`mongoc_insert_flags_t`. -* ``documents``: An array of :symbol:`const bson_t * <bson:bson_t>`. -* ``n_documents``: The number of documents in ``documents``. -* ``write_concern``: A :symbol:`mongoc_write_concern_t` or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function performs a bulk insert of all of the documents in ``documents``. This function is deprecated as it cannot accurately return which documents may have failed during the bulk insert. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -A write concern timeout or write concern error is considered a failure. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_insert_many.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_insert_many.rst deleted file mode 100644 index 73d8a5e8d8c2a67f16e15ea68cdb4ab2e47dab61..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_insert_many.rst +++ /dev/null @@ -1,54 +0,0 @@ -:man_page: mongoc_collection_insert_many - -mongoc_collection_insert_many() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_insert_many (mongoc_collection_t *collection, - const bson_t **documents, - size_t n_documents, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``documents``: An array of pointers to :symbol:`bson:bson_t`. -* ``n_documents``: The length of ``documents``. -* ``reply``: Optional. An uninitialized :symbol:`bson:bson_t` populated with the insert result, or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/insert-many-opts.txt - -Description ------------ - -Insert ``documents`` into ``collection``. - -To insert a single document, see :symbol:`mongoc_collection_insert_one`. - -For any document that does not have an "_id" field, a :symbol:`bson:bson_oid_t` will be generated locally and added to the document. If you must know the inserted document's ``_id``, generate it in your code and include it in the ``document``. The ``_id`` you generate can be a :symbol:`bson:bson_oid_t` or any other non-array BSON type. - -If you pass a non-NULL ``reply``, it is filled out with an "insertedCount" field. If there is a server error then ``reply`` may contain a "writeErrors" array and/or a "writeConcernErrors" array (see :doc:`Bulk Write Operations <bulk>` for examples). The reply must be freed with :symbol:`bson:bson_destroy`. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_insert_one.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_insert_one.rst deleted file mode 100644 index 9375451fcbc48706b5b3e90a62f5f981ee250aec..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_insert_one.rst +++ /dev/null @@ -1,52 +0,0 @@ -:man_page: mongoc_collection_insert_one - -mongoc_collection_insert_one() -============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_insert_one (mongoc_collection_t *collection, - const bson_t *document, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``document``: A :symbol:`bson:bson_t`. -* ``reply``: Optional. An uninitialized :symbol:`bson:bson_t` populated with the insert result, or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/insert-one-opts.txt - -Description ------------ - -This function shall insert ``document`` into ``collection``. - -To insert an array of documents, see :symbol:`mongoc_collection_insert_many`. - -If no ``_id`` element is found in ``document``, then a :symbol:`bson:bson_oid_t` will be generated locally and added to the document. If you must know the inserted document's ``_id``, generate it in your code and include it in the ``document``. The ``_id`` you generate can be a :symbol:`bson:bson_oid_t` or any other non-array BSON type. - -If you pass a non-NULL ``reply``, it is filled out with an "insertedCount" field. If there is a server error then ``reply`` contains either a "writeErrors" array with one subdocument or a "writeConcernErrors" array. The reply must be freed with :symbol:`bson:bson_destroy`. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_keys_to_index_string.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_keys_to_index_string.rst deleted file mode 100644 index 8be59ebbdd4da12be541e87e211b134d5b9adf4a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_keys_to_index_string.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_collection_keys_to_index_string - -mongoc_collection_keys_to_index_string() -======================================== - -Synopsis --------- - -.. code-block:: c - - char * - mongoc_collection_keys_to_index_string (const bson_t *keys); - -Parameters ----------- - -* ``keys``: A :symbol:`bson:bson_t`. - -Description ------------ - -This function returns the canonical stringification of a given key specification. See :doc:`create-indexes`. - -It is a programming error to call this function on a non-standard index, such one other than a straight index with ascending and descending. - -Returns -------- - -A string that should be freed with :symbol:`bson:bson_free()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_read_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_read_command_with_opts.rst deleted file mode 100644 index bf3f3fb79201925fcb6cc756e35cefca9f30a8dc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_read_command_with_opts.rst +++ /dev/null @@ -1,59 +0,0 @@ -:man_page: mongoc_collection_read_command_with_opts - -mongoc_collection_read_command_with_opts() -========================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_read_command_with_opts (mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic that is specific to commands that read, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_collection_command_simple`. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/read-cmd-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -.. include:: includes/retryable-read.txt -.. |generic-cmd| replace:: :symbol:`mongoc_collection_command_with_opts` -.. include:: includes/retryable-read-command.txt - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_read_write_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_read_write_command_with_opts.rst deleted file mode 100644 index 877966119f43fa0b40cf5781404632e95c605f54..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_read_write_command_with_opts.rst +++ /dev/null @@ -1,60 +0,0 @@ -:man_page: mongoc_collection_read_write_command_with_opts - -mongoc_collection_read_write_command_with_opts() -================================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_read_write_command_with_opts ( - mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* UNUSED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic for commands that both read and write, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_collection_command_simple`. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/read-write-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -(The :symbol:`mongoc_read_prefs_t` parameter was included by mistake when this function was introduced in libmongoc 1.5. A command that writes must not obey a read preference.) - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: Ignored. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_remove.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_remove.rst deleted file mode 100644 index 6a867f9d828377d760823519b2c90f8b2fe084d8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_remove.rst +++ /dev/null @@ -1,45 +0,0 @@ -:man_page: mongoc_collection_remove - -mongoc_collection_remove() -========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_remove (mongoc_collection_t *collection, - mongoc_remove_flags_t flags, - const bson_t *selector, - const mongoc_write_concern_t *write_concern, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A :symbol:`mongoc_remove_flags_t`. -* ``selector``: A :symbol:`bson:bson_t` containing the query to match documents. -* ``write_concern``: A :symbol:`mongoc_write_concern_t` or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Superseded by :symbol:`mongoc_collection_delete_one` and :symbol:`mongoc_collection_delete_many`. - -This function shall remove documents in the given ``collection`` that match ``selector``. The bson ``selector`` is not validated, simply passed along as appropriate to the server. As such, compatibility and errors should be validated in the appropriate server documentation. - -If you want to limit deletes to a single document, provide ``MONGOC_REMOVE_SINGLE_REMOVE`` in ``flags``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_rename.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_rename.rst deleted file mode 100644 index 1fc5c4297920b23735806cd03bc53560264af2af..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_rename.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_collection_rename - -mongoc_collection_rename() -========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_rename (mongoc_collection_t *collection, - const char *new_db, - const char *new_name, - bool drop_target_before_rename, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``new_db``: The name of the new database. -* ``new_name``: The new name for the collection. -* ``drop_target_before_rename``: If an existing collection matches the new name, drop it before the rename. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -For more information, see :symbol:`mongoc_collection_rename_with_opts()`. This function is a thin wrapper, passing ``NULL`` in as :symbol:`opts <bson:bson_t>` parameter. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_rename_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_rename_with_opts.rst deleted file mode 100644 index 925fd2dc55ce1265adb7270e8391a9e9e6acca0c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_rename_with_opts.rst +++ /dev/null @@ -1,48 +0,0 @@ -:man_page: mongoc_collection_rename_with_opts - -mongoc_collection_rename_with_opts() -==================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_rename_with_opts (mongoc_collection_t *collection, - const char *new_db, - const char *new_name, - bool drop_target_before_rename, - const bson_t *opts, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``new_db``: The name of the new database. -* ``new_name``: The new name for the collection. -* ``drop_target_before_rename``: If an existing collection matches the new name, drop it before the rename. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/write-opts.txt - -Description ------------ - -This function is a helper to rename an existing collection on a MongoDB server. The name of the collection will also be updated internally so it is safe to continue using this collection after the rename. Additional operations will occur on renamed collection. - -If no write concern is provided in ``opts``, the collection's write concern is used. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_replace_one.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_replace_one.rst deleted file mode 100644 index cb74c6a091f5043b68e80aca1c1d233f06b7fdff..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_replace_one.rst +++ /dev/null @@ -1,57 +0,0 @@ -:man_page: mongoc_collection_replace_one - -mongoc_collection_replace_one() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_replace_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *replacement, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``selector``: A :symbol:`bson:bson_t` containing the query to match the document for updating. -* ``replacement``: A :symbol:`bson:bson_t` containing the replacement document. -* ``reply``: Optional. An uninitialized :symbol:`bson:bson_t` populated with the update result, or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/replace-one-opts.txt - -Description ------------ - -This function shall replace documents in ``collection`` that match ``selector`` with ``replacement``. - -If provided, ``reply`` will be initialized and populated with the fields ``matchedCount``, ``modifiedCount``, ``upsertedCount``, and optionally ``upsertedId`` if applicable. If there is a server error then ``reply`` contains either a ``writeErrors`` array with one subdocument or a ``writeConcernErrors`` array. The reply must be freed with :symbol:`bson:bson_destroy`. - -See Also --------- - -`MongoDB update command documentation <https://docs.mongodb.com/master/reference/command/update/>`_ for more information on the update options. - -:symbol:`mongoc_collection_update_one` -:symbol:`mongoc_collection_update_many` - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_save.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_save.rst deleted file mode 100644 index f55bfa02b3cd4711e00151f1a05a118d92e6b4c9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_save.rst +++ /dev/null @@ -1,51 +0,0 @@ -:man_page: mongoc_collection_save - -mongoc_collection_save() -======================== - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_collection_insert_one()` or -:symbol:`mongoc_collection_replace_one()` with "upsert" instead. - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_save (mongoc_collection_t *collection, - const bson_t *document, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_insert_one or - mongoc_collection_replace_one); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``document``: A :symbol:`bson:bson_t` containing the document. -* ``write_concern``: A :symbol:`mongoc_write_concern_t` or ``NULL`` for default write concern. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function shall save a document into ``collection``. If the document has an ``_id`` field it will be updated. Otherwise it will be inserted. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_set_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_set_read_concern.rst deleted file mode 100644 index e118598f5618410adfaa7937af0fb91f205c7162..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_set_read_concern.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_collection_set_read_concern - -mongoc_collection_set_read_concern() -==================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_collection_set_read_concern (mongoc_collection_t *collection, - const mongoc_read_concern_t *read_concern); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``read_concern``: A :symbol:`mongoc_read_concern_t`. - -Description ------------ - -Sets the read concern to use for operations on ``collection``. - -The default read concern is empty: No readConcern is sent to the server unless explicitly configured. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_set_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_set_read_prefs.rst deleted file mode 100644 index 1337d4bc4446e8473e5a2e57511b88413b597052..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_set_read_prefs.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_collection_set_read_prefs - -mongoc_collection_set_read_prefs() -================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_collection_set_read_prefs (mongoc_collection_t *collection, - const mongoc_read_prefs_t *read_prefs); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - -Description ------------ - -Sets the default read preferences to use for operations on ``collection`` not specifying a read preference. - -The global default is MONGOC_READ_PRIMARY: if the client is connected to a replica set it reads from the primary, otherwise it reads from the current MongoDB server. - -Please see the MongoDB website for a description of `Read Preferences <http://docs.mongodb.org/manual/core/read-preference/>`_. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_set_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_set_write_concern.rst deleted file mode 100644 index d4011e988718d93b9aed6c03bff019d251975507..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_set_write_concern.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_collection_set_write_concern - -mongoc_collection_set_write_concern() -===================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_collection_set_write_concern ( - mongoc_collection_t *collection, - const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Sets the write concern to use for operations on ``collection``. - -The default write concern is MONGOC_WRITE_CONCERN_W_DEFAULT: the driver blocks awaiting basic acknowledgement of write operations from MongoDB. This is the correct write concern for the great majority of applications. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_stats.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_stats.rst deleted file mode 100644 index 1d64c9bf47c942dd283a1677c524e145955597ae..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_stats.rst +++ /dev/null @@ -1,48 +0,0 @@ -:man_page: mongoc_collection_stats - -mongoc_collection_stats() -========================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_stats (mongoc_collection_t *collection, - const bson_t *options, - bson_t *reply, - bson_error_t *error) BSON_GNUC_DEPRECATED; - -Deprecated ----------- - -This helper function is deprecated and should not be used in new code. Run the `collStats <https://docs.mongodb.com/manual/reference/command/collStats/>`_ command directly with :symbol:`mongoc_client_read_command_with_opts()` instead. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``options``: An optional :symbol:`bson:bson_t` containing extra options to pass to the ``collStats`` command. -* ``reply``: An uninitialized :symbol:`bson:bson_t` to store the result. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Run the ``collStats`` command to retrieve statistics about the collection. - -The command uses the :symbol:`mongoc_read_prefs_t` set on ``collection``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -``reply`` is always initialized and must be freed with :symbol:`bson:bson_destroy`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_t.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_t.rst deleted file mode 100644 index 187b4c44ed41d6927ba01e882f8625baf11d2591..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_t.rst +++ /dev/null @@ -1,85 +0,0 @@ -:man_page: mongoc_collection_t - -mongoc_collection_t -=================== - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct _mongoc_collection_t mongoc_collection_t; - -``mongoc_collection_t`` provides access to a MongoDB collection. This handle is useful for actions for most CRUD operations, I.e. insert, update, delete, find, etc. - -Read Preferences and Write Concerns ------------------------------------ - -Read preferences and write concerns are inherited from the parent client. They can be overridden by set_* commands if so desired. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_collection_aggregate - mongoc_collection_command - mongoc_collection_command_simple - mongoc_collection_command_with_opts - mongoc_collection_copy - mongoc_collection_count_documents - mongoc_collection_estimated_document_count - mongoc_collection_count - mongoc_collection_count_with_opts - mongoc_collection_create_bulk_operation - mongoc_collection_create_bulk_operation_with_opts - mongoc_collection_create_index - mongoc_collection_create_index_with_opts - mongoc_collection_delete - mongoc_collection_delete_many - mongoc_collection_delete_one - mongoc_collection_destroy - mongoc_collection_drop - mongoc_collection_drop_index - mongoc_collection_drop_index_with_opts - mongoc_collection_drop_with_opts - mongoc_collection_ensure_index - mongoc_collection_find - mongoc_collection_find_and_modify - mongoc_collection_find_and_modify_with_opts - mongoc_collection_find_indexes - mongoc_collection_find_indexes_with_opts - mongoc_collection_find_with_opts - mongoc_collection_get_last_error - mongoc_collection_get_name - mongoc_collection_get_read_concern - mongoc_collection_get_read_prefs - mongoc_collection_get_write_concern - mongoc_collection_insert - mongoc_collection_insert_bulk - mongoc_collection_insert_many - mongoc_collection_insert_one - mongoc_collection_keys_to_index_string - mongoc_collection_read_command_with_opts - mongoc_collection_read_write_command_with_opts - mongoc_collection_remove - mongoc_collection_rename - mongoc_collection_rename_with_opts - mongoc_collection_replace_one - mongoc_collection_save - mongoc_collection_set_read_concern - mongoc_collection_set_read_prefs - mongoc_collection_set_write_concern - mongoc_collection_stats - mongoc_collection_update - mongoc_collection_update_one - mongoc_collection_update_many - mongoc_collection_validate - mongoc_collection_write_command_with_opts - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_update.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_update.rst deleted file mode 100644 index e2c2fee05359d1d8ed29e1bf8cae29fd4e9c45ec..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_update.rst +++ /dev/null @@ -1,49 +0,0 @@ -:man_page: mongoc_collection_update - -mongoc_collection_update() -========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_update (mongoc_collection_t *collection, - mongoc_update_flags_t flags, - const bson_t *selector, - const bson_t *update, - const mongoc_write_concern_t *write_concern, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``flags``: A bitwise or of :symbol:`mongoc_update_flags_t`. -* ``selector``: A :symbol:`bson:bson_t` containing the query to match documents for updating. -* ``update``: A :symbol:`bson:bson_t` containing the update to perform. If updating with a pipeline, a :symbol:`bson:bson_t` array. -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Superseded by :symbol:`mongoc_collection_update_one`, :symbol:`mongoc_collection_update_many`, and :symbol:`mongoc_collection_replace_one`. - -This function shall update documents in ``collection`` that match ``selector``. - -By default, updates only a single document. Set flags to ``MONGOC_UPDATE_MULTI_UPDATE`` to update multiple documents. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_update_many.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_update_many.rst deleted file mode 100644 index a902d633152bea6bcebf42863bc6c8b9f7c45e0f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_update_many.rst +++ /dev/null @@ -1,58 +0,0 @@ -:man_page: mongoc_collection_update_many - -mongoc_collection_update_many() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_update_many (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``selector``: A :symbol:`bson:bson_t` containing the query to match documents for updating. -* ``update``: A :symbol:`bson:bson_t` containing the update to perform. If updating with a pipeline, a :symbol:`bson:bson_t` array. -* ``reply``: Optional. An uninitialized :symbol:`bson:bson_t` populated with the update result, or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/update-many-opts.txt - -Description ------------ - -This function updates all documents in ``collection`` that match ``selector``. - -To update at most one document see :symbol:`mongoc_collection_update_one`. - -If you pass a non-NULL ``reply``, it is filled out with fields ``matchedCount``, ``modifiedCount``, and optionally ``upsertedId`` if applicable. If there is a server error then ``reply`` contains either a "writeErrors" array with one subdocument or a "writeConcernErrors" array. The reply must be freed with :symbol:`bson:bson_destroy`. - -See Also --------- - -`MongoDB update command documentation <https://docs.mongodb.com/master/reference/command/update/>`_ for more information on the update options. - -:symbol:`mongoc_collection_update_one` - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_update_one.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_update_one.rst deleted file mode 100644 index a3a7d4ff8d60bf22ba0170fbd6801ee39439e195..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_update_one.rst +++ /dev/null @@ -1,66 +0,0 @@ -:man_page: mongoc_collection_update_one - -mongoc_collection_update_one() -============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_update_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``selector``: A :symbol:`bson:bson_t` containing the query to match the document for updating. -* ``update``: A :symbol:`bson:bson_t` containing the update to perform. If updating with a pipeline, a :symbol:`bson:bson_t` array. -* ``reply``: Optional. An uninitialized :symbol:`bson:bson_t` populated with the update result, or ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/update-one-opts.txt - -Description ------------ - -This function updates at most one document in ``collection`` that matches ``selector``. - -To update multiple documents see :symbol:`mongoc_collection_update_many`. - -If you pass a non-NULL ``reply``, it is filled out with fields ``matchedCount``, ``modifiedCount``, and optionally ``upsertedId`` if applicable. If there is a server error then ``reply`` contains either a "writeErrors" array with one subdocument or a "writeConcernErrors" array. The reply must be freed with :symbol:`bson:bson_destroy`. - -See Also --------- - -`MongoDB update command documentation <https://docs.mongodb.com/master/reference/command/update/>`_ for more information on the update options. - -:symbol:`mongoc_collection_update_many` - -:symbol:`mongoc_collection_replace_one` - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - -Example -------- -.. literalinclude:: ../examples/example-update.c - :language: c - :caption: example-update.c diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_validate.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_validate.rst deleted file mode 100644 index 5e3537c59f371842a29f60bd4ad1d5083c89e91f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_validate.rst +++ /dev/null @@ -1,50 +0,0 @@ -:man_page: mongoc_collection_validate - -mongoc_collection_validate() -============================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_validate (mongoc_collection_t *collection, - const bson_t *options, - bson_t *reply, - bson_error_t *error); - -Deprecated ----------- - -This helper function is deprecated and should not be used in new code. Run the `validate <https://docs.mongodb.com/manual/reference/command/validate/>`_ command directly with :symbol:`mongoc_client_read_command_with_opts()` instead. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``options``: A :symbol:`bson:bson_t`. -* ``reply``: An optional location for a :symbol:`bson:bson_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function is a helper function to execute the ``validate`` MongoDB command. - -Currently, the only supported options are ``full``, which is a boolean and ``scandata``, also a boolean. - -See the MongoDB documentation for more information on this command. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -``reply`` is always initialized if it's not ``NULL`` and must be destroyed with :symbol:`bson:bson_destroy()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_watch.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_watch.rst deleted file mode 100644 index 256b6624a71893fcb2ebf3c3358d7c98f7597f1c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_watch.rst +++ /dev/null @@ -1,50 +0,0 @@ -:man_page: mongoc_collection_watch - -mongoc_collection_watch() -========================= - -Synopsis --------- - -.. code-block:: c - - mongoc_change_stream_t* - mongoc_collection_watch (const mongoc_collection_t *coll, - const bson_t *pipeline, - const bson_t *opts); - -A helper function to create a change stream. It is preferred to call this -function over using a raw aggregation to create a change stream. - -This function uses the read preference and read concern of the collection. If -the change stream needs to re-establish connection, the same read preference -will be used. This may happen if the change stream encounters a resumable error. - -.. warning:: - - A change stream is only supported with majority read concern. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``coll``: A :symbol:`mongoc_collection_t` specifying the collection which the change stream listens to. -* ``pipeline``: A :symbol:`bson:bson_t` representing an aggregation pipeline appended to the change stream. This may be an empty document. -* ``opts``: A :symbol:`bson:bson_t` containing change stream options. - -.. include:: includes/change-stream-opts.txt - -Returns -------- -A newly allocated :symbol:`mongoc_change_stream_t` which must be freed with -:symbol:`mongoc_change_stream_destroy` when no longer in use. The returned -:symbol:`mongoc_change_stream_t` is never ``NULL``. If there is an error, it can -be retrieved with :symbol:`mongoc_change_stream_error_document`, and subsequent -calls to :symbol:`mongoc_change_stream_next` will return ``false``. - -See Also --------- -:doc:`mongoc_client_watch` - -:doc:`mongoc_database_watch` diff --git a/lib/mongoc/libmongoc/doc/mongoc_collection_write_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_collection_write_command_with_opts.rst deleted file mode 100644 index 53a522411d760b7c9ab0d2e96105834414d40366..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_collection_write_command_with_opts.rst +++ /dev/null @@ -1,60 +0,0 @@ -:man_page: mongoc_collection_write_command_with_opts - -mongoc_collection_write_command_with_opts() -=========================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_collection_write_command_with_opts (mongoc_collection_t *collection, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic that is specific to commands that write, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_collection_command_simple`. - -.. |opts-source| replace:: ``collection`` - -.. include:: includes/write-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -Parameters ----------- - -* ``collection``: A :symbol:`mongoc_collection_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - -Basic Write Operations ----------------------- - -Do not use this function to call the basic write commands "insert", "update", and "delete". Those commands require special logic not implemented in ``mongoc_collection_write_command_with_opts``. For basic write operations use CRUD functions such as :symbol:`mongoc_collection_insert_one` and the others described in :ref:`the CRUD tutorial <tutorial_crud_operations>`, or use the :doc:`Bulk API <bulk>`. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_clone.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_clone.rst deleted file mode 100644 index 7186b82c09e0aecaa2bf957c90003b16e5724acd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_clone.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_cursor_clone - -mongoc_cursor_clone() -===================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_cursor_clone (const mongoc_cursor_t *cursor) - BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -This function shall create a copy of a :symbol:`mongoc_cursor_t`. The cloned cursor will be reset to the beginning of the query, and therefore the query will be re-executed on the MongoDB server when :symbol:`mongoc_cursor_next()` is called. - -Returns -------- - -A newly allocated :symbol:`mongoc_cursor_t` that should be freed with :symbol:`mongoc_cursor_destroy()` when no longer in use. - -.. warning:: - - Failure to handle the result of this function is a programming error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_current.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_current.rst deleted file mode 100644 index fc14ce2d7f531ea92edd9342b3dc95aa5a295f01..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_current.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_cursor_current - -mongoc_cursor_current() -======================= - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_cursor_current (const mongoc_cursor_t *cursor); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -Fetches the cursors current document or ``NULL`` if there has been an error. - -Returns -------- - -A :symbol:`bson:bson_t` that should not be modified or freed or ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_destroy.rst deleted file mode 100644 index 0848fc810b78d0d5cedc7f7e379eed6cc52e3415..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_cursor_destroy - -mongoc_cursor_destroy() -======================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_cursor_destroy (mongoc_cursor_t *cursor); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -Frees a :symbol:`mongoc_cursor_t` and releases all associated resources. If a server-side cursor has been allocated, it will be released as well. Does nothing if ``cursor`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_error.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_error.rst deleted file mode 100644 index f704f13443034f336bba979244c2f1524dbcf2e9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_error.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_cursor_error - -mongoc_cursor_error() -===================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function checks to see if an error has occurred while iterating the cursor. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -false if no error has occurred, otherwise true and error is set. - -.. only:: html - - .. taglist:: See Also: - :tags: cursor-error diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_error_document.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_error_document.rst deleted file mode 100644 index 059a29f361c5ea492de8388c6a6905b150376dca..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_error_document.rst +++ /dev/null @@ -1,137 +0,0 @@ -:man_page: mongoc_cursor_error_document - -mongoc_cursor_error_document() -============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_cursor_error_document (mongoc_cursor_t *cursor, - bson_error_t *error, - const bson_t **reply); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. -* ``reply``: A location for a :symbol:`const bson_t * <bson:bson_t>`. - -Description ------------ - -This function checks to see if an error has occurred while iterating the cursor. - -If an error occurred client-side, for example if there was a network error or timeout, or the cursor was created with invalid parameters, then ``reply`` is set to an empty BSON document. If an error occurred server-side, ``reply`` is set to the server's reply document with information about the error. - -Errors ------- - -Errors are propagated via the ``error`` and ``reply`` parameters. - -Returns -------- - -False if no error has occurred, otherwise true and ``error`` is set. - -If the function returns true and ``reply`` is not NULL, then ``reply`` is set to a pointer to a BSON document, which is either empty or the server's error response. The document is invalid after the cursor is freed with :symbol:`mongoc_cursor_destroy()`. - -Example -------- - -This example shows the difference between a client-side and server-side error. If the client cannot connect to the server, for example, the error message includes "No suitable servers found" and ``reply`` is set to an empty BSON document. - -On the other hand, if the client connects to the server successfully and attempts to execute an invalid query, the error message comes from the server and ``reply`` is set to the server's reply document, with fields ``errmsg`` and ``code``. - -.. code-block:: c - - void - run_query (const char *uri_str, const bson_t *query) - { - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - const bson_t *reply; - char *str; - - client = mongoc_client_new (uri_str); - - mongoc_client_set_error_api (client, 2); - - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find_with_opts ( - collection, - query, - NULL, /* additional options */ - NULL); /* read prefs, NULL for default */ - - /* this loop is never run: mongoc_cursor_next immediately returns false */ - while (mongoc_cursor_next (cursor, &doc)) { - } - - if (mongoc_cursor_error_document (cursor, &error, &reply)) { - str = bson_as_json (reply, NULL); - fprintf (stderr, "Cursor Failure: %s\nReply: %s\n", error.message, str); - bson_free (str); - } - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - } - - int - main (int argc, char *argv[]) - { - bson_t *good_query; - bson_t *bad_query; - - mongoc_init (); - - /* find documents matching the query {"x": 1} */ - good_query = BCON_NEW ("x", BCON_INT64 (1)); - - /* Cause a network error. This will print an error and empty reply document: - * - * Cursor Failure: No suitable servers found (`serverSelectionTryOnce` set): - * [Failed to resolve 'fake-domain'] - * - * Reply: { } - * - */ - run_query ("mongodb://fake-domain/?appname=cursor-example", good_query); - - /* invalid: {"x": {"$badOperator": 1}} */ - bad_query = BCON_NEW ("x", "{", "$badOperator", BCON_INT64 (1), "}"); - - /* Cause a server error. This will print an error and server reply document: - * - * Cursor Failure: unknown operator: $badOperator - * - * Reply: - * {"ok": 0.0, - * "errmsg":"unknown operator: $badOperator", - * "code": 2, - * "codeName":"BadValue" - * } - * - */ - run_query ("mongodb://localhost/?appname=cursor-example", bad_query); - - bson_destroy (good_query); - bson_destroy (bad_query); - - mongoc_cleanup (); - - return 0; - } - -.. only:: html - - .. taglist:: See Also: - :tags: cursor-error diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_batch_size.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_get_batch_size.rst deleted file mode 100644 index 8bb687701c9bef2772eb2e8be20eeec5e291928f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_batch_size.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_cursor_get_batch_size - -mongoc_cursor_get_batch_size() -============================== - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -Retrieve the cursor's batch size, the maximum number of documents returned per round trip to the server. A batch size of zero means the cursor accepts the server's maximum batch size. - -See `Cursor Batches <https://docs.mongodb.org/manual/core/cursors/#cursor-batches>`_ in the MongoDB Manual. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_hint.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_get_hint.rst deleted file mode 100644 index 153f36563a30fe4f9df39b6147715481b4ce3d50..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_hint.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_cursor_get_hint - -mongoc_cursor_get_hint() -======================== - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_cursor_get_hint (const mongoc_cursor_t *cursor); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -Retrieves the opaque id of the server used for the operation. - -(The function name includes the old term "hint" for the sake of backward compatibility, but we now call this number a "server id".) - -This number is zero until the driver actually uses a server when executing the find operation or :symbol:`mongoc_cursor_set_hint` is called. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_host.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_get_host.rst deleted file mode 100644 index 475656590f25f7c2630f9331893daf603e13823f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_host.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_cursor_get_host - -mongoc_cursor_get_host() -======================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. -* ``host``: A :symbol:`mongoc_host_list_t`. - -Description ------------ - -Fetches the MongoDB host that the cursor is communicating with in the ``host`` out parameter. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_id.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_get_id.rst deleted file mode 100644 index cbf2426428fa008c96a7b55031f95e02f9a07b84..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_id.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_cursor_get_id - -mongoc_cursor_get_id() -====================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_cursor_get_id (const mongoc_cursor_t *cursor); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -Retrieves the cursor id used by the server to track the cursor. - -This number is zero until the driver actually uses a server when executing the query, and after it has fetched all results from the server. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_limit.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_get_limit.rst deleted file mode 100644 index f9557e52847f00eddb60be4d9210590fe5def8df..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_limit.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_cursor_get_limit - -mongoc_cursor_get_limit() -========================= - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_cursor_get_limit (mongoc_cursor_t *cursor); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -Return the value set with :symbol:`mongoc_cursor_set_limit` or :symbol:`mongoc_collection_find`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_max_await_time_ms.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_get_max_await_time_ms.rst deleted file mode 100644 index 4a056ef2f662b1cd40d94b933b7aeb81ca0052bf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_get_max_await_time_ms.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_cursor_get_max_await_time_ms - -mongoc_cursor_get_max_await_time_ms() -===================================== - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_cursor_get_max_await_time_ms (mongoc_cursor_t *cursor); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -Retrieve the value set with :symbol:`mongoc_cursor_set_max_await_time_ms`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_is_alive.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_is_alive.rst deleted file mode 100644 index 7d919ac9dd21f958e038559b4e2a09f9dba4c19c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_is_alive.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_cursor_is_alive - -mongoc_cursor_is_alive() -======================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_cursor_is_alive (const mongoc_cursor_t *cursor) - BSON_GNUC_DEPRECATED_FOR (mongoc_cursor_more); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Deprecated ----------- - -This function is superseded by :symbol:`mongoc_cursor_more()`, which has equivalent behavior. - -Returns -------- - -See :symbol:`mongoc_cursor_more()`. diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_more.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_more.rst deleted file mode 100644 index 6d25cf52adb89619a2555ad69061632fb3e50a86..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_more.rst +++ /dev/null @@ -1,37 +0,0 @@ -:man_page: mongoc_cursor_more - -mongoc_cursor_more() -==================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_cursor_more (mongoc_cursor_t *cursor); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. - -Description ------------ - -This function shall indicate if there is *potentially* more data to be read from the cursor. This is only useful with tailable cursors. Use :symbol:`mongoc_cursor_next` for regular cursors. - -Details: ``mongoc_cursor_more`` is unreliable because it does not contact the server to see if there are actually more documents in the result set. It simply returns true if the cursor has not begun, or if it has begun and there are buffered documents in the client-side cursor, or if it has begun and the server has not yet told the cursor it is completely iterated. - -This is unreliable with regular queries because it returns true for a new cursor before iteration, even if the cursor will match no documents. It is also true if the collection has been dropped on the server since the previous fetch, or if the cursor has finished its final batch and the next batch will be empty. - -Returns -------- - -true if the cursor has locally-buffered documents, or if a round-trip to the server might fetch additional documents. - -See Also --------- - -:ref:`Tailable Cursor Example <cursors_tailable>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_new_from_command_reply.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_new_from_command_reply.rst deleted file mode 100644 index e323087838ae599d005ca4f7bb87827637c7621a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_new_from_command_reply.rst +++ /dev/null @@ -1,66 +0,0 @@ -:man_page: mongoc_cursor_new_from_command_reply - -mongoc_cursor_new_from_command_reply() -====================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_cursor_new_from_command_reply (mongoc_client_t *client, - bson_t *reply, - uint32_t server_id); - BSON_GNUC_DEPRECATED_FOR (mongoc_cursor_new_from_command_reply_with_opts); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_cursor_new_from_command_reply_with_opts()` instead. - -When migrating from the deprecated :symbol:`mongoc_cursor_new_from_command_reply()` to :symbol:`mongoc_cursor_new_from_command_reply_with_opts()`, -note that options previously passed to the ``reply`` argument (e.g. "batchSize") must instead be provided in the ``opts`` argument. - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``reply``: The reply to a command, such as "aggregate", "find", or "listCollections", that returns a cursor document. The reply is destroyed by ``mongoc_cursor_new_from_command_reply`` and must not be accessed afterward. -* ``server_id``: The opaque id of the server used to execute the command. - -Description ------------ - -Some MongoDB commands return a "cursor" document. For example, given an "aggregate" command: - -.. code-block:: none - - { "aggregate" : "collection", "pipeline" : [], "cursor" : {}} - -The server replies: - -.. code-block:: none - - { - "cursor" : { - "id" : 1234, - "ns" : "db.collection", - "firstBatch" : [ ] - }, - "ok" : 1 - } - -``mongoc_cursor_new_from_command_reply`` is a low-level function that initializes a :symbol:`mongoc_cursor_t` from such a reply. Additional options such as "tailable" or "awaitData" can be included in the reply. - -When synthesizing a completed cursor response that has no more batches (i.e. with cursor id 0), set ``server_id`` to 0 as well. - -Use this function only for building a language driver that wraps the C Driver. When writing applications in C, higher-level functions such as :symbol:`mongoc_collection_aggregate` are more appropriate, and ensure compatibility with a range of MongoDB versions. - -Returns -------- - -A :symbol:`mongoc_cursor_t`. On failure, the cursor's error is set. Check for failure with :symbol:`mongoc_cursor_error`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_new_from_command_reply_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_new_from_command_reply_with_opts.rst deleted file mode 100644 index 35b24759b862def1634e84d7925b5e735b75b4fc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_new_from_command_reply_with_opts.rst +++ /dev/null @@ -1,64 +0,0 @@ -:man_page: mongoc_cursor_new_from_command_reply_with_opts - -mongoc_cursor_new_from_command_reply_with_opts() -================================================ - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_cursor_new_from_command_reply_with_opts (mongoc_client_t *client, - bson_t *reply, - const bson_t *opts); - -Parameters ----------- - -* ``client``: A :symbol:`mongoc_client_t`. -* ``reply``: The reply to a command, such as "aggregate", "find", or "listCollections", that returns a cursor document. The reply is destroyed by ``mongoc_cursor_new_from_command_reply_with_opts`` and must not be accessed afterward. -* ``opts``: A :symbol:`bson:bson_t`. - -``opts`` may be NULL or a BSON document with additional options, which have the same meaning for this function as for :symbol:`mongoc_collection_find_with_opts`: - -* ``awaitData`` -* ``batchSize`` -* ``limit`` -* ``maxAwaitTimeMS`` -* ``serverId`` -* ``sessionId`` -* ``skip`` -* ``tailable`` - -Description ------------ - -Some MongoDB commands return a "cursor" document. For example, given an "aggregate" command: - -.. code-block:: none - - { "aggregate" : "collection", "pipeline" : [], "cursor" : {}} - -The server replies: - -.. code-block:: none - - { - "cursor" : { - "id" : 1234, - "ns" : "db.collection", - "firstBatch" : [ ] - }, - "ok" : 1 - } - -``mongoc_cursor_new_from_command_reply_with_opts`` is a low-level function that initializes a :symbol:`mongoc_cursor_t` from such a reply. - -Use this function only for building a language driver that wraps the C Driver. When writing applications in C, higher-level functions such as :symbol:`mongoc_collection_aggregate` are more appropriate, and ensure compatibility with a range of MongoDB versions. - -Returns -------- - -A :symbol:`mongoc_cursor_t`. On failure, the cursor's error is set. Check for failure with :symbol:`mongoc_cursor_error`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_next.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_next.rst deleted file mode 100644 index 6c398f2e6b44093b505658aca71b79b629b0f5a5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_next.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_cursor_next - -mongoc_cursor_next() -==================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. -* ``bson``: A location for a :symbol:`const bson_t * <bson:bson_t>`. - -Description ------------ - -This function shall iterate the underlying cursor, setting ``bson`` to the next document. - -This function is a blocking function. - -Returns -------- - -This function returns true if a valid bson document was read from the cursor. Otherwise, false if there was an error or the cursor was exhausted. - -Errors can be determined with the :symbol:`mongoc_cursor_error()` function. - -Lifecycle ---------- - -The bson objects set in this function are ephemeral and good until the next call. This means that you must copy the returned bson if you wish to retain it beyond the lifetime of a single call to :symbol:`mongoc_cursor_next()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_set_batch_size.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_set_batch_size.rst deleted file mode 100644 index a78afc7c8df4339e7d0958f0c0963bde6d103eb2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_set_batch_size.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_cursor_set_batch_size - -mongoc_cursor_set_batch_size() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. -* ``batch_size``: The requested number of documents per batch. - -Description ------------ - -Limits the number of documents returned in one batch. Each batch requires a round trip to the server. If the batch size is zero, the cursor uses the server-defined maximum batch size. - -See `Cursor Batches <https://docs.mongodb.org/manual/core/cursors/#cursor-batches>`_ in the MongoDB Manual. - -This is not applicable to all cursors. Calling :symbol:`mongoc_cursor_set_batch_size` on a cursor returned by :symbol:`mongoc_client_find_databases_with_opts`, :symbol:`mongoc_database_find_collections_with_opts`, or :symbol:`mongoc_collection_find_indexes_with_opts` will not change the results. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_set_hint.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_set_hint.rst deleted file mode 100644 index 853d11aad0ee00b33b212db6f50ebb23b38dc1dc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_set_hint.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_cursor_set_hint - -mongoc_cursor_set_hint() -======================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_cursor_set_hint (mongoc_cursor_t *cursor, uint32_t server_id); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. -* ``server_id``: An opaque id identifying the server to use. - -Description ------------ - -Specifies which server to use for the operation. This function has an effect only if called before the find operation is executed. - -(The function name includes the old term "hint" for the sake of backward compatibility, but we now call this number a "server id".) - -Use ``mongoc_cursor_set_hint`` only for building a language driver that wraps the C Driver. When writing applications in C, leave the server id unset and allow the driver to choose a suitable server from the find operation's read preference. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and logs an error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_set_limit.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_set_limit.rst deleted file mode 100644 index cd8efa53a1ee860f2ff47cd213d63711a4481166..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_set_limit.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_cursor_set_limit - -mongoc_cursor_set_limit() -========================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_cursor_set_limit (mongoc_cursor_t *cursor, int64_t limit); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. -* ``limit``: The maximum number of documents to retrieve for this query. - -Description ------------ - -Limits the number of documents in the result set. - -This function is useful for setting the limit on a cursor after the cursor is created, but before any calls to :symbol:`mongoc_cursor_next`. It can also be used to pass a negative limit: The ``limit`` parameter to ``mongoc_cursor_set_limit`` is signed, although for backward-compatibility reasons the ``limit`` parameter to :symbol:`mongoc_collection_find` is not. - -Calling this function after :symbol:`mongoc_cursor_next` has no effect. - -This is not applicable to all cursors. Calling :symbol:`mongoc_cursor_set_limit` on a cursor returned by :symbol:`mongoc_client_find_databases_with_opts`, :symbol:`mongoc_database_find_collections_with_opts`, or :symbol:`mongoc_collection_find_indexes_with_opts` will not change the results. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and leaves the limit unchanged. diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_set_max_await_time_ms.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_set_max_await_time_ms.rst deleted file mode 100644 index 5cf467a02d8cbd7afa064db1f9dc6663f982d404..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_set_max_await_time_ms.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_cursor_set_max_await_time_ms - -mongoc_cursor_set_max_await_time_ms() -===================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_cursor_set_max_await_time_ms (mongoc_cursor_t *cursor, - uint32_t max_await_time_ms); - -Parameters ----------- - -* ``cursor``: A :symbol:`mongoc_cursor_t`. -* ``max_await_time_ms``: A timeout in milliseconds. - -Description ------------ - -The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Only applies if the cursor is created from :symbol:`mongoc_collection_find_with_opts` with "tailable" and "awaitData" options, and the server is MongoDB 3.2 or later. See `the documentation for maxTimeMS and the "getMore" command <https://docs.mongodb.org/master/reference/command/getMore/>`_. - -The ``max_await_time_ms`` cannot be changed after the first call to :symbol:`mongoc_cursor_next`. - -This is not applicable to all cursors. Calling :symbol:`mongoc_cursor_set_batch_size` on a cursor returned by :symbol:`mongoc_client_find_databases_with_opts`, :symbol:`mongoc_database_find_collections_with_opts`, or :symbol:`mongoc_collection_find_indexes_with_opts` will not change the results. - -Note: although ``max_await_time_ms`` is a uint32_t, it is possible to set it as a uint64_t through the options arguments in some cursor returning functions like :symbol:`mongoc_collection_find_with_opts()`. - -See Also --------- - -:ref:`Tailable Cursors. <cursors_tailable>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_cursor_t.rst b/lib/mongoc/libmongoc/doc/mongoc_cursor_t.rst deleted file mode 100644 index 2f1891043ed71ce121280095567e3e93b6ea6a07..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_cursor_t.rst +++ /dev/null @@ -1,68 +0,0 @@ -:man_page: mongoc_cursor_t - -mongoc_cursor_t -=============== - -Client-side cursor abstraction - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_cursor_t mongoc_cursor_t; - -``mongoc_cursor_t`` provides access to a MongoDB query cursor. -It wraps up the wire protocol negotiation required to initiate a query and retrieve an unknown number of documents. - -Common cursor operations include: - -* Determine which host we've connected to with :symbol:`mongoc_cursor_get_host()`. -* Retrieve more records with repeated calls to :symbol:`mongoc_cursor_next()`. -* Clone a query to repeat execution at a later point with :symbol:`mongoc_cursor_clone()`. -* Test for errors with :symbol:`mongoc_cursor_error()`. - -Cursors are lazy, meaning that no connection is established and no network traffic occurs until the first call to :symbol:`mongoc_cursor_next()`. - -Thread Safety -------------- - -``mongoc_cursor_t`` is *NOT* thread safe. It may only be used from within the thread in which it was created. - -Example -------- - -.. literalinclude:: ../examples/example-client.c - :language: c - :caption: Query MongoDB and iterate results - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_cursor_clone - mongoc_cursor_current - mongoc_cursor_destroy - mongoc_cursor_error - mongoc_cursor_error_document - mongoc_cursor_get_batch_size - mongoc_cursor_get_hint - mongoc_cursor_get_host - mongoc_cursor_get_id - mongoc_cursor_get_limit - mongoc_cursor_get_max_await_time_ms - mongoc_cursor_is_alive - mongoc_cursor_more - mongoc_cursor_new_from_command_reply - mongoc_cursor_new_from_command_reply_with_opts - mongoc_cursor_next - mongoc_cursor_set_batch_size - mongoc_cursor_set_hint - mongoc_cursor_set_limit - mongoc_cursor_set_max_await_time_ms - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_add_user.rst b/lib/mongoc/libmongoc/doc/mongoc_database_add_user.rst deleted file mode 100644 index f8e6e9f6c21fa3117d79840597a1f84df32a2668..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_add_user.rst +++ /dev/null @@ -1,44 +0,0 @@ -:man_page: mongoc_database_add_user - -mongoc_database_add_user() -========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_add_user (mongoc_database_t *database, - const char *username, - const char *password, - const bson_t *roles, - const bson_t *custom_data, - bson_error_t *error); - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``username``: The name of the user. -* ``password``: The cleartext password for the user. -* ``roles``: An optional :symbol:`bson:bson_t` for roles. -* ``custom_data``: A optional :symbol:`bson:bson_t` for extra data. -* ``error``: A location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -This function shall create a new user with access to ``database``. - -.. warning:: - - Do not call this function without TLS. - -Errors ------- - -Errors are returned through the ``error`` parameter and can include socket or other server side failures. - -Returns -------- - -Returns ``true`` if the user was successfully added. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_aggregate.rst b/lib/mongoc/libmongoc/doc/mongoc_database_aggregate.rst deleted file mode 100644 index 05d7dfc81892fd33c82edccf61eeaea0a768d4ed..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_aggregate.rst +++ /dev/null @@ -1,94 +0,0 @@ -:man_page: mongoc_database_aggregate - -mongoc_database_aggregate() -=========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_database_aggregate (mongoc_database_t *database, - const bson_t *pipeline, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``pipeline``: A :symbol:`bson:bson_t`, either a BSON array or a BSON document containing an array field named "pipeline". -* ``opts``: A :symbol:`bson:bson_t` containing options for the command, or ``NULL``. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` or ``NULL``. - -.. |opts-source| replace:: ``database`` - -.. include:: includes/aggregate-opts.txt - -For a list of all options, see `the MongoDB Manual entry on the aggregate command <http://docs.mongodb.org/manual/reference/command/aggregate/>`_. - -Description ------------ - -This function creates a cursor which sends the aggregate command on the underlying database upon the first call to :symbol:`mongoc_cursor_next()`. For more information on building aggregation pipelines, see `the MongoDB Manual entry on the aggregate command <http://docs.mongodb.org/manual/reference/command/aggregate/>`_. Note that the pipeline must start with a compatible stage that does not require an underlying collection (e.g. "$currentOp", "$listLocalSessions"). - -Read preferences, read and write concern, and collation can be overridden by various sources. The highest-priority sources for these options are listed first in the following table. In a transaction, read concern and write concern are prohibited in ``opts`` and the read preference must be primary or NULL. Write concern is applied from ``opts``, or if ``opts`` has no write concern and the aggregation pipeline includes "$out", the write concern is applied from ``database``. - -================== ============== ============== ========= -Read Preferences Read Concern Write Concern Collation -================== ============== ============== ========= -``read_prefs`` ``opts`` ``opts`` ``opts`` -Transaction Transaction Transaction -``database`` ``database`` ``database`` -================== ============== ============== ========= - -:ref:`See the example for transactions <mongoc_client_session_start_transaction_example>` and for :ref:`the "distinct" command with opts <mongoc_client_read_command_with_opts_example>`. - -.. include:: includes/retryable-read-aggregate.txt - -Returns -------- - -This function returns a newly allocated :symbol:`mongoc_cursor_t` that should be freed with :symbol:`mongoc_cursor_destroy()` when no longer in use. The returned :symbol:`mongoc_cursor_t` is never ``NULL``; if the parameters are invalid, the :symbol:`bson:bson_error_t` in the :symbol:`mongoc_cursor_t` is filled out, and the :symbol:`mongoc_cursor_t` is returned before the server is selected. The user must call :symbol:`mongoc_cursor_next()` on the returned :symbol:`mongoc_cursor_t` to execute the aggregation pipeline. - -.. warning:: - - Failure to handle the result of this function is a programming error. - -Example -------- - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - - static mongoc_cursor_t * - current_op_query (mongoc_client_t *client) - { - mongoc_cursor_t *cursor; - mongoc_database_t *database; - bson_t *pipeline; - - pipeline = BCON_NEW ("pipeline", - "[", - "{", - "$currentOp", - "{", - "}", - "}", - "]"); - - /* $currentOp must be run on the admin database */ - database = mongoc_client_get_database (client, "admin"); - - cursor = mongoc_database_aggregate ( - database, pipeline, NULL, NULL); - - bson_destroy (pipeline); - mongoc_database_destroy (database); - - return cursor; - } diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_command.rst b/lib/mongoc/libmongoc/doc/mongoc_database_command.rst deleted file mode 100644 index 3b3cb726f7404bc8d8c0d1f7c6d0d5b4761d4016..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_command.rst +++ /dev/null @@ -1,48 +0,0 @@ -:man_page: mongoc_database_command - -mongoc_database_command() -========================= - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_database_command (mongoc_database_t *database, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *command, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs); - -This function is superseded by :symbol:`mongoc_database_command_with_opts()`, :symbol:`mongoc_database_read_command_with_opts()`, :symbol:`mongoc_database_write_command_with_opts()`, and :symbol:`mongoc_database_read_write_command_with_opts()`. - -Description ------------ - -This function creates a cursor which will execute the command when :symbol:`mongoc_cursor_next` is called on it. The database's read preference, read concern, and write concern are not applied to the command, and :symbol:`mongoc_cursor_next` will not check the server response for a write concern error or write concern timeout. - -.. include:: includes/not-retryable-read.txt - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``flags``: A :symbol:`mongoc_query_flags_t`. -* ``skip``: The number of documents to skip on the server. -* ``limit``: The maximum number of documents to return from the cursor. -* ``batch_size``: Attempt to batch results from the server in groups of ``batch_size`` documents. -* ``command``: A :symbol:`bson:bson_t` containing the command. -* ``fields``: An optional :symbol:`bson:bson_t` containing the fields to return. ``NULL`` for all fields. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. Otherwise, the command uses mode ``MONGOC_READ_PRIMARY``. - -Returns -------- - -A :symbol:`mongoc_cursor_t`. - -The cursor should be freed with :symbol:`mongoc_cursor_destroy()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_command_simple.rst b/lib/mongoc/libmongoc/doc/mongoc_database_command_simple.rst deleted file mode 100644 index fdf768fdf1362be1eda0c05d06df04d6d7e9b3af..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_command_simple.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_database_command_simple - -mongoc_database_command_simple() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_command_simple (mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. Otherwise, the command uses mode ``MONGOC_READ_PRIMARY``. -* ``reply``: A location to store the commands first result document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -This is a simplified interface to :symbol:`mongoc_database_command()` that returns the first result document. The database's read preference, read concern, and write concern are not applied to the command. The parameter ``reply`` is initialized even upon failure to simplify memory management. - -.. include:: includes/not-retryable-read.txt - -Errors ------- - -Errors are propagated through the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -This function does not check the server response for a write concern error or write concern timeout. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_database_command_with_opts.rst deleted file mode 100644 index 1f9aaa2837255a28a99dce6642169a012767705b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_command_with_opts.rst +++ /dev/null @@ -1,60 +0,0 @@ -:man_page: mongoc_database_command_with_opts - -mongoc_database_command_with_opts() -=================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_command_with_opts ( - mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, interpreting ``opts`` according to the MongoDB server version. To send a raw command to the server without any of this logic, use :symbol:`mongoc_client_command_simple`. - -.. |opts-source| replace:: ``database`` - -.. include:: includes/opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -.. include:: includes/not-retryable-read.txt - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -The reply is not parsed for a write concern timeout or write concern error. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_copy.rst b/lib/mongoc/libmongoc/doc/mongoc_database_copy.rst deleted file mode 100644 index 2e4dada95715a138fedf3dec34846a0fab65b4c6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_copy.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_database_copy - -mongoc_database_copy() -====================== - -Synopsis --------- - -.. code-block:: c - - mongoc_database_t * - mongoc_database_copy (mongoc_database_t *database); - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. - -Description ------------ - -Performs a deep copy of the ``database`` struct and its configuration. Useful if you intend to call :symbol:`mongoc_database_set_write_concern`, :symbol:`mongoc_database_set_read_prefs`, or :symbol:`mongoc_database_set_read_concern`, and want to preserve an unaltered copy of the struct. - -Returns -------- - -A newly allocated :symbol:`mongoc_database_t` that should be freed with :symbol:`mongoc_database_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_create_collection.rst b/lib/mongoc/libmongoc/doc/mongoc_database_create_collection.rst deleted file mode 100644 index 1c6f279158b541b2afc8f95de75cacce697c949a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_create_collection.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_database_create_collection - -mongoc_database_create_collection() -=================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_collection_t * - mongoc_database_create_collection (mongoc_database_t *database, - const char *name, - const bson_t *opts, - bson_error_t *error); - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``name``: The name of the new collection. -* ``opts``: An optional :symbol:`bson:bson_t` for opts to the ``create`` command. -* ``error``: A location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function creates a :symbol:`mongoc_collection_t` from the given :symbol:`mongoc_database_t`. - -If no write concern is provided in ``opts``, the database's write concern is used. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -This function returns a newly allocated :symbol:`mongoc_collection_t` upon success, ``NULL`` upon failure and ``error`` is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_database_destroy.rst deleted file mode 100644 index 0b1b79c85723297861b59f4fb7a8a1cd2117c102..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_destroy.rst +++ /dev/null @@ -1,20 +0,0 @@ -:man_page: mongoc_database_destroy - -mongoc_database_destroy() -========================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_database_destroy (mongoc_database_t *database); - -Releases all resources associated with ``database``, including freeing the structure. Does nothing if ``database`` is NULL. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_drop.rst b/lib/mongoc/libmongoc/doc/mongoc_database_drop.rst deleted file mode 100644 index 67689a23600c714c1f4a1e5936894b1da42e15cd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_drop.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_database_drop - -mongoc_database_drop() -====================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_drop (mongoc_database_t *database, bson_error_t *error); - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -For more information, see :symbol:`mongoc_database_drop_with_opts()`. This function is a thin wrapper, passing ``NULL`` in as :symbol:`opts <bson:bson_t>` parameter. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_drop_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_database_drop_with_opts.rst deleted file mode 100644 index c98e97a2264bcd338a508a9e48294e0c37b81ca4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_drop_with_opts.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_database_drop_with_opts - -mongoc_database_drop_with_opts() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_drop_with_opts (mongoc_database_t *database, - const bson_t *opts, - bson_error_t *error); - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``database`` - -.. include:: includes/write-opts.txt - -Description ------------ - -This function attempts to drop a database on the MongoDB server. - -If no write concern is provided in ``opts``, the database's write concern is used. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_find_collections.rst b/lib/mongoc/libmongoc/doc/mongoc_database_find_collections.rst deleted file mode 100644 index 34a58878e86ab76854b58ce67d39df9973796598..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_find_collections.rst +++ /dev/null @@ -1,47 +0,0 @@ -:man_page: mongoc_database_find_collections - -mongoc_database_find_collections() -================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_database_find_collections (mongoc_database_t *database, - const bson_t *filter, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_database_find_collections_with_opts); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_database_find_collections_with_opts()` instead. - -Description ------------ - -Fetches a cursor containing documents, each corresponding to a collection on this database. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``filter``: A matcher used by the server to filter the returned collections. May be ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -A cursor where each result corresponds to the server's representation of a collection in this database. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_find_collections_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_database_find_collections_with_opts.rst deleted file mode 100644 index 7ccca096039abb5e2fabc214f007c917529f8bea..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_find_collections_with_opts.rst +++ /dev/null @@ -1,79 +0,0 @@ -:man_page: mongoc_database_find_collections_with_opts - -mongoc_database_find_collections_with_opts() -============================================ - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_database_find_collections_with_opts (mongoc_database_t *database, - const bson_t *opts); - -Fetches a cursor containing documents, each corresponding to a collection on this database. - -To get collection names only, use :symbol:`mongoc_database_get_collection_names_with_opts`. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. - -.. |opts-source| replace:: ``database`` - -.. include:: includes/generic-opts.txt - -For a list of all options, see `the MongoDB Manual entry on the listCollections command <http://docs.mongodb.org/manual/reference/command/listCollections/>`_. - -Errors ------- - -Use :symbol:`mongoc_cursor_error` on the returned cursor to check for errors. - -Returns -------- - -A cursor where each result corresponds to the server's representation of a collection in this database. - -The cursor functions :symbol:`mongoc_cursor_set_limit`, :symbol:`mongoc_cursor_set_batch_size`, and :symbol:`mongoc_cursor_set_max_await_time_ms` have no use on the returned cursor. - -Examples --------- - -.. code-block:: c - - { - bson_t opts = BSON_INITIALIZER; - bson_t name_filter; - const bson_t *doc; - bson_iter_t iter; - bson_error_t error; - - BSON_APPEND_DOCUMENT_BEGIN (&opts, "filter", &name_filter); - /* find collections with names like "abbbbc" */ - BSON_APPEND_REGEX (&name_filter, "name", "ab+c", NULL); - bson_append_document_end (&opts, &name_filter); - - cursor = mongoc_database_find_collections_with_opts (database, &opts); - while (mongoc_cursor_next (cursor, &doc)) { - bson_iter_init_find (&iter, doc, "name"); - printf ("found collection: %s\n", bson_iter_utf8 (&iter, NULL)); - } - - if (mongoc_cursor_error (cursor, &error)) - fprintf (stderr, "%s\n", error.msg); - } - - mongoc_cursor_destroy (cursor); - bson_destroy (&opts); - } - -See Also --------- - -:symbol:`mongoc_database_get_collection_names_with_opts()` diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_get_collection.rst b/lib/mongoc/libmongoc/doc/mongoc_database_get_collection.rst deleted file mode 100644 index f4a17d84009bef95e84ebe4a3d3b7608c751454c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_get_collection.rst +++ /dev/null @@ -1,20 +0,0 @@ -:man_page: mongoc_database_get_collection - -mongoc_database_get_collection() -================================ - -Synopsis --------- - -.. code-block:: c - - mongoc_collection_t * - mongoc_database_get_collection (mongoc_database_t *database, const char *name); - -Allocates a new :symbol:`mongoc_collection_t` structure for the collection named ``name`` in ``database``. - -Returns -------- - -A newly allocated :symbol:`mongoc_collection_t` that should be freed with :symbol:`mongoc_collection_destroy()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_get_collection_names.rst b/lib/mongoc/libmongoc/doc/mongoc_database_get_collection_names.rst deleted file mode 100644 index dd667251c8458809e7e6e71821d4980892dadca7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_get_collection_names.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_database_get_collection_names - -mongoc_database_get_collection_names() -====================================== - -Synopsis --------- - -.. code-block:: c - - char ** - mongoc_database_get_collection_names (mongoc_database_t *database, - bson_error_t *error); - -Deprecated ----------- - -This function is deprecated and should not be used in new code. - -Please use :symbol:`mongoc_database_get_collection_names_with_opts()` instead. - -Description ------------ - -Fetches a ``NULL`` terminated array of ``NULL-byte`` terminated ``char*`` strings containing the names of all of the collections in ``database``. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -A ``NULL`` terminated array of ``NULL`` terminated ``char*`` strings that should be freed with :symbol:`bson:bson_strfreev()`. Upon failure, ``NULL`` is returned and ``error`` is set. diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_get_collection_names_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_database_get_collection_names_with_opts.rst deleted file mode 100644 index 2fd6c6f4276dfd8db7dfd5c3cf9cbaaad5900cc2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_get_collection_names_with_opts.rst +++ /dev/null @@ -1,71 +0,0 @@ -:man_page: mongoc_database_get_collection_names_with_opts - -mongoc_database_get_collection_names_with_opts() -================================================ - -Synopsis --------- - -.. code-block:: c - - char ** - mongoc_database_get_collection_names_with_opts (mongoc_database_t *database, - const bson_t *opts, - bson_error_t *error); - -Fetches a ``NULL`` terminated array of ``NULL-byte`` terminated ``char*`` strings containing the names of all of the collections in ``database``. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. |opts-source| replace:: ``database`` - -.. include:: includes/generic-opts.txt - -For a list of all options, see `the MongoDB Manual entry on the listCollections command <http://docs.mongodb.org/manual/reference/command/listCollections/>`_. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -A ``NULL`` terminated array of ``NULL`` terminated ``char*`` strings that should be freed with :symbol:`bson:bson_strfreev()`. Upon failure, ``NULL`` is returned and ``error`` is set. - -Examples --------- - -.. code-block:: c - - { - bson_t opts = BSON_INITIALIZER; - mongoc_read_concern_t *rc; - bson_error_t error; - char **strv; - unsigned i; - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_read_concern_append (rc, &opts); - if ((strv = mongoc_database_get_collection_names_with_opts ( - database, &opts, &error))) { - - for (i = 0; strv[i]; i++) - printf ("%s\n", strv[i]); - - bson_strfreev (strv); - } else { - fprintf (stderr, "Command failed: %s\n", error.message); - } - - mongoc_read_concern_destroy (rc); - bson_destroy (&opts); - } diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_get_name.rst b/lib/mongoc/libmongoc/doc/mongoc_database_get_name.rst deleted file mode 100644 index ae65fd929b04ccfd4a38073ab55ac5be048fbce6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_get_name.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_database_get_name - -mongoc_database_get_name() -========================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_database_get_name (mongoc_database_t *database); - -Fetches the name of the database. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. - -Returns -------- - -A string which should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_get_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_database_get_read_concern.rst deleted file mode 100644 index 790c6989e7671f974ee2ad7110865c88217ace3a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_get_read_concern.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_database_get_read_concern - -mongoc_database_get_read_concern() -================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_concern_t * - mongoc_database_get_read_concern (const mongoc_database_t *database); - -This function retrieves the default :symbol:`mongoc_read_concern_t` to use with ``database`` as configured by the client. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. - -Returns -------- - -A :symbol:`mongoc_read_concern_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_get_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_database_get_read_prefs.rst deleted file mode 100644 index 0db2035b7242adc77c629f4fa5c321fabf9c35a3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_get_read_prefs.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_database_get_read_prefs - -mongoc_database_get_read_prefs() -================================ - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_prefs_t * - mongoc_database_get_read_prefs (const mongoc_database_t *database); - -Fetches the default read preferences to use with ``database``. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. - -Returns -------- - -A :symbol:`mongoc_write_concern_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_get_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_database_get_write_concern.rst deleted file mode 100644 index 8627046d34f264e94bbb98fd57f028832db9f4cc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_get_write_concern.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_database_get_write_concern - -mongoc_database_get_write_concern() -=================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_write_concern_t * - mongoc_database_get_write_concern (const mongoc_database_t *database); - -This function retrieves the default :symbol:`mongoc_write_concern_t` to use with ``database`` as configured by the client. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. - -Returns -------- - -A :symbol:`mongoc_write_concern_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_has_collection.rst b/lib/mongoc/libmongoc/doc/mongoc_database_has_collection.rst deleted file mode 100644 index 65ad7dc748be8c68f3f20d855a1d33142b3326c8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_has_collection.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_database_has_collection - -mongoc_database_has_collection() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_has_collection (mongoc_database_t *database, - const char *name, - bson_error_t *error); - -This function checks to see if a collection exists on the MongoDB server within ``database``. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``name``: A string containing the name of the collection. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -If the function succeeds, it returns ``true`` if the collection exists and ``false`` if not, and in either case the fields of ``error`` are cleared, if ``error`` is not NULL. - -Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_read_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_database_read_command_with_opts.rst deleted file mode 100644 index 5ea5dfe2ac3b1f1c4f1ad49a877d4562565ed8bd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_read_command_with_opts.rst +++ /dev/null @@ -1,59 +0,0 @@ -:man_page: mongoc_database_read_command_with_opts - -mongoc_database_read_command_with_opts() -======================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_read_command_with_opts (mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic that is specific to commands that read, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_database_command_simple`. - -.. |opts-source| replace:: ``database`` - -.. include:: includes/read-cmd-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -.. |generic-cmd| replace:: :symbol:`mongoc_database_command_with_opts` -.. include:: includes/retryable-read.txt -.. include:: includes/retryable-read-command.txt - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: An optional :symbol:`mongoc_read_prefs_t`. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_read_write_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_database_read_write_command_with_opts.rst deleted file mode 100644 index 769afbce8fe66a653fe7119fe185b4089099eae7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_read_write_command_with_opts.rst +++ /dev/null @@ -1,60 +0,0 @@ -:man_page: mongoc_database_read_write_command_with_opts - -mongoc_database_read_write_command_with_opts() -============================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_read_write_command_with_opts ( - mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* UNUSED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic for commands that both read and write, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_database_command_simple`. - -.. |opts-source| replace:: ``database`` - -.. include:: includes/read-write-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -(The :symbol:`mongoc_read_prefs_t` parameter was included by mistake when this function was introduced in libmongoc 1.5. A command that writes must not obey a read preference.) - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``read_prefs``: Ignored. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/read-write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_remove_all_users.rst b/lib/mongoc/libmongoc/doc/mongoc_database_remove_all_users.rst deleted file mode 100644 index 2cafc7d793a54cde86bb08d9d1fa1b5e8e13e176..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_remove_all_users.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_database_remove_all_users - -mongoc_database_remove_all_users() -================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_remove_all_users (mongoc_database_t *database, - bson_error_t *error); - -This function will remove all users configured to access ``database``. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. This may fail if there are socket errors or the current user is not authorized to perform the given command. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_remove_user.rst b/lib/mongoc/libmongoc/doc/mongoc_database_remove_user.rst deleted file mode 100644 index 43b90a4ee2f513f4516c1e81ed8f8702dcfcc8d8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_remove_user.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_database_remove_user - -mongoc_database_remove_user() -============================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_remove_user (mongoc_database_t *database, - const char *username, - bson_error_t *error); - -This function removes the user named ``username`` from ``database``. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``username``: A string containing the username of the user to remove. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. This could include socket errors or others if the current user is not authorized to perform the command. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_set_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_database_set_read_concern.rst deleted file mode 100644 index 074fef50f8ecaa9f1fd76411d71660b74af9e601..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_set_read_concern.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_database_set_read_concern - -mongoc_database_set_read_concern() -================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_database_set_read_concern (mongoc_database_t *database, - const mongoc_read_concern_t *read_concern); - -This function sets the read concern to use on operations performed with ``database``. Collections created with :symbol:`mongoc_database_get_collection()` after this call will inherit this read concern. - -The default read concern is empty: No readConcern is sent to the server unless explicitly configured. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``read_concern``: A :symbol:`mongoc_read_concern_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_set_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_database_set_read_prefs.rst deleted file mode 100644 index 05abceebf6aecd01109ed4067a9592f4439661f8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_set_read_prefs.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_database_set_read_prefs - -mongoc_database_set_read_prefs() -================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_database_set_read_prefs (mongoc_database_t *database, - const mongoc_read_prefs_t *read_prefs); - -This function sets the default read preferences to use on operations performed with ``database``. Collections created with :symbol:`mongoc_database_get_collection()` after this call will inherit these read preferences. - -The global default is MONGOC_READ_PRIMARY: if the client is connected to a replica set it reads from the primary, otherwise it reads from the current MongoDB server. - -Please see the MongoDB website for a description of `Read Preferences <http://docs.mongodb.org/manual/core/read-preference/>`_. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_set_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_database_set_write_concern.rst deleted file mode 100644 index 4e4bef5f87ace025017a2715171afbf9d1a3c20c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_set_write_concern.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_database_set_write_concern - -mongoc_database_set_write_concern() -=================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_database_set_write_concern (mongoc_database_t *database, - const mongoc_write_concern_t *write_concern); - -This function sets the write concern to use on operations performed with ``database``. Collections created with :symbol:`mongoc_database_get_collection()` after this call will inherit this write concern. - -The default write concern is MONGOC_WRITE_CONCERN_W_DEFAULT: the driver blocks awaiting basic acknowledgement of write operations from MongoDB. This is the correct write concern for the great majority of applications. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_t.rst b/lib/mongoc/libmongoc/doc/mongoc_database_t.rst deleted file mode 100644 index 9897bcbf1156aee9a8a84de21c9b009ee5579ee3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_t.rst +++ /dev/null @@ -1,83 +0,0 @@ -:man_page: mongoc_database_t - -mongoc_database_t -================= - -MongoDB Database Abstraction - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_database_t mongoc_database_t; - -``mongoc_database_t`` provides access to a MongoDB database. This handle is useful for actions a particular database object. It *is not* a container for :symbol:`mongoc_collection_t` structures. - -Read preferences and write concerns are inherited from the parent client. They can be overridden with :symbol:`mongoc_database_set_read_prefs()` and :symbol:`mongoc_database_set_write_concern()`. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_database_add_user - mongoc_database_aggregate - mongoc_database_command - mongoc_database_command_simple - mongoc_database_command_with_opts - mongoc_database_copy - mongoc_database_create_collection - mongoc_database_destroy - mongoc_database_drop - mongoc_database_drop_with_opts - mongoc_database_find_collections - mongoc_database_find_collections_with_opts - mongoc_database_get_collection - mongoc_database_get_collection_names - mongoc_database_get_collection_names_with_opts - mongoc_database_get_name - mongoc_database_get_read_concern - mongoc_database_get_read_prefs - mongoc_database_get_write_concern - mongoc_database_has_collection - mongoc_database_read_command_with_opts - mongoc_database_read_write_command_with_opts - mongoc_database_remove_all_users - mongoc_database_remove_user - mongoc_database_set_read_concern - mongoc_database_set_read_prefs - mongoc_database_set_write_concern - mongoc_database_watch - mongoc_database_write_command_with_opts - -Examples --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - int - main (int argc, char *argv[]) - { - mongoc_database_t *database; - mongoc_client_t *client; - - mongoc_init (); - - client = mongoc_client_new ("mongodb://localhost/"); - database = mongoc_client_get_database (client, "test"); - - mongoc_database_destroy (database); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return 0; - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_watch.rst b/lib/mongoc/libmongoc/doc/mongoc_database_watch.rst deleted file mode 100644 index bc92b44e0277752b7c0da7cc53d5c0f294a45cce..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_watch.rst +++ /dev/null @@ -1,50 +0,0 @@ -:man_page: mongoc_database_watch - -mongoc_database_watch() -======================= - -Synopsis --------- - -.. code-block:: c - - mongoc_change_stream_t* - mongoc_database_watch (const mongoc_database_t *db, - const bson_t *pipeline, - const bson_t *opts); - -A helper function to create a change stream. It is preferred to call this -function over using a raw aggregation to create a change stream. - -This function uses the read preference and read concern of the database. If -the change stream needs to re-establish connection, the same read preference -will be used. This may happen if the change stream encounters a resumable error. - -.. warning:: - - A change stream is only supported with majority read concern. - -.. include:: includes/retryable-read.txt - -Parameters ----------- - -* ``db``: A :symbol:`mongoc_database_t` specifying the database which the change stream listens to. -* ``pipeline``: A :symbol:`bson:bson_t` representing an aggregation pipeline appended to the change stream. This may be an empty document. -* ``opts``: A :symbol:`bson:bson_t` containing change stream options. - -.. include:: includes/change-stream-opts.txt - -Returns -------- -A newly allocated :symbol:`mongoc_change_stream_t` which must be freed with -:symbol:`mongoc_change_stream_destroy` when no longer in use. The returned -:symbol:`mongoc_change_stream_t` is never ``NULL``. If there is an error, it can -be retrieved with :symbol:`mongoc_change_stream_error_document`, and subsequent -calls to :symbol:`mongoc_change_stream_next` will return ``false``. - -See Also --------- -:doc:`mongoc_client_watch` - -:doc:`mongoc_collection_watch` diff --git a/lib/mongoc/libmongoc/doc/mongoc_database_write_command_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_database_write_command_with_opts.rst deleted file mode 100644 index a7acf0d731915c3be8ce020d4936c9c7e290ea61..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_database_write_command_with_opts.rst +++ /dev/null @@ -1,61 +0,0 @@ -:man_page: mongoc_database_write_command_with_opts - -mongoc_database_write_command_with_opts() -========================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_database_write_command_with_opts (mongoc_database_t *database, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); - -Execute a command on the server, applying logic that is specific to commands that write, and taking the MongoDB server version into account. To send a raw command to the server without any of this logic, use :symbol:`mongoc_database_command_simple`. - -.. |opts-source| replace:: ``database`` - -.. include:: includes/write-opts-sources.txt - -``reply`` is always initialized, and must be freed with :symbol:`bson:bson_destroy()`. - -Parameters ----------- - -* ``database``: A :symbol:`mongoc_database_t`. -* ``db_name``: The name of the database to run the command on. -* ``command``: A :symbol:`bson:bson_t` containing the command specification. -* ``opts``: A :symbol:`bson:bson_t` containing additional options. -* ``reply``: A location for the resulting document. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -.. include:: includes/write-opts.txt - -Consult `the MongoDB Manual entry on Database Commands <https://docs.mongodb.com/manual/reference/command/>`_ for each command's arguments. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -A write concern timeout or write concern error is considered a failure. - -Basic Write Operations ----------------------- - -Do not use this function to call the basic write commands "insert", "update", and "delete". Those commands require special logic not implemented in ``mongoc_database_write_command_with_opts``. For basic write operations use CRUD functions such as :symbol:`mongoc_collection_insert_one` and the others described in :ref:`the CRUD tutorial <tutorial_crud_operations>`, or use the :doc:`Bulk API <bulk>`. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_delete_flags_t.rst b/lib/mongoc/libmongoc/doc/mongoc_delete_flags_t.rst deleted file mode 100644 index f5c02cf44bac7e73ec45cba583c43e15a859fb13..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_delete_flags_t.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_delete_flags_t - -mongoc_delete_flags_t -===================== - -Flags for deletion operations - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_DELETE_NONE = 0, - MONGOC_DELETE_SINGLE_REMOVE = 1 << 0, - } mongoc_delete_flags_t; - -Deprecated ----------- - -.. warning:: - - These flags are deprecated and should not be used in new code. - -Please use :symbol:`mongoc_collection_delete_one()` or :symbol:`mongoc_collection_delete_many()` instead. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_error_has_label.rst b/lib/mongoc/libmongoc/doc/mongoc_error_has_label.rst deleted file mode 100644 index f34434b3ea99cf25bac7389a9679539c1edcba6c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_error_has_label.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_error_has_label - -mongoc_error_has_label() -======================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_error_has_label (const bson_t *reply, const char *label); - -Test whether a reply from a failed operation includes a specific error label. See :ref:`Error Labels <error_labels>` for details, and see :symbol:`mongoc_client_session_start_transaction` for example code that demonstrates their use. - -Parameters ----------- - -* ``reply``: A :symbol:`bson:bson_t`, the reply to a failed operation. -* ``label``: The label to test for, such as "TransientTransactionError" or "UnknownTransactionCommitResult". - -Returns -------- - -Returns true if ``reply`` contains the error label. diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_append.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_append.rst deleted file mode 100644 index 26b5a0f40ec1b9c706b3e81b0889107a8b0b6d48..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_append.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_append - -mongoc_find_and_modify_opts_append() -==================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_find_and_modify_opts_append (mongoc_find_and_modify_opts_t *opts, - const bson_t *extra); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``extra``: A :symbol:`bson:bson_t` with fields and values to append directly to the findAndModify command sent to the server. - -Description ------------ - -Adds arbitrary options to a `findAndModify <https://docs.mongodb.org/manual/reference/command/findAndModify/>`_ command. - -``extra`` does not have to remain valid after calling this function. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and logs an error. - -Appending options to findAndModify ----------------------------------- - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_OPTS_BEGIN */ - :end-before: /* EXAMPLE_FAM_OPTS_END */ - :caption: opts.c - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_destroy.rst deleted file mode 100644 index 32833e82479a73dadeb4bf76fad69fcb90d3d531..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_destroy.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_destroy - -mongoc_find_and_modify_opts_destroy() -===================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_find_and_modify_opts_destroy ( - mongoc_find_and_modify_opts_t *find_and_modify_opts); - -Parameters ----------- - -* ``find_and_modify_opts``: A :symbol:`mongoc_find_and_modify_opts_t`. - -Description ------------ - -Frees all resources associated with the find and modify builder structure. Does nothing if ``find_and_modify_opts`` is NULL. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_bypass_document_validation.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_bypass_document_validation.rst deleted file mode 100644 index f012795b0a962325a3751b97f139d2a881be029f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_bypass_document_validation.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_get_bypass_document_validation - -mongoc_find_and_modify_opts_get_bypass_document_validation() -============================================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_find_and_modify_opts_get_bypass_document_validation ( - const mongoc_find_and_modify_opts_t *opts); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. - -Returns -------- - -Returns true if :symbol:`mongoc_find_and_modify_opts_set_bypass_document_validation` was called previously on ``opts``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_fields.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_fields.rst deleted file mode 100644 index a0e26f9ce6d9d3ef5d188dc6a8b62142215aa279..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_fields.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_get_fields - -mongoc_find_and_modify_opts_get_fields() -======================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_find_and_modify_opts_get_fields ( - const mongoc_find_and_modify_opts_t *opts, bson_t *fields); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``fields``: An uninitialized :symbol:`bson:bson_t`. - -Description ------------ - -Copy to ``fields`` the BSON document that was set with :symbol:`mongoc_find_and_modify_opts_set_fields`, or initializes ``fields`` with an empty BSON document. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_flags.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_flags.rst deleted file mode 100644 index f6996f6e5ee8b6e38df56f2d111cffe3d03702dc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_flags.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_get_flags - -mongoc_find_and_modify_opts_get_flags() -======================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_find_and_modify_flags_t - mongoc_find_and_modify_opts_get_flags ( - const mongoc_find_and_modify_opts_t *opts); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. - -Returns -------- - -Returns the flags set with :symbol:`mongoc_find_and_modify_opts_set_flags`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_max_time_ms.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_max_time_ms.rst deleted file mode 100644 index 0de3e8aa2b5a8ecbde2ebfd38536bd403debbef5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_max_time_ms.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_get_max_time_ms - -mongoc_find_and_modify_opts_get_max_time_ms() -============================================= - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_find_and_modify_opts_get_max_time_ms ( - const mongoc_find_and_modify_opts_t *opts); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. - -Returns -------- - -Returns the "maxTimeMS" value set with :symbol:`mongoc_find_and_modify_opts_set_max_time_ms`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_sort.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_sort.rst deleted file mode 100644 index 834bfee8fde6a337e3619c9185f0dc665f91529c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_sort.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_get_sort - -mongoc_find_and_modify_opts_get_sort() -====================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_find_and_modify_opts_get_sort (const mongoc_find_and_modify_opts_t *opts, - bson_t *sort); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``sort``: An uninitialized :symbol:`bson:bson_t`. - -Description ------------ - -Copies the sort document set with :symbol:`mongoc_find_and_modify_opts_set_sort`, or initializes ``sort`` with an empty BSON document. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_update.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_update.rst deleted file mode 100644 index 2f861f29cb255d38c293bc6b2abf86ac16372234..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_get_update.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_get_update - -mongoc_find_and_modify_opts_get_update() -======================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_find_and_modify_opts_get_update ( - const mongoc_find_and_modify_opts_t *opts, bson_t *update); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``update``: An uninitialized :symbol:`bson:bson_t`. - -Description ------------ - -Copies the update document set with :symbol:`mongoc_find_and_modify_opts_set_update`, or initializes ``update`` with an empty BSON document. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_new.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_new.rst deleted file mode 100644 index 902f11ddc364f00aa1f80e50d77fda9768a11ffb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_new.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_new - -mongoc_find_and_modify_opts_new() -================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_find_and_modify_opts_t * - mongoc_find_and_modify_opts_new (void); - -Returns -------- - -Creates a newly allocated find and modify builder structure that is used to create a findAndModify command. This should be freed with :symbol:`mongoc_find_and_modify_opts_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_bypass_document_validation.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_bypass_document_validation.rst deleted file mode 100644 index ac024f08a7424d78cb023e7aed03bca4714da1cd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_bypass_document_validation.rst +++ /dev/null @@ -1,61 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_set_bypass_document_validation - -mongoc_find_and_modify_opts_set_bypass_document_validation() -============================================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_find_and_modify_opts_set_bypass_document_validation ( - mongoc_find_and_modify_opts_t *opts, bool bypass); - -This option is only available when talking to MongoDB 3.2 and later. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``bypass``: If the schema validation rules should be ignored. - -Description ------------ - -Adds bypassDocumentValidation argument to the builder. - -When authentication is enabled, the authenticated user must have either the "dbadmin" or "restore" roles to bypass document validation. - -Returns -------- - -Returns ``true`` if it successfully added the option to the builder, otherwise ``false`` and logs an error. - -Setting bypassDocumentValidation --------------------------------- - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_BYPASS_BEGIN */ - :end-before: /* EXAMPLE_FAM_BYPASS_END */ - :caption: bypass.c - -Outputs: - -.. code-block:: c - - { - "lastErrorObject" : {"updatedExisting" : true, "n" : 1}, - "value" : { - "_id" : {"$oid" : "56562a99d13e6d86239c7b00"}, - "age" : 34, - "firstname" : "Zlatan", - "goals" : 342, - "lastname" : "Ibrahimovic", - "profession" : "Football player", - "position" : "striker" - }, - "ok" : 1 - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_fields.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_fields.rst deleted file mode 100644 index e913617cea9a409a7867c95a2f565f6d0a8c1fd3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_fields.rst +++ /dev/null @@ -1,53 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_set_fields - -mongoc_find_and_modify_opts_set_fields() -======================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_find_and_modify_opts_set_fields (mongoc_find_and_modify_opts_t *opts, - const bson_t *fields); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``fields``: A subset of fields to return. Choose which fields to include by appending ``{fieldname: 1}`` for each fieldname, or excluding it with ``{fieldname: 0}``. - -Description ------------ - -Adds fields argument to the builder. - -``fields`` does not have to remain valid after calling this function. - -Returns -------- - -Returns ``true`` if it successfully added the option to the builder, otherwise ``false``. - -Setting fields --------------- - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_FIELDS_BEGIN */ - :end-before: /* EXAMPLE_FAM_FIELDS_END */ - :caption: fields.c - -Outputs: - -.. code-block:: c - - { - "lastErrorObject" - : {"updatedExisting" : true, "n" : 1}, - "value" - : {"_id" : {"$oid" : "56562a99d13e6d86239c7b00"}, "goals" : 343}, - "ok" : 1 - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_flags.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_flags.rst deleted file mode 100644 index ef801fccbf55aa791366e0b81dc16a2d5ab1696d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_flags.rst +++ /dev/null @@ -1,69 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_set_flags - -mongoc_find_and_modify_opts_set_flags() -======================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_find_and_modify_opts_set_flags ( - mongoc_find_and_modify_opts_t *opts, - const mongoc_find_and_modify_flags_t flags); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``flags``: . - -Description ------------ - -Adds one or more flags to the builder. - -================================= ============================================================================= -MONGOC_FIND_AND_MODIFY_NONE Default. Doesn't add anything to the builder. -MONGOC_FIND_AND_MODIFY_REMOVE Will instruct find_and_modify to remove the matching document. -MONGOC_FIND_AND_MODIFY_UPSERT Update the matching document or, if no document matches, insert the document. -MONGOC_FIND_AND_MODIFY_RETURN_NEW Return the resulting document. -================================= ============================================================================= - -Returns -------- - -Returns Returns ``true`` if it successfully added the option to the builder, otherwise ``false`` and logs an error. - -Setting flags -------------- - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_FLAGS_BEGIN */ - :end-before: /* EXAMPLE_FAM_FLAGS_END */ - :caption: flags.c - -Outputs: - -.. code-block:: c - - { - "lastErrorObject" : { - "updatedExisting" : false, - "n" : 1, - "upserted" : {"$oid" : "56562a99d13e6d86239c7b00"} - }, - "value" : { - "_id" : {"$oid" : "56562a99d13e6d86239c7b00"}, - "age" : 34, - "firstname" : "Zlatan", - "goals" : 342, - "lastname" : "Ibrahimovic", - "profession" : "Football player", - "position" : "striker" - }, - "ok" : 1 - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_max_time_ms.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_max_time_ms.rst deleted file mode 100644 index 65834ec7743b33d3cedc29604d99be6de245e5cc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_max_time_ms.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_set_max_time_ms - -mongoc_find_and_modify_opts_set_max_time_ms() -============================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_find_and_modify_opts_set_max_time_ms ( - mongoc_find_and_modify_opts_t *opts, uint32_t max_time_ms); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``max_time_ms``: The maximum server-side execution time permitted, in milliseconds, or 0 to specify no maximum time (the default setting). - -Description ------------ - -Adds a maxTimeMS argument to the builder. - -Returns -------- - -Returns ``true`` if it successfully added the option to the builder, otherwise ``false`` and logs an error. - -Note: although ``max_time_ms`` is a uint32_t, it is possible to set it as a uint64_t through the options arguments in some cursor returning functions like :symbol:`mongoc_collection_find_with_opts()`. - -Setting maxTimeMS ------------------ - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_OPTS_BEGIN */ - :end-before: /* EXAMPLE_FAM_OPTS_END */ - :caption: opts.c - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_sort.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_sort.rst deleted file mode 100644 index ea7b148e490add0ff9a5309a21ede8fbd3d0bbe1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_sort.rst +++ /dev/null @@ -1,60 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_set_sort - -mongoc_find_and_modify_opts_set_sort() -====================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_find_and_modify_opts_set_sort (mongoc_find_and_modify_opts_t *opts, - const bson_t *sort); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``sort``: Determines which document the operation modifies if the query selects multiple documents. findAndModify modifies the first document in the sort order specified by this argument. - -Description ------------ - -Adds sort argument to the builder. - -``sort`` does not have to remain valid after calling this function. - -Returns -------- - -Returns ``true`` if it successfully added the option to the builder, otherwise ``false``. - -Setting sort ------------- - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_SORT_BEGIN */ - :end-before: /* EXAMPLE_FAM_SORT_END */ - :caption: sort.c - -Outputs: - -.. code-block:: c - - { - "lastErrorObject" : {"updatedExisting" : true, "n" : 1}, - "value" : { - "_id" : {"$oid" : "56562a99d13e6d86239c7b00"}, - "age" : 35, - "firstname" : "Zlatan", - "goals" : 343, - "lastname" : "Ibrahimovic", - "profession" : "Football player", - "position" : "striker", - "author" : true - }, - "ok" : 1 - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_update.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_update.rst deleted file mode 100644 index 929d4a0a3598ef217c6e30bec2dae1abc877ba48..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_set_update.rst +++ /dev/null @@ -1,59 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_set_update - -mongoc_find_and_modify_opts_set_update() -======================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_find_and_modify_opts_set_update (mongoc_find_and_modify_opts_t *opts, - const bson_t *update); - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_find_and_modify_opts_t`. -* ``update``: The ``update`` document is the same format as the ``update`` document passed to :symbol:`mongoc_collection_update`. - -Description ------------ - -Adds update argument to the builder. - -``update`` does not have to remain valid after calling this function. - -Returns -------- - -Returns ``true`` if it successfully added the option to the builder, otherwise ``false``. - -Setting update --------------- - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_UPDATE_BEGIN */ - :end-before: /* EXAMPLE_FAM_UPDATE_END */ - :caption: update.c - -Outputs: - -.. code-block:: c - - { - "lastErrorObject" : {"updatedExisting" : true, "n" : 1}, - "value" : { - "_id" : {"$oid" : "56562a99d13e6d86239c7b00"}, - "age" : 35, - "firstname" : "Zlatan", - "goals" : 342, - "lastname" : "Ibrahimovic", - "profession" : "Football player", - "position" : "striker" - }, - "ok" : 1 - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_t.rst b/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_t.rst deleted file mode 100644 index 751189ba88c5cbfc3342269c3a8308ce93777dc5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_find_and_modify_opts_t.rst +++ /dev/null @@ -1,182 +0,0 @@ -:man_page: mongoc_find_and_modify_opts_t - -mongoc_find_and_modify_opts_t -============================= - -find_and_modify abstraction - -Synopsis --------- - -``mongoc_find_and_modify_opts_t`` is a builder interface to construct a `find_and_modify <https://docs.mongodb.org/manual/reference/command/findAndModify/>`_ command. - -It was created to be able to accommodate new arguments to the MongoDB find_and_modify command. - -As of MongoDB 3.2, the :symbol:`mongoc_write_concern_t` specified on the :symbol:`mongoc_collection_t` will be used, if any. - -.. _mongoc_collection_find_and_modify_with_opts_example: - -Example -------- - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_FLAGS_BEGIN */ - :end-before: /* EXAMPLE_FAM_FLAGS_END */ - :caption: flags.c - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_BYPASS_BEGIN */ - :end-before: /* EXAMPLE_FAM_BYPASS_END */ - :caption: bypass.c - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_UPDATE_BEGIN */ - :end-before: /* EXAMPLE_FAM_UPDATE_END */ - :caption: update.c - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_FIELDS_BEGIN */ - :end-before: /* EXAMPLE_FAM_FIELDS_END */ - :caption: fields.c - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_SORT_BEGIN */ - :end-before: /* EXAMPLE_FAM_SORT_END */ - :caption: sort.c - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_OPTS_BEGIN */ - :end-before: /* EXAMPLE_FAM_OPTS_END */ - :caption: opts.c - -.. literalinclude:: ../examples/find_and_modify_with_opts/fam.c - :language: c - :start-after: /* EXAMPLE_FAM_MAIN_BEGIN */ - :end-before: /* EXAMPLE_FAM_MAIN_END */ - :caption: fam.c - -Outputs: - -.. code-block:: json - - { - "lastErrorObject": { - "updatedExisting": false, - "n": 1, - "upserted": { - "$oid": "56562a99d13e6d86239c7b00" - } - }, - "value": { - "_id": { - "$oid": "56562a99d13e6d86239c7b00" - }, - "age": 34, - "firstname": "Zlatan", - "goals": 342, - "lastname": "Ibrahimovic", - "profession": "Football player", - "position": "striker" - }, - "ok": 1 - } - { - "lastErrorObject": { - "updatedExisting": true, - "n": 1 - }, - "value": { - "_id": { - "$oid": "56562a99d13e6d86239c7b00" - }, - "age": 34, - "firstname": "Zlatan", - "goals": 342, - "lastname": "Ibrahimovic", - "profession": "Football player", - "position": "striker" - }, - "ok": 1 - } - { - "lastErrorObject": { - "updatedExisting": true, - "n": 1 - }, - "value": { - "_id": { - "$oid": "56562a99d13e6d86239c7b00" - }, - "age": 35, - "firstname": "Zlatan", - "goals": 342, - "lastname": "Ibrahimovic", - "profession": "Football player", - "position": "striker" - }, - "ok": 1 - } - { - "lastErrorObject": { - "updatedExisting": true, - "n": 1 - }, - "value": { - "_id": { - "$oid": "56562a99d13e6d86239c7b00" - }, - "goals": 343 - }, - "ok": 1 - } - { - "lastErrorObject": { - "updatedExisting": true, - "n": 1 - }, - "value": { - "_id": { - "$oid": "56562a99d13e6d86239c7b00" - }, - "age": 35, - "firstname": "Zlatan", - "goals": 343, - "lastname": "Ibrahimovic", - "profession": "Football player", - "position": "striker", - "author": true - }, - "ok": 1 - } - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_find_and_modify_opts_append - mongoc_find_and_modify_opts_destroy - mongoc_find_and_modify_opts_get_bypass_document_validation - mongoc_find_and_modify_opts_get_fields - mongoc_find_and_modify_opts_get_flags - mongoc_find_and_modify_opts_get_max_time_ms - mongoc_find_and_modify_opts_get_sort - mongoc_find_and_modify_opts_get_update - mongoc_find_and_modify_opts_new - mongoc_find_and_modify_opts_set_bypass_document_validation - mongoc_find_and_modify_opts_set_fields - mongoc_find_and_modify_opts_set_flags - mongoc_find_and_modify_opts_set_max_time_ms - mongoc_find_and_modify_opts_set_sort - mongoc_find_and_modify_opts_set_update - diff --git a/lib/mongoc/libmongoc/doc/mongoc_get_major_version.rst b/lib/mongoc/libmongoc/doc/mongoc_get_major_version.rst deleted file mode 100644 index 07a7ce0c43fd0c9cbd14ae5ece5183c85d979483..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_get_major_version.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_get_major_version - -mongoc_get_major_version() -========================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_get_major_version (void); - -Returns -------- - -The value of ``MONGOC_MAJOR_VERSION`` when libmongoc was compiled. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_get_micro_version.rst b/lib/mongoc/libmongoc/doc/mongoc_get_micro_version.rst deleted file mode 100644 index 2f095c0086a0c5c271d4ef9d93dab7e8998bc48c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_get_micro_version.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_get_micro_version - -mongoc_get_micro_version() -========================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_get_micro_version (void); - -Returns -------- - -The value of ``MONGOC_MICRO_VERSION`` when libmongoc was compiled. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_get_minor_version.rst b/lib/mongoc/libmongoc/doc/mongoc_get_minor_version.rst deleted file mode 100644 index 8ba6158841564e038ef8b65073b29d36ad97e4d6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_get_minor_version.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_get_minor_version - -mongoc_get_minor_version() -========================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_get_minor_version (void); - -Returns -------- - -The value of ``MONGOC_MINOR_VERSION`` when libmongoc was compiled. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_get_version.rst b/lib/mongoc/libmongoc/doc/mongoc_get_version.rst deleted file mode 100644 index d941036e89f2b299876250ec7412f6b1ffb16700..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_get_version.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_get_version - -mongoc_get_version() -==================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_get_version (void); - -Returns -------- - -A string representation of libmongoc's version, formatted something like "1.2.3" or "1.2.3-pre". - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_abort_upload.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_abort_upload.rst deleted file mode 100644 index 6df4c19a017fea89806cb43e0aececdfabcd2a8e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_abort_upload.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_gridfs_bucket_abort_upload - -mongoc_gridfs_bucket_abort_upload() -=================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_bucket_abort_upload (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t` created by :symbol:`mongoc_gridfs_bucket_open_upload_stream` or :symbol:`mongoc_gridfs_bucket_open_upload_stream_with_id`. - -Description ------------ - -Aborts the upload of a GridFS upload stream. - -See Also --------- - -:symbol:`mongoc_gridfs_bucket_open_upload_stream` - -:symbol:`mongoc_gridfs_bucket_open_upload_stream_with_id()` - -Returns -------- - -True on success. False otherwise, and sets an error on ``stream``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_delete_by_id.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_delete_by_id.rst deleted file mode 100644 index e67ce8bcd0aa0a46d6c0858b257465434e797917..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_delete_by_id.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_gridfs_bucket_delete_by_id - -mongoc_gridfs_bucket_delete_by_id() -=================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_bucket_delete_by_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - bson_error_t *error); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t`. -* ``file_id``: A :symbol:`bson_value_t` of the id of the file to delete. -* ``error``: A :symbol:`bson_error_t` to receive any error or ``NULL``. - -Description ------------ - -Deletes a file and its contents from GridFS. - -Returns -------- -True if the operation succeeded. False otherwise, and sets ``error``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_destroy.rst deleted file mode 100644 index 67639c40c131e2d9da4e155bf472e17bb5df789c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_gridfs_bucket_destroy - -mongoc_gridfs_bucket_destroy() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_bucket_destroy (mongoc_gridfs_bucket_t *bucket); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t` or ``NULL``. - -Description ------------ - -Destroys a :symbol:`mongoc_gridfs_bucket_t`. Does nothing if passed ``NULL``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_download_to_stream.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_download_to_stream.rst deleted file mode 100644 index 39d3ffa71be2206809edd94a420cd3a7b433f12a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_download_to_stream.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_gridfs_bucket_download_to_stream - -mongoc_gridfs_bucket_download_to_stream() -========================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_bucket_download_to_stream (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - mongoc_stream_t *destination, - bson_error_t *error); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t`. -* ``file_id``: A :symbol:`bson_value_t` of the id of the file to download. -* ``destination``: A :symbol:`mongoc_stream_t` which receives data from the downloaded file. -* ``error``: A :symbol:`bson_error_t` to receive any error or ``NULL``. - -Description ------------ - -Reads from the GridFS file and writes to the ``destination`` stream. - -Writes the full contents of the file to the ``destination`` stream. -The ``destination`` stream is not closed after calling :symbol:`mongoc_gridfs_bucket_download_to_stream()`; call :symbol:`mongoc_stream_close()` after. - -.. include:: includes/retryable-read.txt - -See Also --------- -:symbol:`mongoc_stream_file_new` and :symbol:`mongoc_stream_file_new_for_path`, which can be used to create a destination stream from a file. - -Returns -------- -True if the operation succeeded. False otherwise, and sets ``error``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_find.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_find.rst deleted file mode 100644 index d1ff6e5d856889459409cf2fa9e429e114dd70bd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_find.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_gridfs_bucket_find - -mongoc_gridfs_bucket_find() -=========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_cursor_t * - mongoc_gridfs_bucket_find (mongoc_gridfs_bucket_t *bucket, - const bson_t *filter, - const bson_t *opts); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t`. -* ``filter``: A :symbol:`bson_t` containing the query to execute. -* ``opts``: A :symbol:`bson_t` for query options, supporting all options in :symbol:`mongoc_collection_find_with_opts()` excluding ``sessionId``. - -Description ------------ - -Finds file documents from the bucket's ``files`` collection. - -.. include:: includes/retryable-read.txt - -Returns -------- -A newly allocated :symbol:`mongoc_cursor_t` that must be freed with :symbol:`mongoc_cursor_destroy()`. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_new.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_new.rst deleted file mode 100644 index 440d2a42dc1de8dcd0fe42f1875ba95c17a0a206..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_new.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_gridfs_bucket_new - -mongoc_gridfs_bucket_new() -========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_bucket_t * - mongoc_gridfs_bucket_new (mongoc_database_t *db, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_error_t* error); - -Parameters ----------- - -* ``db``: A :symbol:`mongoc_database_t`. -* ``opts``: A :symbol:`bson_t` or ``NULL`` -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` used for read operations or ``NULL`` to inherit read preferences from ``db``. -* ``error``: A :symbol:`bson_error_t` or ``NULL``. - -.. include:: includes/gridfs-bucket-opts.txt - -Description ------------ - -Creates a new :symbol:`mongoc_gridfs_bucket_t`. Use this handle to perform GridFS operations. - -Returns -------- - -A newly allocated :symbol:`mongoc_gridfs_bucket_t` that should be freed with :symbol:`mongoc_gridfs_bucket_destroy()` or ``NULL`` on failure. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_download_stream.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_download_stream.rst deleted file mode 100644 index 8f7f15e8b144c9a5598c57c6e39873e996ba836e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_download_stream.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_gridfs_bucket_open_download_stream - -mongoc_gridfs_bucket_open_download_stream() -=========================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_gridfs_bucket_open_download_stream (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - bson_error_t *error); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t`. -* ``file_id``: A :symbol:`bson_value_t` of the id of the file to download. -* ``error``: A :symbol:`bson_error_t` to receive any error or ``NULL``. - -Description ------------ - -Opens a stream for reading a file from GridFS. - -See Also --------- - -:symbol:`mongoc_gridfs_bucket_stream_error()` - -Returns -------- - -A :symbol:`mongoc_stream_t` that can be read from or ``NULL`` on failure. Errors on this stream can be retrieved with :symbol:`mongoc_gridfs_bucket_stream_error()`. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_upload_stream.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_upload_stream.rst deleted file mode 100644 index 462eb102784fa7986bd52b89e703a86a3afbd91f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_upload_stream.rst +++ /dev/null @@ -1,45 +0,0 @@ -:man_page: mongoc_gridfs_bucket_open_upload_stream - -mongoc_gridfs_bucket_open_upload_stream() -========================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_gridfs_bucket_open_upload_stream (mongoc_gridfs_bucket_t *bucket, - const char *filename, - const bson_t *opts, - bson_value_t *file_id, - bson_error_t *error); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t`. -* ``filename``: The name of the file to create. -* ``opts``: A :symbol:`bson_t` or ``NULL``. -* ``file_id``: A :symbol:`bson_value_t` to receive the generated id of the file or ``NULL``. -* ``error``: A :symbol:`bson_error_t` to receive any error or ``NULL``. - -.. include:: includes/gridfs-bucket-upload-opts.txt - -Description ------------ - -Opens a stream for writing to a new file in GridFS. The file id is generated automatically. -To specify an explicit file id, use :symbol:`mongoc_gridfs_bucket_open_upload_stream_with_id()`. - -See Also --------- - -:symbol:`mongoc_gridfs_bucket_open_upload_stream_with_id()` - -:symbol:`mongoc_gridfs_bucket_stream_error()` - -Returns -------- - -A :symbol:`mongoc_stream_t` that can be written to or ``NULL`` on failure. Errors on this stream can be retrieved with :symbol:`mongoc_gridfs_bucket_stream_error`. After calling :symbol:`mongoc_stream_close` the file is completely written in GridFS. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_upload_stream_with_id.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_upload_stream_with_id.rst deleted file mode 100644 index d9c8ef91eea81eb0716644caa41a7e2e91a82e9b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_open_upload_stream_with_id.rst +++ /dev/null @@ -1,45 +0,0 @@ -:man_page: mongoc_gridfs_bucket_open_upload_stream_with_id - -mongoc_gridfs_bucket_open_upload_stream_with_id() -================================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_gridfs_bucket_open_upload_stream_with_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - const char *filename, - const bson_t *opts, - bson_error_t *error); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t`. -* ``file_id``: A :symbol:`bson_value_t` specifying the id of the created file. -* ``filename``: The name of the file to create. -* ``opts``: A :symbol:`bson_t` or ``NULL``. -* ``error``: A :symbol:`bson_error_t` to receive any error or ``NULL``. - -.. include:: includes/gridfs-bucket-upload-opts.txt - -Description ------------ - -Opens a stream for writing to a new file in GridFS for a specified file id. -To have libmongoc generate an id, use :symbol:`mongoc_gridfs_bucket_open_upload_stream()`. - -See Also --------- - -:symbol:`mongoc_gridfs_bucket_open_upload_stream()` - -:symbol:`mongoc_gridfs_bucket_stream_error()` - -Returns -------- - -A :symbol:`mongoc_stream_t` that can be written to or ``NULL`` on failure. Errors on this stream can be retrieved with :symbol:`mongoc_gridfs_bucket_stream_error`. After calling :symbol:`mongoc_stream_close` the file is completely written in GridFS. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_stream_error.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_stream_error.rst deleted file mode 100644 index ab47cad63c0b824887c0fd3f834ac57d3fdcc5e5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_stream_error.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_gridfs_bucket_stream_error - -mongoc_gridfs_bucket_stream_error() -=================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_bucket_stream_error (mongoc_stream_t *stream, - bson_error_t *error); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t` created by :symbol:`mongoc_gridfs_bucket_open_upload_stream`, :symbol:`mongoc_gridfs_bucket_open_upload_stream_with_id`, or :symbol:`mongoc_gridfs_bucket_open_download_stream`. -* ``error``: A :symbol:`bson_error_t` to receive the possible error. - -Description ------------ - -Retrieves an error for a GridFS stream if one exists. - -See Also --------- - -:symbol:`mongoc_gridfs_bucket_open_upload_stream` - -:symbol:`mongoc_gridfs_bucket_open_upload_stream_with_id()` - -:symbol:`mongoc_gridfs_bucket_open_download_stream` - -Returns -------- - -True if an error occurred on the stream and sets ``error``. False otherwise. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_t.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_t.rst deleted file mode 100644 index 4baa58d590b449c95b61299d475482c20daaf8ad..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_t.rst +++ /dev/null @@ -1,64 +0,0 @@ -:man_page: mongoc_gridfs_bucket_t - -mongoc_gridfs_bucket_t -====================== - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct _mongoc_gridfs_bucket_t mongoc_gridfs_bucket_t; - -Description ------------ - -``mongoc_gridfs_bucket_t`` provides a spec-compliant MongoDB GridFS implementation, superseding :symbol:`mongoc_gridfs_t`. See the `GridFS MongoDB documentation <https://docs.mongodb.com/manual/core/gridfs/>`_. - -Thread Safety -------------- - -:symbol:`mongoc_gridfs_bucket_t` is NOT thread-safe and should only be used in the same thread as the owning :symbol:`mongoc_client_t`. - -Lifecycle ---------- - -It is an error to free a :symbol:`mongoc_gridfs_bucket_t` before freeing all derived instances of :symbol:`mongoc_stream_t`. The owning :symbol:`mongoc_client_t` must outlive the :symbol:`mongoc_gridfs_bucket_t`. - - -Example -------- - -.. literalinclude:: ../examples/example-gridfs-bucket.c - :language: c - :caption: example-gridfs-bucket.c - -See also --------- - -- The `MongoDB GridFS specification <https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst>`_. -- The non spec-compliant :symbol:`mongoc_gridfs_t`. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_gridfs_bucket_abort_upload - mongoc_gridfs_bucket_delete_by_id - mongoc_gridfs_bucket_destroy - mongoc_gridfs_bucket_download_to_stream - mongoc_gridfs_bucket_find - mongoc_gridfs_bucket_new - mongoc_gridfs_bucket_open_download_stream - mongoc_gridfs_bucket_open_upload_stream - mongoc_gridfs_bucket_open_upload_stream_with_id - mongoc_gridfs_bucket_stream_error - mongoc_gridfs_bucket_upload_from_stream - mongoc_gridfs_bucket_upload_from_stream_with_id \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_upload_from_stream.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_upload_from_stream.rst deleted file mode 100644 index 372fed776927adcd546f0d8ac0f7446c4954183c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_upload_from_stream.rst +++ /dev/null @@ -1,46 +0,0 @@ -:man_page: mongoc_gridfs_bucket_upload_from_stream - -mongoc_gridfs_bucket_upload_from_stream() -========================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_bucket_upload_from_stream (mongoc_gridfs_bucket_t *bucket, - const char *filename, - mongoc_stream_t *source, - const bson_t *opts, - bson_value_t *file_id, - bson_error_t *error); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t`. -* ``filename``: The name of the file to create. -* ``source``: A :symbol:`mongoc_stream_t` used as the source of the data to upload. -* ``opts``: A :symbol:`bson_t` or ``NULL``. -* ``file_id``: A :symbol:`bson_value_t` to receive the generated id of the file or ``NULL``. -* ``error``: A :symbol:`bson_error_t` to receive any error or ``NULL``. - -.. include:: includes/gridfs-bucket-upload-opts.txt - -Description ------------ - -Reads from the ``source`` stream and writes to a new file in GridFS. The file id is generated automatically. -To specify an explicit file id, use :symbol:`mongoc_gridfs_bucket_upload_from_stream_with_id()`. - -Reads from the ``source`` stream using :symbol:`mongoc_stream_read()` until the return value indicates end-of-file. -The ``source`` stream is not closed after calling :symbol:`mongoc_gridfs_bucket_upload_from_stream()`; call :symbol:`mongoc_stream_close()` after. - -See Also --------- -:symbol:`mongoc_stream_file_new` and :symbol:`mongoc_stream_file_new_for_path`, which can be used to create a source stream from a file. - -Returns -------- -True if the operation succeeded. False otherwise and sets ``error``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_upload_from_stream_with_id.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_upload_from_stream_with_id.rst deleted file mode 100644 index ec1102c0fbdf258c30b59e1efe6a4a2e0dbed058..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_bucket_upload_from_stream_with_id.rst +++ /dev/null @@ -1,46 +0,0 @@ -:man_page: mongoc_gridfs_bucket_upload_from_stream_with_id - -mongoc_gridfs_bucket_upload_from_stream_with_id() -================================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_bucket_upload_from_stream_with_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - const char *filename, - mongoc_stream_t *source, - const bson_t *opts, - bson_error_t *error); - -Parameters ----------- - -* ``bucket``: A :symbol:`mongoc_gridfs_bucket_t`. -* ``file_id``: A :symbol:`bson_value_t` specifying the id of the created file. -* ``filename``: The name of the file to create. -* ``source``: A :symbol:`mongoc_stream_t` used as the source of the data to upload. -* ``opts``: A :symbol:`bson_t` or ``NULL``. -* ``error``: A :symbol:`bson_error_t` to receive any error or ``NULL``. - -.. include:: includes/gridfs-bucket-upload-opts.txt - -Description ------------ - -Reads from the ``source`` stream and writes to a new file in GridFS. -To have libmongoc generate an id, use :symbol:`mongoc_gridfs_bucket_upload_from_stream()`. - -Reads from the ``source`` stream using :symbol:`mongoc_stream_read()` until the return value indicates end-of-file. -The ``source`` stream is not closed after calling :symbol:`mongoc_gridfs_bucket_upload_from_stream()`; call :symbol:`mongoc_stream_close()` after. - -See Also --------- -:symbol:`mongoc_stream_file_new` and :symbol:`mongoc_stream_file_new_for_path`, which can be used to create a source stream from a file. - -Returns -------- -True if the operation succeeded. False otherwise and sets ``error``. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_create_file.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_create_file.rst deleted file mode 100644 index 1f3aadc979d03d2bb9ca6782663eb0e800ac75af..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_create_file.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_gridfs_create_file - -mongoc_gridfs_create_file() -=========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_file_t * - mongoc_gridfs_create_file (mongoc_gridfs_t *gridfs, - mongoc_gridfs_file_opt_t *opt); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``opt``: A :symbol:`mongoc_gridfs_file_opt_t` to specify file options. - -Description ------------ - -This function shall create a new :symbol:`mongoc_gridfs_file_t`. - -Use :symbol:`mongoc_gridfs_file_writev()` to write to the file. - -Returns -------- - -Returns a newly allocated :symbol:`mongoc_gridfs_file_t` that should be freed with :symbol:`mongoc_gridfs_file_destroy()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_create_file_from_stream.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_create_file_from_stream.rst deleted file mode 100644 index 88c43ce909c41834bc4c7e4f84907b7c1fd57aee..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_create_file_from_stream.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_gridfs_create_file_from_stream - -mongoc_gridfs_create_file_from_stream() -======================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_file_t * - mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t *gridfs, - mongoc_stream_t *stream, - mongoc_gridfs_file_opt_t *opt); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``stream``: A :symbol:`mongoc_stream_t`. -* ``opt``: A :symbol:`mongoc_gridfs_file_opt_t` to specify file options. - -Description ------------ - -This function shall create a new :symbol:`mongoc_gridfs_file_t` and fill it with the contents of ``stream``. Note that this function will read from ``stream`` until End of File, making it best suited for file-backed streams. - -Returns -------- - -A newly allocated :symbol:`mongoc_gridfs_file_t` that should be freed with :symbol:`mongoc_gridfs_file_destroy()` when no longer in use. -Returns NULL and logs an error message if there is a network or server error writing data to the MongoDB server. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_destroy.rst deleted file mode 100644 index f9b19b0151dbe4aa3522c889a8553affc9dcefb9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_gridfs_destroy - -mongoc_gridfs_destroy() -======================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_destroy (mongoc_gridfs_t *gridfs); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. - -Description ------------ - -This function shall destroy the gridfs structure referenced by ``gridfs`` and any resources associated with the gridfs. Does nothing if ``gridfs`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_drop.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_drop.rst deleted file mode 100644 index eea57d2c868eff04bcb5afea5e610a0f97846d85..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_drop.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_gridfs_drop - -mongoc_gridfs_drop() -==================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_drop (mongoc_gridfs_t *gridfs, bson_error_t *error); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Requests that an entire GridFS be dropped, including all files associated with it. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_destroy.rst deleted file mode 100644 index e923f38d177b9bed76eaf4c53e2d38b8869167f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_gridfs_file_destroy - -mongoc_gridfs_file_destroy() -============================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_file_destroy (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Destroys the :symbol:`mongoc_gridfs_file_t` instance and any resources associated with it. Does nothing if ``file`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_error.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_error.rst deleted file mode 100644 index 5eb5d4d67ed8e31a1a2582cbe0fb8ae8243a6790..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_error.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_gridfs_file_error - -mongoc_gridfs_file_error() -========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_file_error (mongoc_gridfs_file_t *file, bson_error_t *error); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function checks to see if there has been an error associated with the last operation upon ``file``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns false if there has been no registered error, otherwise true and error is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_aliases.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_aliases.rst deleted file mode 100644 index a33e4ccc7f89b37a9d774206e4aed00569fe0a77..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_aliases.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_get_aliases - -mongoc_gridfs_file_get_aliases() -================================ - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_gridfs_file_get_aliases (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches the aliases associated with a gridfs file. - -Returns -------- - -Returns a :symbol:`const bson_t * <bson:bson_t>` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_chunk_size.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_chunk_size.rst deleted file mode 100644 index 2ac04ce1164223a69649c0fbe1b62392634e54f1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_chunk_size.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_get_chunk_size - -mongoc_gridfs_file_get_chunk_size() -=================================== - -Synopsis --------- - -.. code-block:: c - - int32_t - mongoc_gridfs_file_get_chunk_size (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches the chunk size used with the underlying gridfs file. - -Returns -------- - -A signed 32-bit integer. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_content_type.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_content_type.rst deleted file mode 100644 index cd8314420ffe83d863b5547e07836024291b921c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_content_type.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_get_content_type - -mongoc_gridfs_file_get_content_type() -===================================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_gridfs_file_get_content_type (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches the content type specified for the underlying file. - -Returns -------- - -Returns a string which should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_filename.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_filename.rst deleted file mode 100644 index 56778b2986615f3d613b126ba0ca97e38454d5ff..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_filename.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_get_filename - -mongoc_gridfs_file_get_filename() -================================= - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_gridfs_file_get_filename (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches the filename for the given gridfs file. - -Returns -------- - -A string which should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_id.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_id.rst deleted file mode 100644 index efdf04e1f3cc1061506fe0f32f0bf7fe32a71c48..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_id.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_gridfs_file_get_id - -mongoc_gridfs_file_get_id() -=========================== - -Synopsis --------- - -.. code-block:: c - - const bson_value_t * - mongoc_gridfs_file_get_id (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches the id of a gridfs file. - -The C Driver always uses an ObjectId for ``_id``, but files created by other drivers may have any type of ``_id``. - -Returns -------- - -Returns a :symbol:`const bson_value_t * <bson:bson_value_t>` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_length.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_length.rst deleted file mode 100644 index cb75a4d6d9e9db3d636f205c882ccdb06c014121..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_length.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_get_length - -mongoc_gridfs_file_get_length() -=============================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_gridfs_file_get_length (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches the length of the gridfs file in bytes. - -Returns -------- - -A 64-bit signed integer. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_md5.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_md5.rst deleted file mode 100644 index b3e5fa1a6f8afc8d06ffcaf037cd1f8ee93c695e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_md5.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_get_md5 - -mongoc_gridfs_file_get_md5() -============================ - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_gridfs_file_get_md5 (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches the pre-computed MD5 for the underlying gridfs file. - -Returns -------- - -Returns a string that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_metadata.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_metadata.rst deleted file mode 100644 index 5d379e93941570f8d294baa71da5767d8d6dc911..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_metadata.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_get_metadata - -mongoc_gridfs_file_get_metadata() -================================= - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_gridfs_file_get_metadata (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches a bson document containing the metadata for the gridfs file. - -Returns -------- - -Returns a :symbol:`const bson_t * <bson:bson_t>` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_upload_date.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_upload_date.rst deleted file mode 100644 index 571d6f2530e780d41ebbfb5dc94f3e7968e74f16..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_get_upload_date.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_get_upload_date - -mongoc_gridfs_file_get_upload_date() -==================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_gridfs_file_get_upload_date (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Fetches the specified upload date of the gridfs file in milliseconds since the UNIX epoch. - -Returns -------- - -A signed int64 with the upload date in milliseconds since the UNIX epoch. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_destroy.rst deleted file mode 100644 index 46125e42b3a86b98095a602f9934064da4ed0ecc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_gridfs_file_list_destroy - -mongoc_gridfs_file_list_destroy() -================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_file_list_destroy (mongoc_gridfs_file_list_t *list); - -Parameters ----------- - -* ``list``: A :symbol:`mongoc_gridfs_file_list_t`. - -Description ------------ - -Frees a ``mongoc_gridfs_file_list_t`` and releases any associated resources. Does nothing if ``list`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_error.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_error.rst deleted file mode 100644 index 64b5c09acdad8bf312c2e0cdf10c329e41dad6e1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_error.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_gridfs_file_list_error - -mongoc_gridfs_file_list_error() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_file_list_error (mongoc_gridfs_file_list_t *list, - bson_error_t *error); - -Parameters ----------- - -* ``list``: A :symbol:`mongoc_gridfs_file_list_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Fetches any error that has occurred while trying to retrieve the file list. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -false if no error has been registered, otherwise true and error is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_next.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_next.rst deleted file mode 100644 index 1862ec46775c05090706aed20010e6721859dde3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_next.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_list_next - -mongoc_gridfs_file_list_next() -============================== - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_file_t * - mongoc_gridfs_file_list_next (mongoc_gridfs_file_list_t *list); - -Parameters ----------- - -* ``list``: A :symbol:`mongoc_gridfs_file_list_t`. - -Description ------------ - -This function shall iterate the underlying gridfs file list, returning the next file each iteration. This is a blocking function. - -Returns -------- - -A newly allocated :symbol:`mongoc_gridfs_file_t` that should be freed with :symbol:`mongoc_gridfs_file_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_t.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_t.rst deleted file mode 100644 index 19281021c9c1960f896f73344095dac60d22e089..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_list_t.rst +++ /dev/null @@ -1,50 +0,0 @@ -:man_page: mongoc_gridfs_file_list_t - -mongoc_gridfs_file_list_t -========================= - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct _mongoc_gridfs_file_list_t mongoc_gridfs_file_list_t; - -Description ------------ - -``mongoc_gridfs_file_list_t`` provides a gridfs file list abstraction. It provides iteration and basic marshalling on top of a regular :symbol:`mongoc_collection_find_with_opts()` style query. In interface, it's styled after :symbol:`mongoc_cursor_t`. - -Example -------- - -.. code-block:: c - - mongoc_gridfs_file_list_t *list; - mongoc_gridfs_file_t *file; - - list = mongoc_gridfs_find (gridfs, query); - - while ((file = mongoc_gridfs_file_list_next (list))) { - do_something (file); - - mongoc_gridfs_file_destroy (file); - } - - mongoc_gridfs_file_list_destroy (list); - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_gridfs_file_list_destroy - mongoc_gridfs_file_list_error - mongoc_gridfs_file_list_next - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_opt_t.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_opt_t.rst deleted file mode 100644 index 513c31baa263fe1f3b7b4e49c3a3aa7e16d79f78..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_opt_t.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_gridfs_file_opt_t - -mongoc_gridfs_file_opt_t -======================== - -Synopsis --------- - -.. code-block:: c - - typedef struct { - const char *md5; - const char *filename; - const char *content_type; - const bson_t *aliases; - const bson_t *metadata; - uint32_t chunk_size; - } mongoc_gridfs_file_opt_t; - -Description ------------ - -This structure contains options that can be set on a :symbol:`mongoc_gridfs_file_t`. It can be used by various functions when creating a new gridfs file. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_readv.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_readv.rst deleted file mode 100644 index 3d0d2fb360e82d395c4056761fa41e3542626049..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_readv.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_gridfs_file_readv - -mongoc_gridfs_file_readv() -========================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - uint32_t timeout_msec); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``iov``: An array of :symbol:`mongoc_iovec_t`. -* ``iovcnt``: The number of elements in ``iov``. -* ``min_bytes``: The minimum number of bytes that must be read or an error will be synthesized. -* ``timeout_msec``: Unused. - -Description ------------ - -This function performs a scattered read from ``file``, potentially blocking to read from the MongoDB server. - -The ``timeout_msec`` parameter is unused. - -Returns -------- - -Returns the number of bytes read, or -1 on failure. Use :symbol:`mongoc_gridfs_file_error` to retrieve error details. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_remove.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_remove.rst deleted file mode 100644 index 7b443fa5798f82c1327e893c7df9d14fe285bd6a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_remove.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_gridfs_file_remove - -mongoc_gridfs_file_remove() -=========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_file_remove (mongoc_gridfs_file_t *file, bson_error_t *error); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Removes ``file`` and its data chunks from the MongoDB server. - -Returns -------- - -Returns ``true`` if successful. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_save.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_save.rst deleted file mode 100644 index 960e1b201f2dd10a29d80dc473c84a6db99356f2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_save.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_gridfs_file_save - -mongoc_gridfs_file_save() -========================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_file_save (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -Saves modifications to ``file`` to the MongoDB server. - -If an error occurred, false is returned and the error can be retrieved with :symbol:`mongoc_gridfs_file_error()`. - -Modifying GridFS files is NOT thread-safe. Only one thread or process can access a GridFS file while it is being modified. - -Returns -------- - -Returns true if successful, otherwise false. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_seek.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_seek.rst deleted file mode 100644 index 230376708e4ba2f7bbdea9894fcd1103c706a50c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_seek.rst +++ /dev/null @@ -1,46 +0,0 @@ -:man_page: mongoc_gridfs_file_seek - -mongoc_gridfs_file_seek() -========================= - -Synopsis --------- - -.. code-block:: c - - int - mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, int64_t delta, int whence); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``delta``: The amount to move the file position. May be positive or negative. -* ``whence``: One of SEEK_SET, SEEK_CUR or SEEK_END. - -Description ------------ - -Adjust the file position pointer in the given file by ``delta``, starting from the position ``whence``. The ``whence`` argument is interpreted as in ``fseek(2)``: - -============ ===================================================== -``SEEK_SET`` Set the position relative to the start of the file. -``SEEK_CUR`` Move ``delta`` relative to the current file position. -``SEEK_END`` Move ``delta`` relative to the end of the file. -============ ===================================================== - -On success, the file's underlying position pointer is set appropriately. On failure, the file position is NOT changed and errno is set to indicate the error. - -Errors ------- - -========== ======================================================== -``EINVAL`` ``whence`` is not one of SEEK_SET, SEEK_CUR or SEEK_END. -``EINVAL`` The resulting file position would be negative. -========== ======================================================== - -Returns -------- - -Returns 0 if successful; otherwise -1 and errno is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_aliases.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_aliases.rst deleted file mode 100644 index adf88970db920395f0ecfbb883fef8ef60c8a6fc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_aliases.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_gridfs_file_set_aliases - -mongoc_gridfs_file_set_aliases() -================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_file_set_aliases (mongoc_gridfs_file_t *file, const bson_t *bson); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``bson``: A :symbol:`bson:bson_t` containing the aliases. - -Description ------------ - -Sets the aliases for a gridfs file. - -You need to call :symbol:`mongoc_gridfs_file_save()` to persist this change. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_content_type.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_content_type.rst deleted file mode 100644 index 58377ecca7ad4f7ae5c5cdb5801daa44828cf76e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_content_type.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_gridfs_file_set_content_type - -mongoc_gridfs_file_set_content_type() -===================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_file_set_content_type (mongoc_gridfs_file_t *file, - const char *content_type); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``str``: A string containing the content type. - -Description ------------ - -Sets the content type for the gridfs file. This should be something like ``"text/plain"``. - -You need to call :symbol:`mongoc_gridfs_file_save()` to persist this change. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_filename.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_filename.rst deleted file mode 100644 index 6b6f3656c41c8b17136f28ac8f98cfded94da317..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_filename.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_gridfs_file_set_filename - -mongoc_gridfs_file_set_filename() -================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_file_set_filename (mongoc_gridfs_file_t *file, - const char *filename); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``str``: A UTF-8 encoded string containing the filename. - -Description ------------ - -Sets the filename for ``file``. - -You need to call :symbol:`mongoc_gridfs_file_save()` to persist this change. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_id.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_id.rst deleted file mode 100644 index d061fd7bb814d64a1a49ea3cad0bee99ca6cb62c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_id.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_gridfs_file_set_id - -mongoc_gridfs_file_set_id() -=========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_file_set_id (mongoc_gridfs_file_t *file, - const bson_value_t *id, - bson_error_t error); - -Parameters ----------- - -* ``file``: A :symbol:` mongoc_gridfs_file_t <mongoc_gridfs_file_t>`. -* ``id``: A :symbol:`bson:bson_value_t`. -* ``error``: A :symbol:`bson_error_t <errors>`. - -Description ------------ - -Sets the id of ``file`` to any BSON type. - -If an error occurred, false is returned. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and logs an error. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_md5.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_md5.rst deleted file mode 100644 index d99039192d157fe76b142cb99bb810a6f95ba02e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_md5.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_gridfs_file_set_md5 - -mongoc_gridfs_file_set_md5() -============================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_file_set_md5 (mongoc_gridfs_file_t *file, const char *md5); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``str``: A string containing the MD5 of the file. - -Description ------------ - -Sets the MD5 checksum for ``file``. - -You need to call :symbol:`mongoc_gridfs_file_save()` to persist this change. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_metadata.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_metadata.rst deleted file mode 100644 index 6ffd05e2964491e0a960003151bbc8aefec2a314..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_set_metadata.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_gridfs_file_set_metadata - -mongoc_gridfs_file_set_metadata() -================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_gridfs_file_set_metadata (mongoc_gridfs_file_t *file, - const bson_t *metadata); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``bson``: A :symbol:`bson:bson_t` containing metadata for ``file``. - -Description ------------ - -Sets the metadata associated with ``file``. - -You need to call :symbol:`mongoc_gridfs_file_save()` to persist this change. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_t.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_t.rst deleted file mode 100644 index 103c3ac3c1ffcacaf11eabe9a52ffff95e74b55f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_t.rst +++ /dev/null @@ -1,68 +0,0 @@ -:man_page: mongoc_gridfs_file_t - -mongoc_gridfs_file_t -==================== - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_gridfs_file_t mongoc_gridfs_file_t; - -Description ------------ - -This structure provides a MongoDB GridFS file abstraction. It provides several APIs. - -* readv, writev, seek, and tell. -* General file metadata such as filename and length. -* GridFS metadata such as md5, filename, content_type, aliases, metadata, chunk_size, and upload_date. - -Thread Safety -------------- - -This structure is NOT thread-safe and should only be used from one thread at a time. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_gridfs_file_destroy - mongoc_gridfs_file_error - mongoc_gridfs_file_get_aliases - mongoc_gridfs_file_get_chunk_size - mongoc_gridfs_file_get_content_type - mongoc_gridfs_file_get_filename - mongoc_gridfs_file_get_id - mongoc_gridfs_file_get_length - mongoc_gridfs_file_get_md5 - mongoc_gridfs_file_get_metadata - mongoc_gridfs_file_get_upload_date - mongoc_gridfs_file_readv - mongoc_gridfs_file_remove - mongoc_gridfs_file_save - mongoc_gridfs_file_seek - mongoc_gridfs_file_set_aliases - mongoc_gridfs_file_set_content_type - mongoc_gridfs_file_set_filename - mongoc_gridfs_file_set_id - mongoc_gridfs_file_set_md5 - mongoc_gridfs_file_set_metadata - mongoc_gridfs_file_tell - mongoc_gridfs_file_writev - mongoc_stream_gridfs_new - -Related -------- - -* :symbol:`mongoc_client_t` -* :symbol:`mongoc_gridfs_t` -* :symbol:`mongoc_gridfs_file_list_t` -* :symbol:`mongoc_gridfs_file_opt_t` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_tell.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_tell.rst deleted file mode 100644 index 4a6cc071b7a2d512a63557f7df2da14b16d7a554..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_tell.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_file_tell - -mongoc_gridfs_file_tell() -========================= - -Synopsis --------- - -.. code-block:: c - - uint64_t - mongoc_gridfs_file_tell (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -Description ------------ - -This function returns the current position indicator within ``file``. - -Returns -------- - -Returns a file position as an unsigned 64-bit integer. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_writev.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_writev.rst deleted file mode 100644 index 27e110d2ee82c99b9b02b8f3077c74efaea6c2e6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_file_writev.rst +++ /dev/null @@ -1,37 +0,0 @@ -:man_page: mongoc_gridfs_file_writev - -mongoc_gridfs_file_writev() -=========================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, - const mongoc_iovec_t *iov, - size_t iovcnt, - uint32_t timeout_msec); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. -* ``iov``: An array of :symbol:`mongoc_iovec_t`. -* ``iovcnt``: The number of elements in ``iov``. -* ``timeout_msec``: Unused. - -Description ------------ - -Performs a gathered write to the underlying gridfs file. - -The ``timeout_msec`` parameter is unused. - -Modifying GridFS files is NOT thread-safe. Only one thread or process can access a GridFS file while it is being modified. - -Returns -------- - -Returns the number of bytes written, or -1 on failure. Use :symbol:`mongoc_gridfs_file_error` to retrieve error details. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_find.rst deleted file mode 100644 index 4023c7df205749a8603b1581a9984e7cd14963f7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find.rst +++ /dev/null @@ -1,37 +0,0 @@ -:man_page: mongoc_gridfs_find - -mongoc_gridfs_find() -==================== - -Deprecated ----------- - -This function is deprecated, use :symbol:`mongoc_gridfs_find_with_opts` instead. - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_file_list_t * - mongoc_gridfs_find (mongoc_gridfs_t *gridfs, const bson_t *query) - BSON_GNUC_DEPRECATED_FOR (mongoc_gridfs_find_with_opts); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``query``: A :symbol:`bson:bson_t`. - -Description ------------ - -Finds all gridfs files matching ``query``. You can iterate the matched gridfs files with the resulting file list. - -.. include:: includes/retryable-read.txt - -Returns -------- - -A newly allocated :symbol:`mongoc_gridfs_file_list_t` that should be freed with :symbol:`mongoc_gridfs_file_list_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one.rst deleted file mode 100644 index 94d143bf7177015ff2851db5a90a3b147ac168cd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one.rst +++ /dev/null @@ -1,45 +0,0 @@ -:man_page: mongoc_gridfs_find_one - -mongoc_gridfs_find_one() -======================== - -Deprecated ----------- - -This function is deprecated, use :symbol:`mongoc_gridfs_find_one_with_opts` instead. - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_file_t * - mongoc_gridfs_find_one (mongoc_gridfs_t *gridfs, - const bson_t *query, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_gridfs_find_one_with_opts); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``query``: A :symbol:`bson:bson_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -This function shall execute a query on the underlying gridfs implementation. The first file matching ``query`` will be returned. If there is an error, NULL is returned and ``error`` is filled out; if there is no error but no matching file is found, NULL is returned and the error code and domain are 0. - -.. include:: includes/retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -A newly allocated :symbol:`mongoc_gridfs_file_t` or ``NULL`` if no file could be found. You must free the resulting file with :symbol:`mongoc_gridfs_file_destroy()` if non-NULL. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one_by_filename.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one_by_filename.rst deleted file mode 100644 index b0e84e726f85c03bf3066e406066b5d72fd18387..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one_by_filename.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_gridfs_find_one_by_filename - -mongoc_gridfs_find_one_by_filename() -==================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_file_t * - mongoc_gridfs_find_one_by_filename (mongoc_gridfs_t *gridfs, - const char *filename, - bson_error_t *error); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``filename``: A UTF-8 encoded string containing the filename. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Finds the first file matching the filename specified. If there is an error, NULL is returned and ``error`` is filled out; if there is no error but no matching file is found, NULL is returned and the error code and domain are 0. - -.. include:: includes/retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns a newly allocated :symbol:`mongoc_gridfs_file_t` if successful. You must free the resulting file with :symbol:`mongoc_gridfs_file_destroy()` when no longer in use. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one_with_opts.rst deleted file mode 100644 index ad75810673a13b69b108143f29076c8839d99c94..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_one_with_opts.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_gridfs_find_one_with_opts - -mongoc_gridfs_find_one_with_opts() -================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_file_t * - mongoc_gridfs_find_one_with_opts (mongoc_gridfs_t *gridfs, - const bson_t *filter, - const bson_t *opts, - bson_error_t *error) - BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``filter``: A :symbol:`bson:bson_t` containing the query to execute. -* ``opts``: A :symbol:`bson:bson_t` query options, including sort order and which fields to return. Can be ``NULL``. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Find the first GridFS file matching ``filter``. If there is an error, NULL is returned and ``error`` is filled out; if there is no error but no matching file is found, NULL is returned and the error code and domain are 0. - -See :symbol:`mongoc_collection_find_with_opts` for a description of the ``filter`` and ``opts`` parameters. - -.. include:: includes/retryable-read.txt - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -Returns a newly allocated :symbol:`mongoc_gridfs_file_t` if successful. You must free the resulting file with :symbol:`mongoc_gridfs_file_destroy()` when no longer in use. diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_with_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_with_opts.rst deleted file mode 100644 index 517cc9e8ba0148277eb4d074dbb3504fa3ebcc7d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_find_with_opts.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_gridfs_find_with_opts - -mongoc_gridfs_find_with_opts() -============================== - -Synopsis --------- - -.. code-block:: c - - mongoc_gridfs_file_list_t * - mongoc_gridfs_find_with_opts (mongoc_gridfs_t *gridfs, - const bson_t *filter, - const bson_t *opts) BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``filter``: A :symbol:`bson:bson_t` containing the query to execute. -* ``opts``: A :symbol:`bson:bson_t` query options, including sort order and which fields to return. Can be ``NULL``. - -Description ------------ - -Finds all gridfs files matching ``filter``. You can iterate the matched gridfs files with the resulting file list. - -See :symbol:`mongoc_collection_find_with_opts` for a description of the ``filter`` and ``opts`` parameters. - -.. include:: includes/retryable-read.txt - -Returns -------- - -A newly allocated :symbol:`mongoc_gridfs_file_list_t` that should be freed with :symbol:`mongoc_gridfs_file_list_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_get_chunks.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_get_chunks.rst deleted file mode 100644 index 62b632e18904de62a1452c955f5e2954af17b1e6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_get_chunks.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_get_chunks - -mongoc_gridfs_get_chunks() -========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_collection_t * - mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. - -Description ------------ - -Returns a :symbol:`mongoc_collection_t` that contains the chunks for files. This instance is owned by the :symbol:`mongoc_gridfs_t` instance and should not be modified or freed. - -Returns -------- - -Returns a :symbol:`mongoc_collection_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_get_files.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_get_files.rst deleted file mode 100644 index d914828869d380a59654ec13cf5b26c257da51c7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_get_files.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_gridfs_get_files - -mongoc_gridfs_get_files() -========================= - -Synopsis --------- - -.. code-block:: c - - mongoc_collection_t * - mongoc_gridfs_get_files (mongoc_gridfs_t *gridfs); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. - -Description ------------ - -Retrieves the :symbol:`mongoc_collection_t` containing the file metadata for GridFS. This instance is owned by the :symbol:`mongoc_gridfs_t` and should not be modified or freed. - -Returns -------- - -Returns a :symbol:`mongoc_collection_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_remove_by_filename.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_remove_by_filename.rst deleted file mode 100644 index 3cca9444b3ce88ef64dca8c7363aa638244b1536..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_remove_by_filename.rst +++ /dev/null @@ -1,37 +0,0 @@ -:man_page: mongoc_gridfs_remove_by_filename - -mongoc_gridfs_remove_by_filename() -================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_gridfs_remove_by_filename (mongoc_gridfs_t *gridfs, - const char *filename, - bson_error_t *error); - -Parameters ----------- - -* ``gridfs``: A :symbol:`mongoc_gridfs_t`. -* ``filename``: A UTF-8 encoded string containing the filename. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Removes all files matching ``filename`` and their data chunks from the MongoDB server. - -Returns -------- - -Returns true if successful, including when no files match. Returns ``false`` and sets ``error`` if there are invalid arguments or a server or network error. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_gridfs_t.rst b/lib/mongoc/libmongoc/doc/mongoc_gridfs_t.rst deleted file mode 100644 index 19ffa533ce9e83ed84f235cb6f9b10a749f8955a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_gridfs_t.rst +++ /dev/null @@ -1,76 +0,0 @@ -:man_page: mongoc_gridfs_t - -mongoc_gridfs_t -=============== - -.. warning:: - - This GridFS implementation does not conform to the `MongoDB GridFS specification <https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst>`_. For a spec compliant implementation, use :symbol:`mongoc_gridfs_bucket_t`. - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct _mongoc_gridfs_t mongoc_gridfs_t; - -Description ------------ - -``mongoc_gridfs_t`` provides a MongoDB gridfs implementation. The system as a whole is made up of ``gridfs`` objects, which contain ``gridfs_files`` and ``gridfs_file_lists``. Essentially, a basic file system API. - -There are extensive caveats about the kind of use cases gridfs is practical for. In particular, any writing after initial file creation is likely to both break any concurrent readers and be quite expensive. That said, this implementation does allow for arbitrary writes to existing gridfs object, just use them with caution. - -mongoc_gridfs also integrates tightly with the :symbol:`mongoc_stream_t` abstraction, which provides some convenient wrapping for file creation and reading/writing. It can be used without, but its worth looking to see if your problem can fit that model. - -.. warning:: - - ``mongoc_gridfs_t`` does not support read preferences. In a replica set, GridFS queries are always routed to the primary. - -Thread Safety -------------- - -``mongoc_gridfs_t`` is NOT thread-safe and should only be used in the same thread as the owning :symbol:`mongoc_client_t`. - -Lifecycle ---------- - -It is an error to free a ``mongoc_gridfs_t`` before freeing all related instances of :symbol:`mongoc_gridfs_file_t` and :symbol:`mongoc_gridfs_file_list_t`. - -Example -------- - -.. literalinclude:: ../examples/example-gridfs.c - :language: c - :caption: example-gridfs.c - -See also --------- - -- The `MongoDB GridFS specification <https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst>`_. -- The spec-compliant :symbol:`mongoc_gridfs_bucket_t`. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_gridfs_create_file - mongoc_gridfs_create_file_from_stream - mongoc_gridfs_destroy - mongoc_gridfs_drop - mongoc_gridfs_find - mongoc_gridfs_find_one - mongoc_gridfs_find_one_by_filename - mongoc_gridfs_find_one_with_opts - mongoc_gridfs_find_with_opts - mongoc_gridfs_get_chunks - mongoc_gridfs_get_files - mongoc_gridfs_remove_by_filename - diff --git a/lib/mongoc/libmongoc/doc/mongoc_host_list_t.rst b/lib/mongoc/libmongoc/doc/mongoc_host_list_t.rst deleted file mode 100644 index 030c52e56ec56b5014005feecf9e8afcd250393e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_host_list_t.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_host_list_t - -mongoc_host_list_t -================== - -Synopsis --------- - -.. code-block:: c - - typedef struct { - mongoc_host_list_t *next; - char host[BSON_HOST_NAME_MAX + 1]; - char host_and_port[BSON_HOST_NAME_MAX + 7]; - uint16_t port; - int family; - void *padding[4]; - } mongoc_host_list_t; - -Description ------------ - -The host and port of a MongoDB server. Can be part of a linked list: for example the return value of :symbol:`mongoc_uri_get_hosts` when multiple hosts are provided in the MongoDB URI. - -See Also --------- - -:symbol:`mongoc_uri_get_hosts` and :symbol:`mongoc_cursor_get_host`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_get_default.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_get_default.rst deleted file mode 100644 index f72e814d2f5d6996cddbfee97559df27b3856669..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_get_default.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_index_opt_geo_get_default - -mongoc_index_opt_geo_get_default() -================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_index_opt_geo_t * - mongoc_index_opt_geo_get_default (void) BSON_GNUC_PURE; - -Returns -------- - -Returns a pointer to the default GEO index creation options. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_init.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_init.rst deleted file mode 100644 index d58d865de2c77006e7f2bbf3740b507ce9b1314c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_init.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_index_opt_geo_init - -mongoc_index_opt_geo_init() -=========================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_index_opt_geo_init (mongoc_index_opt_geo_t *opt); - -Parameters ----------- - -* ``opt``: A :symbol:`mongoc_index_opt_geo_t`. - -Description ------------ - -This function will initialize ``opt`` to the default values. It should be called before modifying any fields within the structure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_t.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_t.rst deleted file mode 100644 index 70fb42b8c73b33a9684dca6482a9a26210d0c9e0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_geo_t.rst +++ /dev/null @@ -1,45 +0,0 @@ -:man_page: mongoc_index_opt_geo_t - -mongoc_index_opt_geo_t -====================== - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct { - uint8_t twod_sphere_version; - uint8_t twod_bits_precision; - double twod_location_min; - double twod_location_max; - double haystack_bucket_size; - uint8_t *padding[32]; - } mongoc_index_opt_geo_t; - -Description ------------ - -This structure contains the options that may be used for tuning a GEO index. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_index_opt_geo_get_default - mongoc_index_opt_geo_init - -See Also --------- - -:doc:`mongoc_index_opt_t` - -:doc:`mongoc_index_opt_wt_t` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_get_default.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_get_default.rst deleted file mode 100644 index 068a33a23d4c5de8f10425ff0e29bd7037da7979..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_get_default.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_index_opt_get_default - -mongoc_index_opt_get_default() -============================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_index_opt_t * - mongoc_index_opt_get_default (void) BSON_GNUC_PURE; - -Returns -------- - -Returns a pointer to the default index creation options. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_init.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_init.rst deleted file mode 100644 index 6633a40cd90810cd650c2b9a1876086a66d3da1e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_init.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_index_opt_init - -mongoc_index_opt_init() -======================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_index_opt_init (mongoc_index_opt_t *opt); - -Parameters ----------- - -* ``opt``: A :symbol:`mongoc_index_opt_t`. - -Description ------------ - -This function will initialize ``opt`` to the default values. It should be called before modifying any fields within the structure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_t.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_t.rst deleted file mode 100644 index b5d4a46467f5527f7359691477801d731cf28db4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_t.rst +++ /dev/null @@ -1,96 +0,0 @@ -:man_page: mongoc_index_opt_t - -mongoc_index_opt_t -================== - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct { - bool is_initialized; - bool background; - bool unique; - const char *name; - bool drop_dups; - bool sparse; - int32_t expire_after_seconds; - int32_t v; - const bson_t *weights; - const char *default_language; - const char *language_override; - mongoc_index_opt_geo_t *geo_options; - mongoc_index_opt_storage_t *storage_options; - const bson_t *partial_filter_expression; - const bson_t *collation; - void *padding[4]; - } mongoc_index_opt_t; - -Deprecated ----------- - -This structure is deprecated and should not be used in new code. See :doc:`create-indexes`. - -Description ------------ - -This structure contains the options that may be used for tuning a specific index. - -See the `createIndexes documentations <https://docs.mongodb.org/manual/reference/command/createIndexes/>`_ in the MongoDB manual for descriptions of individual options. - -.. note:: - - dropDups is deprecated as of MongoDB version 3.0.0. This option is silently ignored by the server and unique index builds using this option will fail if a duplicate value is detected. - -Example -------- - -.. code-block:: c - - { - bson_t keys; - bson_error_t error; - mongoc_index_opt_t opt; - mongoc_index_opt_geo_t geo_opt; - - mongoc_index_opt_init (&opt); - mongoc_index_opt_geo_init (&geo_opt); - - bson_init (&keys); - BSON_APPEND_UTF8 (&keys, "location", "2d"); - - geo_opt.twod_location_min = -123; - geo_opt.twod_location_max = +123; - geo_opt.twod_bits_precision = 30; - opt.geo_options = &geo_opt; - - collection = mongoc_client_get_collection (client, "test", "geo_test"); - if (mongoc_collection_create_index (collection, &keys, &opt, &error)) { - /* Successfully created the geo index */ - } - bson_destroy (&keys); - mongoc_collection_destroy (&collection); - } - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_index_opt_get_default - mongoc_index_opt_init - -See Also --------- - -:doc:`mongoc_index_opt_geo_t` - -:doc:`mongoc_index_opt_wt_t` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_get_default.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_get_default.rst deleted file mode 100644 index 3057f3fbbfafec2d432f980b67681684388b8afa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_get_default.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_index_opt_wt_get_default - -mongoc_index_opt_wt_get_default() -================================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_index_opt_wt_t * - mongoc_index_opt_wt_get_default (void) BSON_GNUC_PURE; - -Returns -------- - -Returns a pointer to the default WiredTiger index creation options. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_init.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_init.rst deleted file mode 100644 index cbfa67f1da8752f593d4e050c6ba8459c8234f77..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_init.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_index_opt_wt_init - -mongoc_index_opt_wt_init() -========================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_index_opt_wt_init (mongoc_index_opt_wt_t *opt); - -Parameters ----------- - -* ``opt``: A :symbol:`mongoc_index_opt_wt_t`. - -Description ------------ - -This function will initialize ``opt`` to the default values. It should be called before modifying any fields within the structure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_t.rst b/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_t.rst deleted file mode 100644 index 86643840ed09edec3d3bd934d0550ff7403a2497..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_index_opt_wt_t.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_index_opt_wt_t - -mongoc_index_opt_wt_t -===================== - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct { - mongoc_index_opt_storage_t base; - const char *config_str; - void *padding[8]; - } mongoc_index_opt_wt_t; - -Description ------------ - -This structure contains the options that may be used for tuning a WiredTiger specific index. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_index_opt_wt_get_default - mongoc_index_opt_wt_init - -See Also --------- - -:doc:`mongoc_index_opt_t` - -:doc:`mongoc_index_opt_geo_t` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_init.rst b/lib/mongoc/libmongoc/doc/mongoc_init.rst deleted file mode 100644 index 49f0fc72dda7edaf301c53afae57428839a407cf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_init.rst +++ /dev/null @@ -1,17 +0,0 @@ -:man_page: mongoc_init - -mongoc_init() -============= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_init (void); - -Description ------------ - -.. include:: includes/init_cleanup.txt diff --git a/lib/mongoc/libmongoc/doc/mongoc_insert_flags_t.rst b/lib/mongoc/libmongoc/doc/mongoc_insert_flags_t.rst deleted file mode 100644 index e12c912067a398e1d2343565cc38e707287a4b99..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_insert_flags_t.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_insert_flags_t - -mongoc_insert_flags_t -===================== - -Flags for insert operations - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_INSERT_NONE = 0, - MONGOC_INSERT_CONTINUE_ON_ERROR = 1 << 0, - } mongoc_insert_flags_t; - - #define MONGOC_INSERT_NO_VALIDATE (1U << 31) - -Description ------------ - -These flags correspond to the MongoDB wire protocol. They may be bitwise or'd together. They may modify how an insert happens on the MongoDB server. - -Flag Values ------------ - -=============================== ====================================================================================================================================================================== -MONGOC_INSERT_NONE Specify no insert flags. -MONGOC_INSERT_CONTINUE_ON_ERROR Continue inserting documents from the insertion set even if one insert fails. -MONGOC_INSERT_NO_VALIDATE Do not validate insertion documents before performing an insert. Validation can be expensive, so this can save some time if you know your documents are already valid. -=============================== ====================================================================================================================================================================== - diff --git a/lib/mongoc/libmongoc/doc/mongoc_iovec_t.rst b/lib/mongoc/libmongoc/doc/mongoc_iovec_t.rst deleted file mode 100644 index e8ab492ea5d0eae591e0b162ac3f7630a9d64e63..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_iovec_t.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_iovec_t - -mongoc_iovec_t -============== - -Synopsis --------- - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - #ifdef _WIN32 - typedef struct { - u_long iov_len; - char *iov_base; - } mongoc_iovec_t; - #else - typedef struct iovec mongoc_iovec_t; - #endif - -The ``mongoc_iovec_t`` structure is a portability abstraction for consumers of the :symbol:`mongoc_stream_t` interfaces. It allows for scatter/gather I/O through the socket subsystem. - -.. warning:: - - When writing portable code, beware of the ordering of ``iov_len`` and ``iov_base`` as they are different on various platforms. Therefore, you should not use C initializers for initialization. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_matcher_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_matcher_destroy.rst deleted file mode 100644 index d5f237bc6a7017e13a3caaae4f50737ffb357116..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_matcher_destroy.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_matcher_destroy - -mongoc_matcher_destroy() -======================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_matcher_destroy (mongoc_matcher_t *matcher); - -Release all resources associated with ``matcher`` including freeing the structure. - -Deprecated ----------- - -.. warning:: - - ``mongoc_matcher_t`` is deprecated and will be removed in version 2.0. - -Parameters ----------- - -* ``matcher``: A :symbol:`mongoc_matcher_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_matcher_match.rst b/lib/mongoc/libmongoc/doc/mongoc_matcher_match.rst deleted file mode 100644 index 4728f13cffd204a5bb1f2e58e575583a627d7398..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_matcher_match.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_matcher_match - -mongoc_matcher_match() -====================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_matcher_match (const mongoc_matcher_t *matcher, const bson_t *document); - -This function will check to see if the query compiled in ``matcher`` matches ``document``. - -Deprecated ----------- - -.. warning:: - - ``mongoc_matcher_t`` is deprecated and will be removed in version 2.0. - -Parameters ----------- - -* ``matcher``: A :symbol:`mongoc_matcher_t`. -* ``query``: A :symbol:`bson:bson_t` that contains the query. - -Returns -------- - -``true`` if ``document`` matches the query specification provided to :symbol:`mongoc_matcher_new()`. Otherwise, ``false``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_matcher_new.rst b/lib/mongoc/libmongoc/doc/mongoc_matcher_new.rst deleted file mode 100644 index 7cb94275e3f40e3828e599f3d24fd7530163c525..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_matcher_new.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_matcher_new - -mongoc_matcher_new() -==================== - -Synopsis --------- - -.. code-block:: c - - mongoc_matcher_t * - mongoc_matcher_new (const bson_t *query, bson_error_t *error); - -Create a new :symbol:`mongoc_matcher_t` using the query specification provided. - -Deprecated ----------- - -.. warning:: - - ``mongoc_matcher_t`` is deprecated and will be removed in version 2.0. - -Parameters ----------- - -* ``query``: A :symbol:`bson:bson_t`. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Errors ------- - -Errors are propagated via the ``error`` parameter. - -Returns -------- - -A newly allocated :symbol:`mongoc_matcher_t` that should be freed with :symbol:`mongoc_matcher_destroy()` when no longer in use. Upon failure, ``NULL`` is returned and ``error`` is set. This could happen if ``query`` contains an invalid query specification. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_matcher_t.rst b/lib/mongoc/libmongoc/doc/mongoc_matcher_t.rst deleted file mode 100644 index 86beeaad9a85bc3cc955eb3bd5a4783aa2de2a26..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_matcher_t.rst +++ /dev/null @@ -1,91 +0,0 @@ -:man_page: mongoc_matcher_t - -mongoc_matcher_t -================ - -Client-side document matching abstraction - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_matcher_t mongoc_matcher_t; - -``mongoc_matcher_t`` provides a reduced-interface for client-side matching of BSON documents. - -It can perform the basics such as $in, $nin, $eq, $neq, $gt, $gte, $lt, and $lte. - -.. warning:: - - ``mongoc_matcher_t`` does not currently support the full spectrum of query operations that the MongoDB server supports. - -Deprecated ----------- - -.. warning:: - - ``mongoc_matcher_t`` is deprecated and will be removed in version 2.0. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_matcher_destroy - mongoc_matcher_match - mongoc_matcher_new - -Example -------- - -.. code-block:: c - :caption: Filter a sequence of BSON documents from STDIN based on a query - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - int - main (int argc, char *argv[]) - { - mongoc_matcher_t *matcher; - bson_reader_t *reader; - const bson_t *bson; - bson_t *spec; - char *str; - int fd; - - mongoc_init (); - - #ifdef _WIN32 - fd = fileno (stdin); - #else - fd = STDIN_FILENO; - #endif - - reader = bson_reader_new_from_fd (fd, false); - - spec = BCON_NEW ("hello", "world"); - matcher = mongoc_matcher_new (spec, NULL); - - while ((bson = bson_reader_read (reader, NULL))) { - if (mongoc_matcher_match (matcher, bson)) { - str = bson_as_canonical_extended_json (bson, NULL); - printf ("%s\n", str); - bson_free (str); - } - } - - bson_reader_destroy (reader); - bson_destroy (spec); - - mongoc_cleanup (); - - return 0; - } - diff --git a/lib/mongoc/libmongoc/doc/mongoc_query_flags_t.rst b/lib/mongoc/libmongoc/doc/mongoc_query_flags_t.rst deleted file mode 100644 index c2aacb021177ad3b80e92485bb23fd308569ccf8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_query_flags_t.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_query_flags_t - -mongoc_query_flags_t -==================== - -Flags for query operations - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_QUERY_NONE = 0, - MONGOC_QUERY_TAILABLE_CURSOR = 1 << 1, - MONGOC_QUERY_SLAVE_OK = 1 << 2, - MONGOC_QUERY_OPLOG_REPLAY = 1 << 3, - MONGOC_QUERY_NO_CURSOR_TIMEOUT = 1 << 4, - MONGOC_QUERY_AWAIT_DATA = 1 << 5, - MONGOC_QUERY_EXHAUST = 1 << 6, - MONGOC_QUERY_PARTIAL = 1 << 7, - } mongoc_query_flags_t; - -Description ------------ - -These flags correspond to the MongoDB wire protocol. They may be bitwise or'd together. They may modify how a query is performed in the MongoDB server. - -Flag Values ------------ - -============================== ===================================================================================================================================================== -MONGOC_QUERY_NONE Specify no query flags. -MONGOC_QUERY_TAILABLE_CURSOR Cursor will not be closed when the last data is retrieved. You can resume this cursor later. -MONGOC_QUERY_SLAVE_OK Allow query of replica set secondaries. -MONGOC_QUERY_OPLOG_REPLAY Used internally by MongoDB. -MONGOC_QUERY_NO_CURSOR_TIMEOUT The server normally times out an idle cursor after an inactivity period (10 minutes). This prevents that. -MONGOC_QUERY_AWAIT_DATA Use with MONGOC_QUERY_TAILABLE_CURSOR. Block rather than returning no data. After a period, time out. -MONGOC_QUERY_EXHAUST Stream the data down full blast in multiple "reply" packets. Faster when you are pulling down a lot of data and you know you want to retrieve it all. -MONGOC_QUERY_PARTIAL Get partial results from mongos if some shards are down (instead of throwing an error). -============================== ===================================================================================================================================================== - diff --git a/lib/mongoc/libmongoc/doc/mongoc_rand.rst b/lib/mongoc/libmongoc/doc/mongoc_rand.rst deleted file mode 100644 index 8170c4194f854b4bc5a5c974690f808391f927ba..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_rand.rst +++ /dev/null @@ -1,51 +0,0 @@ -:man_page: mongoc_rand - -mongoc_rand -=========== - -MongoDB Random Number Generator - -Synopsis --------- - -.. code-block:: c - - void - mongoc_rand_add (const void *buf, int num, double entropy); - - void - mongoc_rand_seed (const void *buf, int num); - - int - mongoc_rand_status (void); - -Description ------------ - -The ``mongoc_rand`` family of functions provide access to the low level randomness primitives used by the MongoDB C Driver. In particular, they control the creation of cryptographically strong pseudo-random bytes required by some security mechanisms. - -While we can usually pull enough entropy from the environment, you may be required to seed the PRNG manually depending on your OS, hardware and other entropy consumers running on the same system. - -Entropy -------- - -``mongoc_rand_add`` and ``mongoc_rand_seed`` allow the user to directly provide entropy. They differ insofar as ``mongoc_rand_seed`` requires that each bit provided is fully random. ``mongoc_rand_add`` allows the user to specify the degree of randomness in the provided bytes as well. - -Status ------- - -The ``mongoc_rand_status`` function allows the user to check the status of the mongoc PRNG. This can be used to guarantee sufficient entropy at program startup, rather than waiting for runtime errors to occur. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_rand_add - mongoc_rand_seed - mongoc_rand_status - diff --git a/lib/mongoc/libmongoc/doc/mongoc_rand_add.rst b/lib/mongoc/libmongoc/doc/mongoc_rand_add.rst deleted file mode 100644 index be0d7a3204eefea5eafa19311a5a3755dc9beeed..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_rand_add.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_rand_add - -mongoc_rand_add() -================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_rand_add (const void *buf, int num, double entropy); - -Description ------------ - -Mixes num bytes of data into the mongoc random number generator. Entropy specifies a lower bound estimate of the randomness contained in buf. - -Parameters ----------- - -* ``buf``: A buffer. -* ``num``: An int of number of bytes in buf. -* ``entropy``: A double of randomness estimate in buf. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_rand_seed.rst b/lib/mongoc/libmongoc/doc/mongoc_rand_seed.rst deleted file mode 100644 index 31aa0fbe12827e99db1feaa41433296da7726f3f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_rand_seed.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_rand_seed - -mongoc_rand_seed() -================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_rand_seed (const void *buf, int num); - -Description ------------ - -Seeds the mongoc random number generator with num bytes of entropy. - -Parameters ----------- - -* ``buf``: A buffer. -* ``num``: An int of number of bytes in buf. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_rand_status.rst b/lib/mongoc/libmongoc/doc/mongoc_rand_status.rst deleted file mode 100644 index b0143b3413d7e7646592a007af29d2cce1533e22..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_rand_status.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_rand_status - -mongoc_rand_status() -==================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_rand_status (void); - -Description ------------ - -The status of the mongoc random number generator. - -Returns -------- - -Returns 1 if the PRNG has been seeded with enough data, 0 otherwise. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_concern_append.rst b/lib/mongoc/libmongoc/doc/mongoc_read_concern_append.rst deleted file mode 100644 index 4c848de1a524114b2c06647cc4c8ed6a825ae132..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_concern_append.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_read_concern_append - -mongoc_read_concern_append() -============================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_read_concern_append (mongoc_read_concern_t *read_concern, bson_t *opts); - -Parameters ----------- - -* ``read_concern``: A pointer to a :symbol:`mongoc_read_concern_t`. -* ``command``: A pointer to a :symbol:`bson:bson_t`. - -Description ------------ - -This function appends a read concern to command options. It is useful for appending a read concern to command options before passing them to :symbol:`mongoc_client_read_command_with_opts` or a related function that takes an options document. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and logs an error. - -Example -------- - -See the example code for :symbol:`mongoc_client_read_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_concern_copy.rst b/lib/mongoc/libmongoc/doc/mongoc_read_concern_copy.rst deleted file mode 100644 index cccacf0c39f24c27350bcee76eb52e607ba757ef..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_concern_copy.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_read_concern_copy - -mongoc_read_concern_copy() -========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_read_concern_t * - mongoc_read_concern_copy (const mongoc_read_concern_t *read_concern); - -Parameters ----------- - -* ``read_concern``: A :symbol:`mongoc_read_concern_t`. - -Description ------------ - -Performs a deep copy of ``read_concern``. - -Returns -------- - -Returns a newly allocated copy of ``read_concern`` that should be freed with :symbol:`mongoc_read_concern_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_concern_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_read_concern_destroy.rst deleted file mode 100644 index e897ca0a748b52b8c4671734757ebb88b46d61da..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_concern_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_read_concern_destroy - -mongoc_read_concern_destroy() -============================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_read_concern_destroy (mongoc_read_concern_t *read_concern); - -Parameters ----------- - -* ``read_concern``: A :symbol:`mongoc_read_concern_t`. - -Description ------------ - -Frees all resources associated with the read concern structure. Does nothing if ``read_concern`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_concern_get_level.rst b/lib/mongoc/libmongoc/doc/mongoc_read_concern_get_level.rst deleted file mode 100644 index a1f87964d8be87cde2a71cf8d8edeb0d7a964c9c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_concern_get_level.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_read_concern_get_level - -mongoc_read_concern_get_level() -=============================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_read_concern_get_level (const mongoc_read_concern_t *read_concern); - -Parameters ----------- - -* ``read_concern``: A :symbol:`mongoc_read_concern_t`. - -Description ------------ - -Returns the currently set read concern. - -Returns -------- - -Returns the current readConcern. If none is set, returns NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_concern_is_default.rst b/lib/mongoc/libmongoc/doc/mongoc_read_concern_is_default.rst deleted file mode 100644 index 355f21fc79a5061eb9b3b74c2234ad7099e34896..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_concern_is_default.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_read_concern_is_default - -mongoc_read_concern_is_default() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_read_concern_is_default (mongoc_read_concern_t *read_concern); - -Parameters ----------- - -* ``read_concern``: A pointer to a :symbol:`mongoc_read_concern_t`. - -Description ------------ - -Returns true if ``read_concern`` has not been modified from the default. For example, if no "readConcern" option is set in the MongoDB URI and you have not called :symbol:`mongoc_client_set_read_concern()`, then :symbol:`mongoc_read_concern_is_default()` is true for the read concern returned by :symbol:`mongoc_client_get_read_concern()`. diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_concern_new.rst b/lib/mongoc/libmongoc/doc/mongoc_read_concern_new.rst deleted file mode 100644 index debc4d4b016be7950c8e563d997c98377ff1417a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_concern_new.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_read_concern_new - -mongoc_read_concern_new() -========================= - -Synopsis --------- - -.. code-block:: c - - mongoc_read_concern_t * - mongoc_read_concern_new (void); - -Returns -------- - -Creates a newly allocated read concern that can be configured based on user preference. This should be freed with :symbol:`mongoc_read_concern_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_concern_set_level.rst b/lib/mongoc/libmongoc/doc/mongoc_read_concern_set_level.rst deleted file mode 100644 index febbbcba8554e9a8a6578dd17e41e10000dff988..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_concern_set_level.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_read_concern_set_level - -mongoc_read_concern_set_level() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_read_concern_set_level (mongoc_read_concern_t *read_concern, - const char *level); - -Parameters ----------- - -* ``read_concern``: A :symbol:`mongoc_read_concern_t`. -* ``level``: The readConcern level to use. - -Description ------------ - -Sets the read concern level. See :symbol:`mongoc_read_concern_t` for details. - -Beginning in version 1.9.0, this function can now alter the read concern after -it has been used in an operation. Previously, using the struct with an operation -would mark it as "frozen" and calling this function would return ``false`` -instead of altering the read concern. - -Returns -------- - -Returns ``true`` if the read concern level was set, or ``false`` otherwise. diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_concern_t.rst b/lib/mongoc/libmongoc/doc/mongoc_read_concern_t.rst deleted file mode 100644 index 238e6cdaff869799d5e90e2d505097e45ff56255..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_concern_t.rst +++ /dev/null @@ -1,56 +0,0 @@ -:man_page: mongoc_read_concern_t - -mongoc_read_concern_t -===================== - -Read Concern abstraction - -Synopsis --------- - -New in MongoDB 3.2. - -The ``mongoc_read_concern_t`` allows clients to choose a level of isolation for their reads. The default, MONGOC_READ_CONCERN_LEVEL_LOCAL, is right for the great majority of applications. - -You can specify a read concern on connection objects, database objects, or collection objects. - -See `readConcern <https://docs.mongodb.org/master/reference/readConcern/>`_ on the MongoDB website for more information. - -Read Concern is only sent to MongoDB when it has explicitly been set by :symbol:`mongoc_read_concern_set_level` to anything other than NULL. - -.. _mongoc_read_concern_levels: - -Read Concern Levels -------------------- - -====================================== =========================== ===================== -Macro Description First MongoDB version -====================================== =========================== ===================== -MONGOC_READ_CONCERN_LEVEL_LOCAL Level "local", the default. 3.2 -MONGOC_READ_CONCERN_LEVEL_MAJORITY Level "majority". 3.2 -MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE Level "linearizable". 3.4 -MONGOC_READ_CONCERN_LEVEL_AVAILABLE Level "available". 3.6 -MONGOC_READ_CONCERN_LEVEL_SNAPSHOT Level "snapshot". 4.0 -====================================== =========================== ===================== - -For the sake of compatibility with future versions of MongoDB, :symbol:`mongoc_read_concern_set_level` allows any string, not just this list of known read concern levels. - -See `Read Concern Levels <https://docs.mongodb.com/master/reference/read-concern/#read-concern-levels>`_ in the MongoDB manual for more information about the individual read concern levels. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_read_concern_append - mongoc_read_concern_copy - mongoc_read_concern_destroy - mongoc_read_concern_get_level - mongoc_read_concern_is_default - mongoc_read_concern_new - mongoc_read_concern_set_level - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_mode_t.rst b/lib/mongoc/libmongoc/doc/mongoc_read_mode_t.rst deleted file mode 100644 index 66a53a03962c348b08b4fd233d99991b1fa1d4da..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_mode_t.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_read_mode_t - -mongoc_read_mode_t -================== - -Read Preference Modes - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_READ_PRIMARY = (1 << 0), - MONGOC_READ_SECONDARY = (1 << 1), - MONGOC_READ_PRIMARY_PREFERRED = (1 << 2) | MONGOC_READ_PRIMARY, - MONGOC_READ_SECONDARY_PREFERRED = (1 << 2) | MONGOC_READ_SECONDARY, - MONGOC_READ_NEAREST = (1 << 3) | MONGOC_READ_SECONDARY, - } mongoc_read_mode_t; - -Description ------------ - -This enum describes how reads should be dispatched. The default is MONGOC_READ_PRIMARY. - -Please see the MongoDB website for a description of `Read Preferences <http://docs.mongodb.org/manual/core/read-preference/>`_. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_add_tag.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_add_tag.rst deleted file mode 100644 index 26f1b9e59cf9cb33a0acf4818fa0237b395a7cdf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_add_tag.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_read_prefs_add_tag - -mongoc_read_prefs_add_tag() -=========================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. -* ``tag``: A :symbol:`bson:bson_t`. - -Description ------------ - -This function shall add a tag to a read preference. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_copy.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_copy.rst deleted file mode 100644 index a455e9dec3912673a7243b7b085d448f64a3dee1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_copy.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_read_prefs_copy - -mongoc_read_prefs_copy() -======================== - -Synopsis --------- - -.. code-block:: c - - mongoc_read_prefs_t * - mongoc_read_prefs_copy (const mongoc_read_prefs_t *read_prefs); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - -Description ------------ - -This function shall deep copy a read preference. - -Returns -------- - -Returns a newly allocated read preference that should be freed with :symbol:`mongoc_read_prefs_destroy()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_destroy.rst deleted file mode 100644 index d71f84947bfafea3150c5d98e7beb97624477f32..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_read_prefs_destroy - -mongoc_read_prefs_destroy() -=========================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_read_prefs_destroy (mongoc_read_prefs_t *read_prefs); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - -Description ------------ - -Frees a read preference and all associated resources. Does nothing if ``read_prefs`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_max_staleness_seconds.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_max_staleness_seconds.rst deleted file mode 100644 index 6de710e989860bec2687881cc139ef1e50071a67..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_max_staleness_seconds.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_read_prefs_get_max_staleness_seconds - -mongoc_read_prefs_get_max_staleness_seconds() -============================================= - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_read_prefs_get_max_staleness_seconds ( - const mongoc_read_prefs_t *read_prefs); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - -Description ------------ - -Clients estimate the staleness of each secondary, and select for reads only those secondaries whose estimated staleness is less than or equal to maxStalenessSeconds. The default is ``MONGOC_NO_MAX_STALENESS``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_mode.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_mode.rst deleted file mode 100644 index cf8520d5a74872c7be25e1fabb51e169a0cfe3a6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_mode.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_read_prefs_get_mode - -mongoc_read_prefs_get_mode() -============================ - -Synopsis --------- - -.. code-block:: c - - mongoc_read_mode_t - mongoc_read_prefs_get_mode (const mongoc_read_prefs_t *read_prefs); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - -Description ------------ - -Fetches the :symbol:`mongoc_read_mode_t` for the read preference. - -Returns -------- - -Returns the read preference mode. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_tags.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_tags.rst deleted file mode 100644 index bca7592104768ee8891c86885bda37f16ae1a38e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_get_tags.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_read_prefs_get_tags - -mongoc_read_prefs_get_tags() -============================ - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_read_prefs_get_tags (const mongoc_read_prefs_t *read_prefs); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - -Description ------------ - -Fetches any read preference tags that have been registered. - -Returns -------- - -Returns a :symbol:`bson:bson_t` that should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_is_valid.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_is_valid.rst deleted file mode 100644 index fa7391843c391bd1ca2baf505c2e930ffd965836..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_is_valid.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_read_prefs_is_valid - -mongoc_read_prefs_is_valid() -============================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - -Description ------------ - -Performs a consistency check of ``read_prefs`` to ensure it makes sense and can be satisfied. - -This only performs local consistency checks. - -Returns -------- - -Returns true if the read pref is valid. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_new.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_new.rst deleted file mode 100644 index 51f05d22168a39d48674701ca5cc7a1bade0778c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_new.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_read_prefs_new - -mongoc_read_prefs_new() -======================= - -Synopsis --------- - -.. code-block:: c - - mongoc_read_prefs_t * - mongoc_read_prefs_new (mongoc_read_mode_t read_mode); - -Parameters ----------- - -* ``read_mode``: A :symbol:`mongoc_read_mode_t`. - -Description ------------ - -Creates a new :symbol:`mongoc_read_prefs_t` using the mode specified. - -Returns -------- - -Returns a newly allocated :symbol:`mongoc_read_prefs_t` that should be freed with :symbol:`mongoc_read_prefs_destroy()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_max_staleness_seconds.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_max_staleness_seconds.rst deleted file mode 100644 index 42b469a3836b5427742baa1e8cadc5aa54c35013..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_max_staleness_seconds.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_read_prefs_set_max_staleness_seconds - -mongoc_read_prefs_set_max_staleness_seconds() -============================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs, - int64_t max_staleness_seconds); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. -* ``max_staleness_seconds``: A positive integer or ``MONGOC_NO_MAX_STALENESS``. - -Description ------------ - -Sets the maxStalenessSeconds to be used for the read preference. Clients estimate the staleness of each secondary, and select for reads only those secondaries whose estimated staleness is less than or equal to maxStalenessSeconds. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_mode.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_mode.rst deleted file mode 100644 index 52e89bd7aa05b3d3be1f5dec8ea536422179c312..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_mode.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_read_prefs_set_mode - -mongoc_read_prefs_set_mode() -============================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_read_prefs_set_mode (mongoc_read_prefs_t *read_prefs, - mongoc_read_mode_t mode); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. -* ``mode``: A :symbol:`mongoc_read_mode_t`. - -Description ------------ - -Sets the read preference mode. See the MongoDB website for more information on `Read Preferences <http://docs.mongodb.org/manual/core/read-preference/>`_. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_tags.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_tags.rst deleted file mode 100644 index de29996762cee2ab8a7fde4e2adc20287bdf9b30..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_set_tags.rst +++ /dev/null @@ -1,94 +0,0 @@ -:man_page: mongoc_read_prefs_set_tags - -mongoc_read_prefs_set_tags() -============================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_read_prefs_set_tags (mongoc_read_prefs_t *read_prefs, - const bson_t *tags); - -Parameters ----------- - -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. -* ``tags``: A :symbol:`bson:bson_t`. - -Description ------------ - -Sets the tags to be used for the read preference. Only mongod instances matching these tags will be suitable for handling the request. - -Examples --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - static void - run_query_with_read_prefs_tags (mongoc_collection_t *collection) - { - char *str; - const bson_t *doc; - bson_t filter = BSON_INITIALIZER; - bson_error_t error; - mongoc_cursor_t *cursor; - mongoc_read_prefs_t *read_prefs; - /* Create a tagset representing - * [ - * {"dc": "ny", "rack": "1" }, // Any node in rack1 in the ny datacenter - * {"dc": "ny", "rack": "2" }, // Any node in rack2 in the ny datacenter - * {"dc": "ny" }, // Any node in the ny datacenter - * {} // If all else fails, just any available node - * ] - */ - bson_t *tags = BCON_NEW ( - "0", "{", "dc", BCON_UTF8("ny"), "rack", BCON_UTF8("1"), "}", - "1", "{", "dc", BCON_UTF8("ny"), "rack", BCON_UTF8("2"), "}", - "2", "{", "dc", BCON_UTF8("ny"), "}", - "3", "{", "}" - ); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_read_prefs_set_tags (read_prefs, tags); - bson_destroy (tags); - - cursor = - mongoc_collection_find_with_opts (collection, &filter, NULL, read_prefs); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - printf ("%s\n", str); - bson_free (str); - } - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "Cursor error: %s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - mongoc_read_prefs_destroy (read_prefs); - bson_destroy (doc); - } - - int main (void) - { - mongoc_client_t *client; - mongoc_collection_t *collection; - - mongoc_init (); - - client = - mongoc_client_new ("mongodb://localhost/?appname=rp_tags&replicaSet=foo"); - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "dbname", "collname"); - run_query_with_read_prefs_tags (collection); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_cleanup(); - } diff --git a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_t.rst b/lib/mongoc/libmongoc/doc/mongoc_read_prefs_t.rst deleted file mode 100644 index 3f4f9428bd98e772d68e25a5721d9571d75d708a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_read_prefs_t.rst +++ /dev/null @@ -1,91 +0,0 @@ -:man_page: mongoc_read_prefs_t - -mongoc_read_prefs_t -=================== - -A read preference abstraction - -Synopsis --------- - -:symbol:`mongoc_read_prefs_t` provides an abstraction on top of the MongoDB connection read preferences. It allows for hinting to the driver which nodes in a replica set should be accessed first. - -You can specify a read preference mode on connection objects, database objects, collection objects, or per-operation. Generally, it makes the most sense to stick with the global default, ``MONGOC_READ_PRIMARY``. All of the other modes come with caveats that won't be covered in great detail here. - -Read Modes ----------- - -=============================== ==================================================================================================================================================== -MONGOC_READ_PRIMARY Default mode. All operations read from the current replica set primary. -MONGOC_READ_SECONDARY All operations read from among the nearest secondary members of the replica set. -MONGOC_READ_PRIMARY_PREFERRED In most situations, operations read from the primary but if it is unavailable, operations read from secondary members. -MONGOC_READ_SECONDARY_PREFERRED In most situations, operations read from among the nearest secondary members, but if no secondaries are available, operations read from the primary. -MONGOC_READ_NEAREST Operations read from among the nearest members of the replica set, irrespective of the member's type. -=============================== ==================================================================================================================================================== - -.. _mongoc-read-prefs-tag-sets: - -Tag Sets --------- - -Tag sets allow you to specify custom read preferences and write concerns so that your application can target operations to specific members. - -Custom read preferences and write concerns evaluate tags sets in different ways: read preferences consider the value of a tag when selecting a member to read from. while write concerns ignore the value of a tag to when selecting a member except to consider whether or not the value is unique. - -You can specify tag sets with the following read preference modes: - -* primaryPreferred -* secondary -* secondaryPreferred -* nearest - -Tags are not compatible with ``MONGOC_READ_PRIMARY`` and, in general, only apply when selecting a secondary member of a set for a read operation. However, the nearest read mode, when combined with a tag set will select the nearest member that matches the specified tag set, which may be a primary or secondary. - -Tag sets are represented as a comma-separated list of colon-separated key-value -pairs when provided as a connection string, e.g. `dc:ny,rack:1`. - -To specify a list of tag sets, using multiple readPreferenceTags, e.g. - -.. code-block:: none - - readPreferenceTags=dc:ny,rack:1;readPreferenceTags=dc:ny;readPreferenceTags= - -Note the empty value for the last one, which means match any secondary as a -last resort. - -Order matters when using multiple readPreferenceTags. - -Tag Sets can also be configured using :symbol:`mongoc_read_prefs_set_tags`. - -All interfaces use the same member selection logic to choose the member to which to direct read operations, basing the choice on read preference mode and tag sets. - -Max Staleness -------------- - -When connected to replica set running MongoDB 3.4 or later, the driver estimates the staleness of each secondary based on lastWriteDate values provided in server isMaster responses. - -Max Staleness is the maximum replication lag in seconds (wall clock time) that a secondary can suffer and still be eligible for reads. The default is ``MONGOC_NO_MAX_STALENESS``, which disables staleness checks. Otherwise, it must be a positive integer at least ``MONGOC_SMALLEST_MAX_STALENESS_SECONDS`` (90 seconds). - -Max Staleness is also supported by sharded clusters of replica sets if all servers run MongoDB 3.4 or later. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_read_prefs_add_tag - mongoc_read_prefs_copy - mongoc_read_prefs_destroy - mongoc_read_prefs_get_max_staleness_seconds - mongoc_read_prefs_get_mode - mongoc_read_prefs_get_tags - mongoc_read_prefs_is_valid - mongoc_read_prefs_new - mongoc_read_prefs_set_max_staleness_seconds - mongoc_read_prefs_set_mode - mongoc_read_prefs_set_tags - diff --git a/lib/mongoc/libmongoc/doc/mongoc_remove_flags_t.rst b/lib/mongoc/libmongoc/doc/mongoc_remove_flags_t.rst deleted file mode 100644 index 34297576e6e107f4d53be5ddabd11a93f01c39f0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_remove_flags_t.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_remove_flags_t - -mongoc_remove_flags_t -===================== - -Flags for deletion operations - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_REMOVE_NONE = 0, - MONGOC_REMOVE_SINGLE_REMOVE = 1 << 0, - } mongoc_remove_flags_t; - -Description ------------ - -These flags correspond to the MongoDB wire protocol. They may be bitwise or'd together. They may change the number of documents that are removed during a remove command. - -Flag Values ------------ - -=========================== ================================================================= -MONGOC_REMOVE_NONE Specify no removal flags. All matching documents will be removed. -MONGOC_REMOVE_SINGLE_REMOVE Only remove the first matching document from the selector. -=========================== ================================================================= - diff --git a/lib/mongoc/libmongoc/doc/mongoc_reply_flags_t.rst b/lib/mongoc/libmongoc/doc/mongoc_reply_flags_t.rst deleted file mode 100644 index 45aafcfd45201fd78248242326271d8ae7a688df..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_reply_flags_t.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_reply_flags_t - -mongoc_reply_flags_t -==================== - -Flags from server replies - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_REPLY_NONE = 0, - MONGOC_REPLY_CURSOR_NOT_FOUND = 1 << 0, - MONGOC_REPLY_QUERY_FAILURE = 1 << 1, - MONGOC_REPLY_SHARD_CONFIG_STALE = 1 << 2, - MONGOC_REPLY_AWAIT_CAPABLE = 1 << 3, - } mongoc_reply_flags_t; - -Description ------------ - -These flags correspond to the wire protocol. They may be bitwise or'd together. - -Flag Values ------------ - -=============================== ================================================================== -MONGOC_REPLY_NONE No flags set. -MONGOC_REPLY_CURSOR_NOT_FOUND No matching cursor was found on the server. -MONGOC_REPLY_QUERY_FAILURE The query failed or was invalid. Error document has been provided. -MONGOC_REPLY_SHARD_CONFIG_STALE Shard config is stale. -MONGOC_REPLY_AWAIT_CAPABLE If the returned cursor is capable of MONGOC_QUERY_AWAIT_DATA. -=============================== ================================================================== - diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_destroy.rst deleted file mode 100644 index d9e9f4bd62f5c2ec649b08f2aef76db1e33c168c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_server_description_destroy - -mongoc_server_description_destroy() -=================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_server_description_destroy (mongoc_server_description_t *description); - -Parameters ----------- - -* ``description``: A :symbol:`mongoc_server_description_t`. - -Description ------------ - -Clean up all memory associated with the server description. Does nothing if ``description`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_host.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_host.rst deleted file mode 100644 index d07693b3bb128830fe6b42e8c7ca5497d2ff3da7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_host.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_server_description_host - -mongoc_server_description_host() -================================ - -Synopsis --------- - -.. code-block:: c - - mongoc_host_list_t * - mongoc_server_description_host (const mongoc_server_description_t *description); - -Parameters ----------- - -* ``description``: A :symbol:`mongoc_server_description_t`. - -Description ------------ - -Return the server's host and port. This object is owned by the server description. - -Returns -------- - -A reference to the server description's :symbol:`mongoc_host_list_t`, which you must not modify or free. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_id.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_id.rst deleted file mode 100644 index a1be02bc8168cc4ab40b68cfd557d8cde588f55a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_id.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_server_description_id - -mongoc_server_description_id() -============================== - -Synopsis --------- - -.. code-block:: c - - uint32_t - mongoc_server_description_id (const mongoc_server_description_t *description); - -Parameters ----------- - -* ``description``: A :symbol:`mongoc_server_description_t`. - -Description ------------ - -Get the server's id, an opaque identifier generated by the client or client pool. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_ismaster.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_ismaster.rst deleted file mode 100644 index f33f64faf4d6d5ca3ee0820f206d4e1e88f65d37..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_ismaster.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_server_description_ismaster - -mongoc_server_description_ismaster() -==================================== - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_server_description_ismaster ( - const mongoc_server_description_t *description); - -Parameters ----------- - -* ``description``: A :symbol:`mongoc_server_description_t`. - -Description ------------ - -The client or client pool periodically runs an `"isMaster" <https://docs.mongodb.org/manual/reference/command/isMaster/>`_ command on each server, to update its view of the MongoDB deployment. Use :symbol:`mongoc_client_get_server_descriptions()` and ``mongoc_server_description_ismaster()`` to get the most recent "isMaster" response. - -Returns -------- - -A reference to a BSON document, owned by the server description. The document is empty if the driver is not connected to the server. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_last_update_time.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_last_update_time.rst deleted file mode 100644 index 935f557a57722875cbea0bdd7f5f13a9ba27c57d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_last_update_time.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_server_description_last_update_time - -mongoc_server_description_last_update_time() -============================================ - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_server_description_last_update_time (const mongoc_server_description_t *description); - -Parameters ----------- - -* ``description``: A :symbol:`mongoc_server_description_t`. - -Description ------------ - -Get the last point in time when we processed an ismaster for this server, or, if we have not processed any ismasters since creating the description, the time the server description was initialized. - -Returns -------- - -The server's last update time, in microseconds. diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_new_copy.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_new_copy.rst deleted file mode 100644 index 60b30c149f61da2b3887e6f0817fc0ff96b25237..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_new_copy.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_server_description_new_copy - -mongoc_server_description_new_copy() -==================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_server_description_t * - mongoc_server_description_new_copy ( - const mongoc_server_description_t *description); - -Parameters ----------- - -* ``description``: A :symbol:`mongoc_server_description_t`. - -Description ------------ - -This function copies the given server description and returns a new server description object. The caller is responsible for destroying the new copy. - -Returns -------- - -A copy of the original server description. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_round_trip_time.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_round_trip_time.rst deleted file mode 100644 index 5f7a7c21600244827cde12217dd08562e4537ad1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_round_trip_time.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_server_description_round_trip_time - -mongoc_server_description_round_trip_time() -=========================================== - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_server_description_round_trip_time ( - const mongoc_server_description_t *description); - -Parameters ----------- - -* ``description``: A :symbol:`mongoc_server_description_t`. - -Description ------------ - -Get the server's round trip time in milliseconds. This is the client's measurement of the duration of an "ismaster" command. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_t.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_t.rst deleted file mode 100644 index 23491461c2c3b13cacfe795812e12933bb984ecb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_t.rst +++ /dev/null @@ -1,43 +0,0 @@ -:man_page: mongoc_server_description_t - -mongoc_server_description_t -=========================== - -Server description - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - typedef struct _mongoc_server_description_t mongoc_server_description_t - -``mongoc_server_description_t`` holds information about a mongod or mongos the driver is connected to. - -See also :symbol:`mongoc_client_get_server_descriptions()`. - -Lifecycle ---------- - -Clean up with :symbol:`mongoc_server_description_destroy()`. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_server_description_destroy - mongoc_server_description_host - mongoc_server_description_id - mongoc_server_description_ismaster - mongoc_server_description_last_update_time - mongoc_server_description_new_copy - mongoc_server_description_round_trip_time - mongoc_server_description_type - mongoc_server_descriptions_destroy_all - diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_description_type.rst b/lib/mongoc/libmongoc/doc/mongoc_server_description_type.rst deleted file mode 100644 index 5e371ab3189e769274e6b568bac164de116a2cbd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_description_type.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_server_description_type - -mongoc_server_description_type() -================================ - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_server_description_type (const mongoc_server_description_t *description); - -Parameters ----------- - -* ``description``: A :symbol:`mongoc_server_description_t`. - -Description ------------ - -This function returns a string, one of the server types defined in the Server Discovery And Monitoring Spec: - -* Standalone -* Mongos -* PossiblePrimary -* RSPrimary -* RSSecondary -* RSArbiter -* RSOther -* RSGhost -* Unknown - diff --git a/lib/mongoc/libmongoc/doc/mongoc_server_descriptions_destroy_all.rst b/lib/mongoc/libmongoc/doc/mongoc_server_descriptions_destroy_all.rst deleted file mode 100644 index 0fe69a88034e1800674cae3dcedea2e0e091eb34..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_server_descriptions_destroy_all.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_server_descriptions_destroy_all - -mongoc_server_descriptions_destroy_all() -======================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_server_descriptions_destroy_all (mongoc_server_description_t **sds, - size_t n); - -Frees the array of :symbol:`mongoc_server_description_t` structs returned by :symbol:`mongoc_client_get_server_descriptions`. - -Parameters ----------- - -* ``sds``: The array of server descriptions. -* ``n``: The number of elements in ``sds``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opt_t.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opt_t.rst deleted file mode 100644 index 797e38034b33d594e626e331b3cf66f58dfcb1b4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opt_t.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_session_opt_t - -mongoc_session_opt_t -==================== - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct _mongoc_session_opt_t mongoc_session_opt_t; - -Synopsis --------- - -.. include:: includes/session-lifecycle.txt - -See the example code for :symbol:`mongoc_session_opts_set_causal_consistency`. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_session_opts_new - mongoc_session_opts_get_causal_consistency - mongoc_session_opts_set_causal_consistency - mongoc_session_opts_get_default_transaction_opts - mongoc_session_opts_set_default_transaction_opts - mongoc_session_opts_get_transaction_opts - mongoc_session_opts_clone - mongoc_session_opts_destroy diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opts_clone.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opts_clone.rst deleted file mode 100644 index 561b809720ec36b264a163e86b27458ad8bf01c9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opts_clone.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_session_opts_clone - -mongoc_session_opts_clone() -=========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_session_opt_t * - mongoc_session_opts_clone (const mongoc_session_opt_t *opts); - -Create a copy of a session options struct. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_session_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opts_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opts_destroy.rst deleted file mode 100644 index 8bfbde59348d41788d4bfc4fa9959fd14f960ec1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opts_destroy.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_session_opts_destroy - -mongoc_session_opts_destroy() -============================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_session_opts_destroy (mongoc_session_opt_t *opts); - -Free a :symbol:`mongoc_session_opt_t`. Does nothing if ``opts`` is NULL. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_session_opt_t`. - -Example -------- - -See the example code for :symbol:`mongoc_session_opts_set_causal_consistency`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_causal_consistency.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_causal_consistency.rst deleted file mode 100644 index bee91e97526a3807430757a6392f37b3c9a166ce..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_causal_consistency.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_session_opts_get_causal_consistency - -mongoc_session_opts_get_causal_consistency() -============================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_session_opts_get_causal_consistency (const mongoc_session_opt_t *opts); - -Return true if this session is configured for causal consistency (the default), else false. See :symbol:`mongoc_session_opts_set_causal_consistency()`. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_session_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_default_transaction_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_default_transaction_opts.rst deleted file mode 100644 index 3a87806031da0ea4782e049d9bad3f696792ffaf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_default_transaction_opts.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_session_opts_get_default_transaction_opts - -mongoc_session_opts_get_default_transaction_opts() -================================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_transaction_opt_t * - mongoc_session_opts_get_default_transaction_opts (const mongoc_session_opt_t *opts); - -The default options for transactions started with this session. The returned value is valid only for the lifetime of ``opts``. See :symbol:`mongoc_session_opts_set_default_transaction_opts()`. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_session_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_transaction_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_transaction_opts.rst deleted file mode 100644 index b181710a84994afd25266f4ad41e79467b5c4142..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opts_get_transaction_opts.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_session_opts_get_transaction_opts - -mongoc_session_opts_get_transaction_opts() -========================================== - -Synopsis --------- - -.. code-block:: c - - mongoc_transaction_opt_t * - mongoc_session_opts_get_transaction_opts (const mongoc_client_session_t *session); - -The options for the current transaction started with this session. The resulting :symbol:`mongoc_transaction_opt_t` should be freed with :symbol:`mongoc_transaction_opts_destroy`. If this ``session`` is not in a transaction, then the returned value is ``NULL``. See :symbol:`mongoc_client_session_in_transaction()`. - -Parameters ----------- - -* ``session``: A :symbol:`mongoc_client_session_t`. - -Returns -------- - -A newly allocated :symbol:`mongoc_transaction_opt_t` that should be freed with :symbol:`mongoc_transaction_opts_destroy` or ``NULL`` if the session is not in a transaction. - -.. only:: html - - .. taglist:: See Also: - :tags: session - diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opts_new.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opts_new.rst deleted file mode 100644 index dc32b5c3f593e8dc1ccade429071c3691ab72373..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opts_new.rst +++ /dev/null @@ -1,21 +0,0 @@ -:man_page: mongoc_session_opts_new - -mongoc_session_opts_new() -========================= - -Synopsis --------- - -.. code-block:: c - - mongoc_session_opt_t * - mongoc_session_opts_new (void); - -.. include:: includes/session-lifecycle.txt - -See the example code for :symbol:`mongoc_session_opts_set_causal_consistency`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opts_set_causal_consistency.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opts_set_causal_consistency.rst deleted file mode 100644 index 1024357bace4793504c314e0b5caaa8c3d5060dc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opts_set_causal_consistency.rst +++ /dev/null @@ -1,71 +0,0 @@ -:man_page: mongoc_session_opts_set_causal_consistency - -mongoc_session_opts_set_causal_consistency() -============================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_session_opts_set_causal_consistency (mongoc_session_opt_t *opts, - bool causal_consistency); - -Configure causal consistency in a session. If true (the default), each operation in the session will be causally ordered after the previous read or write operation. Set to false to disable causal consistency. See `the MongoDB Manual Entry for Causal Consistency <http://dochub.mongodb.org/core/causal-consistency>`_. - -Unacknowledged writes are not causally consistent. If you execute a write operation with a :symbol:`mongoc_write_concern_t` on which you have called :symbol:`mongoc_write_concern_set_w` with a value of 0, the write does not participate in causal consistency. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_session_opt_t`. -* ``causal_consistency``: True or false. - -Example -------- - -.. code-block:: c - - mongoc_client_t *client; - mongoc_session_opt_t *session_opts; - mongoc_client_session_t *client_session; - mongoc_collection_t *collection; - bson_t insert_opts = BSON_INITIALIZER; - bson_t *doc; - bson_error_t error; - bool r; - - client = mongoc_client_new ("mongodb://example/?appname=session-opts-example"); - mongoc_client_set_error_api (client, 2); - - session_opts = mongoc_session_opts_new (); - mongoc_session_opts_set_causal_consistency (session_opts, false); - client_session = mongoc_client_start_session (client, session_opts, &error); - mongoc_session_opts_destroy (session_opts); - - if (!client_session) { - fprintf (stderr, "Failed to start session: %s\n", error.message); - abort (); - } - - collection = mongoc_client_get_collection (client, "test", "collection"); - doc = BCON_NEW ("_id", BCON_INT32 (1)); - r = mongoc_client_session_append (client_session, &insert_opts, NULL); - if (!r) { - fprintf (stderr, "mongoc_client_session_append failed: %s\n", error.message); - abort (); - } - - r = mongoc_collection_insert_one ( - collection, doc, &insert_opts, NULL /* reply */, &error); - - if (!r) { - fprintf (stderr, "Insert failed: %s\n", error.message); - abort (); - } - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_session_opts_set_default_transaction_opts.rst b/lib/mongoc/libmongoc/doc/mongoc_session_opts_set_default_transaction_opts.rst deleted file mode 100644 index 58abc44befc5d032bab689685a0b2082653fe195..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_session_opts_set_default_transaction_opts.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_session_opts_set_default_transaction_opts - -mongoc_session_opts_set_default_transaction_opts() -================================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_session_opts_set_default_transaction_opts ( - mongoc_session_opt_t *opts, const mongoc_transaction_opt_t *txn_opts); - -Set the default options for transactions started with this session. The ``txn_opts`` argument is copied and can be freed after calling this function. - -When a session is first created with :symbol:`mongoc_client_start_session`, it inherits from the client the read concern, write concern, and read preference with which to start transactions. Each of these fields can be overridden independently. Create a :symbol:`mongoc_transaction_opt_t` with :symbol:`mongoc_transaction_opts_new`, and pass a non-NULL option to any of the :symbol:`mongoc_transaction_opt_t` setter functions: - -* :symbol:`mongoc_transaction_opts_set_read_concern` -* :symbol:`mongoc_transaction_opts_set_write_concern` -* :symbol:`mongoc_transaction_opts_set_read_prefs` - -Pass the resulting transaction options to :symbol:`mongoc_session_opts_set_default_transaction_opts`. Each field set in the transaction options overrides the inherited client configuration. There is an opportunity to override each one of these fields again by passing a :symbol:`mongoc_transaction_opt_t` to :symbol:`mongoc_client_session_start_transaction`. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_session_opt_t`. -* ``txn_opts``: A :symbol:`mongoc_transaction_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_accept.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_accept.rst deleted file mode 100644 index a122a5f69e8e8349e27482d80c01a4d1b21b88b6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_accept.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_socket_accept - -mongoc_socket_accept() -====================== - -Synopsis --------- - -.. code-block:: c - - mongoc_socket_t * - mongoc_socket_accept (mongoc_socket_t *sock, int64_t expire_at); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``expire_at``: An int64_t containing a timeout in milliseconds. - -Description ------------ - -This function is a wrapper around the BSD socket ``accept()`` interface. It allows for more portability between UNIX-like and Microsoft Windows platforms. - -Returns -------- - -NULL upon failure to accept or timeout. A newly allocated ``mongoc_socket_t`` that should be released with :symbol:`mongoc_socket_destroy()` on success. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_bind.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_bind.rst deleted file mode 100644 index 44883807257609e953957167aceeabab935ca725..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_bind.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_socket_bind - -mongoc_socket_bind() -==================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_socket_bind (mongoc_socket_t *sock, - const struct sockaddr *addr, - mongoc_socklen_t addrlen); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``addr``: A struct sockaddr. -* ``addrlen``: A mongoc_socklen_t. - -Description ------------ - -This function is a wrapper around the BSD socket ``bind()`` interface. It provides better portability between UNIX-like and Microsoft Windows platforms. - -Returns -------- - -0 on success, -1 on failure and errno is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_close.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_close.rst deleted file mode 100644 index 42683be2b97a156863e964adf64ab4956adac27c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_close.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_socket_close - -mongoc_socket_close() -===================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_socket_close (mongoc_socket_t *socket); - -Parameters ----------- - -* ``socket``: A :symbol:`mongoc_socket_t`. - -Description ------------ - -This function is a wrapper around the BSD socket ``shutdown()`` and ``close()`` functions, and their Windows equivalents. The socket is shut down only if the current process is the same as the process that opened the socket. Regardless, the socket is then closed. - -Returns -------- - -0 on success, -1 on failure to close the socket. On failure, the socket's errno is set; retrieve it with :symbol:`mongoc_socket_errno()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_connect.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_connect.rst deleted file mode 100644 index 025cbc08541679c6d0825fec8928da27c624ec62..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_connect.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_socket_connect - -mongoc_socket_connect() -======================= - -Synopsis --------- - -.. code-block:: c - - int - mongoc_socket_connect (mongoc_socket_t *sock, - const struct sockaddr *addr, - mongoc_socklen_t addrlen, - int64_t expire_at); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``addr``: A struct sockaddr. -* ``addrlen``: A mongoc_socklen_t. -* ``expire_at``: A int64_t containing the absolute timeout using the monotonic clock. - -Description ------------ - -This function is a wrapper around the BSD socket ``connect()`` interface. It provides better portability between UNIX-like and Microsoft Windows platforms. - -This function performs a socket connection but will fail if ``expire_at`` has been reached by the monotonic clock. Keep in mind that this is an absolute timeout in milliseconds. You should add your desired timeout to :symbol:`bson:bson_get_monotonic_time()`. - -Returns -------- - -0 if successful, -1 on failure and errno is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_destroy.rst deleted file mode 100644 index 9a8a3c5fd57244b863ff38a81a03a0e2ca77c225..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_socket_destroy - -mongoc_socket_destroy() -======================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_socket_destroy (mongoc_socket_t *sock); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. - -Description ------------ - -This function releases all resources associated with a :symbol:`mongoc_socket_t`. This should be called when you are no longer using the socket. Does nothing if ``sock`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_errno.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_errno.rst deleted file mode 100644 index 25b8fb155f69c7c8941214fd970dee6a416cb74b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_errno.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_socket_errno - -mongoc_socket_errno() -===================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_socket_errno (mongoc_socket_t *sock); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. - -Description ------------ - -This function returns the currently captured ``errno`` for a socket. This may be useful to check was the last errno was after another function call has been made that clears the threads errno variable. - -Returns -------- - -0 if there is no error, otherwise a specific errno. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_getnameinfo.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_getnameinfo.rst deleted file mode 100644 index 1cd3ef1740a7f5b98e9974c703d17b5793202f44..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_getnameinfo.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_socket_getnameinfo - -mongoc_socket_getnameinfo() -=========================== - -Synopsis --------- - -.. code-block:: c - - char * - mongoc_socket_getnameinfo (mongoc_socket_t *sock); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. - -Description ------------ - -This is a helper around getting the local name of a socket. It is a wrapper around ``getpeername()`` and ``getnameinfo()``. - -Returns -------- - -A newly allocated string that should be freed with :symbol:`bson:bson_free()`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_getsockname.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_getsockname.rst deleted file mode 100644 index 8276eda8958692fe34aa528f92c86b4763163004..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_getsockname.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_socket_getsockname - -mongoc_socket_getsockname() -=========================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_socket_getsockname (mongoc_socket_t *sock, - struct sockaddr *addr, - mongoc_socklen_t *addrlen); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``addr``: A struct sockaddr. -* ``addrlen``: A mongoc_socklen_t. - -Description ------------ - -Retrieves the socket name for ``sock``. The result is stored in ``addr``. ``addrlen`` should be the size of the ``addr`` when calling this. - -Returns -------- - -0 if successful, otherwise -1 and errno is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_listen.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_listen.rst deleted file mode 100644 index a3ff17ddbf96f6bab2bd35fb050d59615af026cc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_listen.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_socket_listen - -mongoc_socket_listen() -====================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_socket_listen (mongoc_socket_t *sock, unsigned int backlog); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``backlog``: An int containing max backlog size. - -Description ------------ - -This function is similar to the BSD sockets ``listen()`` function. It is meant for socket servers. - -Returns -------- - -0 on success, -1 on failure and errno is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_new.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_new.rst deleted file mode 100644 index 1acba4771888501dd4406f09e19c8d124aeeb2f0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_new.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_socket_new - -mongoc_socket_new() -=================== - -Synopsis --------- - -.. code-block:: c - - mongoc_socket_t * - mongoc_socket_new (int domain, int type, int protocol); - -Parameters ----------- - -* ``domain``: An int containing the address family such as AF_INET. -* ``type``: An int containing the socket type such as SOCK_STREAM. -* ``protocol``: A protocol subset, typically 0. - -Description ------------ - -Creates a new ``mongoc_socket_t`` structure. This calls ``socket()`` underneath to create a network socket. - -Returns -------- - -A new socket if successful, otherwise ``NULL`` and errno is set. The result should be freed with :symbol:`mongoc_socket_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_recv.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_recv.rst deleted file mode 100644 index c9568b7d6336e8802655b4fdce81ddcfc939aae6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_recv.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_socket_recv - -mongoc_socket_recv() -==================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_socket_recv (mongoc_socket_t *sock, - void *buf, - size_t buflen, - int flags, - int64_t expire_at); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``buf``: A buffer to read into. -* ``buflen``: A size_t with the number of bytes to receive. -* ``flags``: flags for ``recv()``. -* ``expire_at``: A int64_t with the time to expire in monotonic time using :symbol:`bson:bson_get_monotonic_time()`, which is in microseconds. - -Description ------------ - -This function performs a ``recv()`` on the underlying socket. - -Returns -------- - -The number of bytes received on success, 0 on stream closed, and -1 if there was a failure and errno is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_send.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_send.rst deleted file mode 100644 index edd15ac09657da97006c1ba2e93ba62a1614fc2f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_send.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_socket_send - -mongoc_socket_send() -==================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_socket_send (mongoc_socket_t *sock, - const void *buf, - size_t buflen, - int64_t expire_at); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``buf``: A buffer to send. -* ``buflen``: A size_t with the number of bytes in buf. -* ``expire_at``: A int64_t with an absolute timeout for the operation or 0. The timeout is in monotonic time using microseconds. You can retrieve the current monotonic time with :symbol:`bson:bson_get_monotonic_time()`. - -Description ------------ - -Sends buflen bytes in buf to the destination. If a timeout expired, the number of bytes sent will be returned or -1 if no bytes were sent. - -Returns -------- - --1 on failure and errno is set, or the number of bytes sent. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_sendv.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_sendv.rst deleted file mode 100644 index fb916da69e1631423fd316634423189ef1a9b294..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_sendv.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_socket_sendv - -mongoc_socket_sendv() -===================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_socket_sendv (mongoc_socket_t *sock, - mongoc_iovec_t *iov, - size_t iovcnt, - int64_t expire_at); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``iov``: A mongoc_iovec_t. -* ``iovcnt``: A size_t containing the number of elements in iov. -* ``expire_at``: A int64_t with absolute timeout in monotonic time. The monotonic clock is in microseconds and can be fetched using :symbol:`bson:bson_get_monotonic_time()`. - -Description ------------ - -Sends a vector of buffers to the destination. This uses ``sendmsg()`` when available to perform a gathered write. If IOV_MAX is reached, a fallback will be used. - -Returns -------- - -the number of bytes sent on success, or -1 on failure and errno is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_setsockopt.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_setsockopt.rst deleted file mode 100644 index cfdc7a37fd7b38008f18d424d81fec146d9f479b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_setsockopt.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_socket_setsockopt - -mongoc_socket_setsockopt() -========================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_socket_setsockopt (mongoc_socket_t *sock, - int level, - int optname, - const void *optval, - mongoc_socklen_t optlen); - -Parameters ----------- - -* ``sock``: A :symbol:`mongoc_socket_t`. -* ``level``: A sockopt level. -* ``optname``: A sockopt name. -* ``optval``: A the value for the sockopt. -* ``optlen``: A mongoc_socklen_t that contains the length of optval. - -Description ------------ - -This is a helper function for ``setsockopt()``. - -Returns -------- - -0 on success, -1 on failure and errno is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_socket_t.rst b/lib/mongoc/libmongoc/doc/mongoc_socket_t.rst deleted file mode 100644 index 26bde64f4a6b8b49395e9d7c28856918f025155b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_socket_t.rst +++ /dev/null @@ -1,45 +0,0 @@ -:man_page: mongoc_socket_t - -mongoc_socket_t -=============== - -Portable socket abstraction - -Synopsis --------- - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct _mongoc_socket_t mongoc_socket_t - -Synopsis --------- - -This structure provides a socket abstraction that is friendlier for portability than BSD sockets directly. Inconsistencies between Linux, various BSDs, Solaris, and Windows are handled here. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_socket_accept - mongoc_socket_bind - mongoc_socket_close - mongoc_socket_connect - mongoc_socket_destroy - mongoc_socket_errno - mongoc_socket_getnameinfo - mongoc_socket_getsockname - mongoc_socket_listen - mongoc_socket_new - mongoc_socket_recv - mongoc_socket_send - mongoc_socket_sendv - mongoc_socket_setsockopt - diff --git a/lib/mongoc/libmongoc/doc/mongoc_ssl_opt_get_default.rst b/lib/mongoc/libmongoc/doc/mongoc_ssl_opt_get_default.rst deleted file mode 100644 index 0696562008968403880c7ee2f3aafdd856d0fe90..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_ssl_opt_get_default.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_ssl_opt_get_default - -mongoc_ssl_opt_get_default() -============================ - -Synopsis --------- - -.. code-block:: c - - const mongoc_ssl_opt_t * - mongoc_ssl_opt_get_default (void) BSON_GNUC_PURE; - -Returns -------- - -Returns the default SSL options for the process. This should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_ssl_opt_t.rst b/lib/mongoc/libmongoc/doc/mongoc_ssl_opt_t.rst deleted file mode 100644 index 6712e5364ed9e8595b47dcd5c21d5b41fbc2a15e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_ssl_opt_t.rst +++ /dev/null @@ -1,130 +0,0 @@ -:man_page: mongoc_ssl_opt_t - -mongoc_ssl_opt_t -================ - -Synopsis --------- - -.. code-block:: c - - typedef struct { - const char *pem_file; - const char *pem_pwd; - const char *ca_file; - const char *ca_dir; - const char *crl_file; - bool weak_cert_validation; - bool allow_invalid_hostname; - void *padding[7]; - } mongoc_ssl_opt_t; - -Description ------------ - -This structure is used to set the SSL options for a :symbol:`mongoc_client_t` or :symbol:`mongoc_client_pool_t`. - -Beginning in version 1.2.0, once a pool or client has any SSL options set, all connections use SSL, even if ``ssl=true`` is omitted from the MongoDB URI. Before, SSL options were ignored unless ``ssl=true`` was included in the URI. - -As of 1.4.0, the :symbol:`mongoc_client_pool_set_ssl_opts` and :symbol:`mongoc_client_set_ssl_opts` will not only shallow copy the struct, but will also copy the ``const char*``. It is therefore no longer needed to make sure the values remain valid after setting them. - -Configuration through URI Options ---------------------------------- - -Most of the configurable options can be using the Connection URI. - -=============================== =============================== -**mongoc_ssl_opt_t key** **URI key** -=============================== =============================== -pem_file sslClientCertificateKeyFile -pem_pwd sslClientCertificateKeyPassword -ca_file sslCertificateAuthorityFile -weak_cert_validation sslAllowInvalidCertificates -allow_invalid_hostname sslAllowInvalidHostnames -=============================== =============================== - -Client Authentication ---------------------- - -When MongoDB is started with SSL enabled, it will by default require the client to provide a client certificate issued by a certificate authority specified by ``--sslCAFile``, or an authority trusted by the native certificate store in use on the server. - -To provide the client certificate, the user must configure the ``pem_file`` to point at a PEM armored certificate. - -.. code-block:: c - - mongoc_ssl_opt_t ssl_opts = {0}; - - ssl_opts.pem_file = "/path/to/client-certificate.pem" - - /* Then set the client ssl_opts, when using a single client mongoc_client_t */ - mongoc_client_set_ssl_opts (client, &ssl_opts); - - /* or, set the pool ssl_opts, when using a the thread safe mongoc_client_pool_t */ - mongoc_client_pool_set_ssl_opts (pool, &ssl_opts); - -Server Certificate Verification -------------------------------- - -The MongoDB C Driver will automatically verify the validity of the server certificate, such as issued by configured Certificate Authority, hostname validation, and expiration. - -To overwrite this behaviour, it is possible to disable hostname validation, and/or allow otherwise invalid certificates. This behaviour is controlled using the ``allow_invalid_hostname`` and ``weak_cert_validation`` fields. By default, both are set to ``false``. It is not recommended to change these defaults as it exposes the client to *Man In The Middle* attacks (when ``allow_invalid_hostname`` is set) and otherwise invalid certificates when ``weak_cert_validation`` is set to ``true``. - -OpenSSL -------- - -The MongoDB C Driver uses OpenSSL, if available, on Linux and Unix platforms (besides macOS). Industry best practices and some regulations require the use of TLS 1.1 or newer, which requires at least OpenSSL 1.0.1. Check your OpenSSL version like so:: - - $ openssl version - -Ensure your system's OpenSSL is a recent version (at least 1.0.1), or install a recent version in a non-system path and build against it with:: - - cmake -DOPENSSL_ROOT_DIR=/absolute/path/to/openssl - -When compiled against OpenSSL, the driver will attempt to load the system default certificate store, as configured by the distribution, if the ``ca_file`` and ``ca_dir`` are not set. - -LibreSSL / libtls ------------------ - -The MongoDB C Driver supports LibreSSL through the use of OpenSSL compatibility checks when configured to compile against ``openssl``. It also supports the new ``libtls`` library when configured to build against ``libressl``. - -Native TLS Support on Windows (Secure Channel) ----------------------------------------------- - -The MongoDB C Driver supports the Windows native TLS library (Secure Channel, or SChannel), and its native crypto library (Cryptography API: Next Generation, or CNG). - -When compiled against the Windows native libraries, the ``ca_dir`` option is not supported, and will issue an error if used. - -Encrypted PEM files (e.g., requiring ``pem_pwd``) are also not supported, and will result in error when attempting to load them. - -When ``ca_file`` is provided, the driver will only allow server certificates issued by the authority (or authorities) provided. When no ``ca_file`` is provided, the driver will look up the Certificate Authority using the ``System Local Machine Root`` certificate store to confirm the provided certificate. - -When ``crl_file`` is provided, the driver will import the revocation list to the ``System Local Machine Root`` certificate store. - -.. _Secure Transport: - -Native TLS Support on macOS / Darwin (Secure Transport) -------------------------------------------------------- - -The MongoDB C Driver supports the Darwin (OS X, macOS, iOS, etc.) native TLS library (Secure Transport), and its native crypto library (Common Crypto, or CC). - -When compiled against Secure Transport, the ``ca_dir`` option is not supported, and will issue an error if used. - -When ``ca_file`` is provided, the driver will only allow server certificates issued by the authority (or authorities) provided. When no ``ca_file`` is provided, the driver will use the Certificate Authorities in the currently unlocked keychains. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_ssl_opt_get_default - -See Also --------- - -* :doc:`mongoc_client_set_ssl_opts` -* :doc:`mongoc_client_pool_set_ssl_opts` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_buffered_new.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_buffered_new.rst deleted file mode 100644 index cfab7e236a8699fa826b21f1353b9779a7ba71f5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_buffered_new.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_stream_buffered_new - -mongoc_stream_buffered_new() -============================ - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_stream_buffered_new (mongoc_stream_t *base_stream, size_t buffer_size); - -Parameters ----------- - -* ``base_stream``: A :symbol:`mongoc_stream_t` to buffer. -* ``buffer_size``: A size_t containing the desired buffer size. - -This function shall create a new :symbol:`mongoc_stream_t` that buffers bytes to and from the underlying ``base_stream``. - -``buffer_size`` will be used as the initial buffer size. It may grow past this size. - -Returns -------- - -A newly allocated :symbol:`mongoc_stream_buffered_t` on success, otherwise ``NULL``. This should be freed with :symbol:`mongoc_stream_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_buffered_t.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_buffered_t.rst deleted file mode 100644 index 139ed88772b681b0d50ad276f8dd1eaf9db6a9b6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_buffered_t.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_stream_buffered_t - -mongoc_stream_buffered_t -======================== - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_stream_buffered_t mongoc_stream_buffered_t; - -Description ------------ - -``mongoc_stream_buffered_t`` should be considered a subclass of :symbol:`mongoc_stream_t`. It performs buffering on an underlying stream. - -See Also --------- - -:doc:`mongoc_stream_buffered_new() <mongoc_stream_buffered_new>` - -:doc:`mongoc_stream_destroy() <mongoc_stream_destroy>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_close.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_close.rst deleted file mode 100644 index 4d8780eef67634a2aa3731f76dcf54df7b26b50d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_close.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_stream_close - -mongoc_stream_close() -===================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_stream_close (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. - -This function shall close underlying file-descriptors of ``stream``. - -Returns -------- - -``0`` on success, otherwise ``-1`` and ``errno`` is set. - -See Also --------- - -:doc:`mongoc_stream_destroy() <mongoc_stream_destroy>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_cork.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_cork.rst deleted file mode 100644 index d4b27bcafb9dfb7e2b551dc16d281438ddc9fd1b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_cork.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_stream_cork - -mongoc_stream_cork() -==================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_stream_cork (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. - -This function shall prevent the writing of bytes to the underlying socket. - -.. note:: - - Not all streams implement this function. Buffering generally works better. - -Returns -------- - -``0`` on success, ``-1`` on failure and ``errno`` is set. - -See Also --------- - -:doc:`mongoc_stream_buffered_new() <mongoc_stream_buffered_new>`. - -:doc:`mongoc_stream_uncork() <mongoc_stream_uncork>`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_destroy.rst deleted file mode 100644 index 684c9c1702dbd8d2f51a8fce47759511f5dae99e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_destroy.rst +++ /dev/null @@ -1,19 +0,0 @@ -:man_page: mongoc_stream_destroy - -mongoc_stream_destroy() -======================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_stream_destroy (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. - -This function shall release all resources associated with a :symbol:`mongoc_stream_t`, including freeing the structure. It is invalid to use ``stream`` after calling this function. Does nothing if ``stream`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_file_get_fd.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_file_get_fd.rst deleted file mode 100644 index bc31269672a565b437af7162a45d5325b83fa0b7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_file_get_fd.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_stream_file_get_fd - -mongoc_stream_file_get_fd() -=========================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_stream_file_get_fd (mongoc_stream_file_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_file_t`. - -This function shall return the underlying file-descriptor of a :symbol:`mongoc_stream_file_t`. - -.. warning:: - - Performing operations on the underlying file-descriptor may not be safe if used in conjunction with buffering. Avoid reading or writing from this file-descriptor. - -Returns -------- - -A file-descriptor that should not be modified by the caller. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_file_new.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_file_new.rst deleted file mode 100644 index d4c2c376ba69d47c705f59f93e45ca64bbc60189..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_file_new.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_stream_file_new - -mongoc_stream_file_new() -======================== - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_stream_file_new (int fd); - -Parameters ----------- - -* ``fd``: A UNIX style file-descriptor. - -Creates a new :symbol:`mongoc_stream_file_t` using the file-descriptor provided. - -Returns -------- - -``NULL`` upon failure, otherwise a newly allocated :symbol:`mongoc_stream_file_t` that should be freed with :symbol:`mongoc_stream_destroy()` when no longer in use. - -``errno`` is set upon failure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_file_new_for_path.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_file_new_for_path.rst deleted file mode 100644 index 59c78d2e67a440f2a91f4c9b61ebe024fd012b09..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_file_new_for_path.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_stream_file_new_for_path - -mongoc_stream_file_new_for_path() -================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_stream_file_new_for_path (const char *path, int flags, int mode); - -Parameters ----------- - -* ``path``: The path of the target file. -* ``flags``: Flags to be passed to ``open()``. -* ``mode``: An optional mode to be passed to ``open()`` when creating a file. - -This function shall create a new :symbol:`mongoc_stream_file_t` after opening the underlying file with ``open()`` or the platform equivalent. - -Returns -------- - -``NULL`` on failure, otherwise a newly allocated :symbol:`mongoc_stream_file_t` that should be freed with :symbol:`mongoc_stream_destroy()` when no longer in use. - -``errno`` is set upon failure. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_file_t.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_file_t.rst deleted file mode 100644 index 78cd8df24a83ff4d0b0cc414b15c6c9900da59ef..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_file_t.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_stream_file_t - -mongoc_stream_file_t -==================== - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_stream_file_t mongoc_stream_file_t - -``mongoc_stream_file_t`` is a :symbol:`mongoc_stream_t` subclass for working with standard UNIX style file-descriptors. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_stream_file_get_fd - mongoc_stream_file_new - mongoc_stream_file_new_for_path - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_flush.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_flush.rst deleted file mode 100644 index 702dc20baceb5516d799c2c39c4fe550f9c08cb5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_flush.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_stream_flush - -mongoc_stream_flush() -===================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_stream_flush (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. - -This function shall flush any buffered bytes in the underlying stream to the physical transport. It mimics the API and semantics of ``fflush()``, forcing a write of user space buffered data. - -Not all stream implementations may implement this feature. - -Returns -------- - -0 is returned on success, otherwise ``-1`` and ``errno`` is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_get_base_stream.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_get_base_stream.rst deleted file mode 100644 index 1f994f36c5248220d669f2f5e37f41a3626cb80d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_get_base_stream.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_stream_get_base_stream - -mongoc_stream_get_base_stream() -=============================== - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_stream_get_base_stream (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. - -This function shall fetch the underlying stream for streams that wrap a base stream. Such implementations include :symbol:`mongoc_stream_buffered_t` and :symbol:`mongoc_stream_tls_t`. - -Returns -------- - -A :symbol:`mongoc_stream_t` or ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_gridfs_new.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_gridfs_new.rst deleted file mode 100644 index f19b5333d1e4a885cdf877e833fa187c8c420fb8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_gridfs_new.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_stream_gridfs_new - -mongoc_stream_gridfs_new() -========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_stream_gridfs_new (mongoc_gridfs_file_t *file); - -Parameters ----------- - -* ``file``: A :symbol:`mongoc_gridfs_file_t`. - -This function shall create a new :symbol:`mongoc_stream_t` to read from and write to a GridFS file. GridFS files are created with :symbol:`mongoc_gridfs_create_file` or :symbol:`mongoc_gridfs_create_file_from_stream`. - -This function does not transfer ownership of ``file``. Therefore, ``file`` must remain valid for the lifetime of this stream. - -Returns -------- - -A newly allocated :symbol:`mongoc_stream_t` if successful, otherwise ``NULL``. - -Note, the returned stream ignores read and write timeouts passed to :symbol:`mongoc_stream_readv`, :symbol:`mongoc_stream_writev`, and so on. It uses the "socketTimeoutMS" and "connectTimeoutMS" values from the MongoDB URI. diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_read.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_read.rst deleted file mode 100644 index e6d522695cec78bee49f1cba3668e4bdda6092ee..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_read.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_stream_read - -mongoc_stream_read() -==================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_stream_read (mongoc_stream_t *stream, - void *buf, - size_t count, - size_t min_bytes, - int32_t timeout_msec); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. -* ``buf``: The buffer to read into. -* ``count``: The number of bytes to read. -* ``min_bytes``: The minimum number of bytes to read, or else indicate failure. -* ``timeout_msec``: The number of milliseconds to wait before failure, a timeout of 0 will not block. If negative, use the default timeout. - -The :symbol:`mongoc_stream_read()` function shall perform a read from a :symbol:`mongoc_stream_t`. It's modeled on the API and semantics of ``read()``, though the parameters map only loosely. - -Returns -------- - -The :symbol:`mongoc_stream_read` function returns the number of bytes read on success. It returns ``>= 0`` and ``< min_bytes`` when end-of-file is encountered and ``-1`` on failure. ``errno`` is set upon failure. - -See Also --------- - -:symbol:`mongoc_stream_readv()` - -:symbol:`mongoc_stream_write()` - -:symbol:`mongoc_stream_writev()` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_readv.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_readv.rst deleted file mode 100644 index 5ed3c9204ac313747de9008319dedabfeeaa1836..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_readv.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_stream_readv - -mongoc_stream_readv() -===================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_stream_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. -* ``iov``: A vector of :symbol:`mongoc_iovec_t`. -* ``iovcnt``: The number of items in ``iov``. -* ``min_bytes``: The minimum number of bytes to read or failure will be indicated. -* ``timeout_msec``: A timeout in milliseconds, or 0 to indicate non-blocking. A negative value with use the default timeout. - -This function is identical to :symbol:`mongoc_stream_read()` except that it takes a :symbol:`mongoc_iovec_t` to perform gathered I/O. - -Returns -------- - -``>= 0`` on success, ``-1`` on failure and ``errno`` is set. - -See Also --------- - -:symbol:`mongoc_stream_read()` - -:symbol:`mongoc_stream_write()` - -:symbol:`mongoc_stream_writev()` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_setsockopt.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_setsockopt.rst deleted file mode 100644 index 994e941a76c80aed5644d9ac8b5669b4ba5e9fba..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_setsockopt.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_stream_setsockopt - -mongoc_stream_setsockopt() -========================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_stream_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. -* ``level``: The level to pass to ``setsockopt()``. -* ``optname``: The optname to pass to ``setsockopt()``. -* ``optval``: The optval to pass to ``setsockopt()``. -* ``optlen``: The optlen to pass to ``setsockopt()``. - -This function is a wrapper around ``setsockopt()`` for streams that wrap sockets. - -Returns -------- - -``0`` on success, otherwise ``-1`` and ``errno`` is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_should_retry.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_should_retry.rst deleted file mode 100644 index 3571e3359185d228924997abfb76e8d34754b4f3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_should_retry.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_stream_should_retry - -mongoc_stream_should_retry() -============================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_stream_should_retry (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. - -Returns -------- - -True if the stream is open and has encountered a retryable network error such as EAGAIN or if a TLS exchange is in progress and needs more data. diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_socket_get_socket.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_socket_get_socket.rst deleted file mode 100644 index ad8875744e9ed36c40a411b541b73c002d38f052..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_socket_get_socket.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_stream_socket_get_socket - -mongoc_stream_socket_get_socket() -================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_socket_t * - mongoc_stream_socket_get_socket (mongoc_stream_socket_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_socket_t`. - -Retrieves the underlying :symbol:`mongoc_socket_t` for a :symbol:`mongoc_stream_socket_t`. - -Returns -------- - -A :symbol:`mongoc_stream_socket_t`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_socket_new.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_socket_new.rst deleted file mode 100644 index 911f8b8a3b227405d3a1f0450be2f26de17de20d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_socket_new.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_stream_socket_new - -mongoc_stream_socket_new() -========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_stream_t * - mongoc_stream_socket_new (mongoc_socket_t *socket); - -Parameters ----------- - -* ``socket``: A :symbol:`mongoc_socket_t`. - -Creates a new :symbol:`mongoc_stream_socket_t` using the :symbol:`mongoc_socket_t` provided. - -.. warning:: - - This function transfers ownership of ``socket`` to the newly allocated stream. - -Returns -------- - -A newly allocated :symbol:`mongoc_stream_socket_t` that should be freed with :symbol:`mongoc_stream_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_socket_t.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_socket_t.rst deleted file mode 100644 index 2c3e008c1aeeaa880fbda3aa34f71df3980b30ea..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_socket_t.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_stream_socket_t - -mongoc_stream_socket_t -====================== - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_stream_socket_t mongoc_stream_socket_t - -``mongoc_stream_socket_t`` should be considered a subclass of :symbol:`mongoc_stream_t` that works upon socket streams. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_stream_socket_get_socket - mongoc_stream_socket_new - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_t.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_t.rst deleted file mode 100644 index 851cb399f92624c67d44107de24d257911017baf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_t.rst +++ /dev/null @@ -1,55 +0,0 @@ -:man_page: mongoc_stream_t - -mongoc_stream_t -=============== - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_stream_t mongoc_stream_t - -``mongoc_stream_t`` provides a generic streaming IO abstraction based on a struct of pointers interface. The idea is to allow wrappers, perhaps other language drivers, to easily shim their IO system on top of ``mongoc_stream_t``. - -The API for the stream abstraction is currently private and non-extensible. - -Stream Types ------------- - -There are a number of built in stream types that come with mongoc. The default configuration is a buffered unix stream. If SSL is in use, that in turn is wrapped in a tls stream. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_stream_buffered_new - mongoc_stream_close - mongoc_stream_cork - mongoc_stream_destroy - mongoc_stream_flush - mongoc_stream_get_base_stream - mongoc_stream_read - mongoc_stream_readv - mongoc_stream_setsockopt - mongoc_stream_should_retry - mongoc_stream_timed_out - mongoc_stream_uncork - mongoc_stream_write - mongoc_stream_writev - -See Also --------- - -:doc:`mongoc_stream_buffered_t` - -:doc:`mongoc_stream_file_t` - -:doc:`mongoc_stream_socket_t` - -:doc:`mongoc_stream_tls_t` diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_timed_out.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_timed_out.rst deleted file mode 100644 index 6354156b593fffc2aa76c1817bedaafeec8eb692..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_timed_out.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_stream_timed_out - -mongoc_stream_timed_out() -========================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_stream_timed_out (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. - -Returns -------- - -True if there has been a network timeout error on this stream. diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_tls_t.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_tls_t.rst deleted file mode 100644 index bc92953157b2cb9b79f6db8b3815b6a366c4e68d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_tls_t.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_stream_tls_t - -mongoc_stream_tls_t -=================== - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_stream_tls_t mongoc_stream_tls_t - -``mongoc_stream_tls_t`` is a :symbol:`mongoc_stream_t` subclass for working with OpenSSL TLS streams. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_uncork.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_uncork.rst deleted file mode 100644 index 31fcfed7b41d2dec2125b1c06e96f15b49bfc553..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_uncork.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_stream_uncork - -mongoc_stream_uncork() -====================== - -Synopsis --------- - -.. code-block:: c - - int - mongoc_stream_uncork (mongoc_stream_t *stream); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. - -This function shall allow a previously corked socket to pass bytes to the underlying socket. - -.. note:: - - Not all streams implement this function. Buffering generally works better. - -Returns -------- - -``0`` on success, ``-1`` on failure and ``errno`` is set. - -See Also --------- - -:doc:`mongoc_stream_buffered_new() <mongoc_stream_buffered_new>`. - -:doc:`mongoc_stream_cork() <mongoc_stream_cork>`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_write.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_write.rst deleted file mode 100644 index 16310644f50e304972f12b4ed8858c9a0cf34658..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_write.rst +++ /dev/null @@ -1,40 +0,0 @@ -:man_page: mongoc_stream_write - -mongoc_stream_write() -===================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_stream_write (mongoc_stream_t *stream, - void *buf, - size_t count, - int32_t timeout_msec); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. -* ``buf``: The buffer to write. -* ``count``: The number of bytes to write. -* ``timeout_msec``: The number of milliseconds to wait before failure, a timeout of 0 will not block. If negative, use the default timeout. - -The :symbol:`mongoc_stream_write()` function shall perform a write to a :symbol:`mongoc_stream_t`. It's modeled on the API and semantics of ``write()``, though the parameters map only loosely. - -Returns -------- - -The :symbol:`mongoc_stream_write` function returns the number of bytes written on success. It returns ``-1`` and sets ``errno`` upon failure. - -See Also --------- - -:symbol:`mongoc_stream_read()` - -:symbol:`mongoc_stream_readv()` - -:symbol:`mongoc_stream_writev()` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_stream_writev.rst b/lib/mongoc/libmongoc/doc/mongoc_stream_writev.rst deleted file mode 100644 index 6ff616fda5151c669de20b15e62ec03e3c4458a4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_stream_writev.rst +++ /dev/null @@ -1,34 +0,0 @@ -:man_page: mongoc_stream_writev - -mongoc_stream_writev() -====================== - -Synopsis --------- - -.. code-block:: c - - ssize_t - mongoc_stream_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec); - -Parameters ----------- - -* ``stream``: A :symbol:`mongoc_stream_t`. -* ``iov``: A vector of :symbol:`mongoc_iovec_t`. -* ``iovcnt``: The number of items in ``iov``. -* ``timeout_msec``: The number of milliseconds to block before indicating failure, or 0 for non-blocking. Negative values indicate the default timeout. - -The ``mongoc_stream_writev()`` function shall perform a write -to a :symbol:`mongoc_stream_t`. It's modeled on the -API and semantics of ``writev()``, though the parameters map only -loosely. - -Returns -------- - -The number of bytes written on success, or ``-1`` upon failure and ``errno`` is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_topology_description_get_servers.rst b/lib/mongoc/libmongoc/doc/mongoc_topology_description_get_servers.rst deleted file mode 100644 index 657295afb6fc48f27b3329981a3c1b72ca61856e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_topology_description_get_servers.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_topology_description_get_servers - -mongoc_topology_description_get_servers() -========================================= - -Synopsis --------- - -.. code-block:: c - - mongoc_server_description_t ** - mongoc_topology_description_get_servers ( - const mongoc_topology_description_t *td, size_t *n); - -Fetches an array of :symbol:`mongoc_server_description_t` structs for all known servers in the topology. - -Parameters ----------- - -* ``td``: A :symbol:`mongoc_topology_description_t`. -* ``n``: Receives the length of the descriptions array. - -Returns -------- - -A newly allocated array that must be freed with :symbol:`mongoc_server_descriptions_destroy_all`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_topology_description_has_readable_server.rst b/lib/mongoc/libmongoc/doc/mongoc_topology_description_has_readable_server.rst deleted file mode 100644 index 31240eeb6855100626b45b26e015eb119eaf2b2e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_topology_description_has_readable_server.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_topology_description_has_readable_server - -mongoc_topology_description_has_readable_server() -================================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_topology_description_has_readable_server ( - mongoc_topology_description_t *td, const mongoc_read_prefs_t *prefs); - -Determines if the topology has a readable server available. -Servers are filtered by the given read preferences only if the driver is connected to a replica set, otherwise the read preferences are ignored. -This function uses the driver's current knowledge of the state of the MongoDB server or servers it is connected to; it does no I/O and it does not block. - -.. |td-func| replace:: ``mongoc_topology_description_has_readable_server`` - -.. include:: includes/cast-away-td-const.txt - -Parameters ----------- - -* ``td``: A :symbol:`mongoc_topology_description_t`. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t` or ``NULL`` for default read preferences. - -Returns -------- - -True if there is a known server matching ``prefs``. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_topology_description_has_writable_server.rst b/lib/mongoc/libmongoc/doc/mongoc_topology_description_has_writable_server.rst deleted file mode 100644 index f7fe58a51ff7a5ef4c8c9d251f1408bdfd9fbc84..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_topology_description_has_writable_server.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_topology_description_has_writable_server - -mongoc_topology_description_has_writable_server() -================================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_topology_description_has_writable_server ( - mongoc_topology_description_t *td); - -Determines if the topology has a writable server available, such as a primary, mongos, or standalone. This function uses the driver's current knowledge of the state of the MongoDB server or servers it is connected to; it does no I/O and it does not block. - -.. |td-func| replace:: ``mongoc_topology_description_has_writable_server`` - -.. include:: includes/cast-away-td-const.txt - -Parameters ----------- - -* ``td``: A :symbol:`mongoc_topology_description_t`. - -Returns -------- - -True if there is a known writable server. - -See Also --------- - -:doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_topology_description_t.rst b/lib/mongoc/libmongoc/doc/mongoc_topology_description_t.rst deleted file mode 100644 index de61915e6b858a07cd39dcfb7cebeaa1adfac783..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_topology_description_t.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_topology_description_t - -mongoc_topology_description_t -============================= - -Status of MongoDB Servers - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_topology_description_t mongoc_topology_description_t; - -``mongoc_topology_description_t`` is an opaque type representing the driver's knowledge of the MongoDB server or servers it is connected to. -Its API conforms to the `SDAM Monitoring Specification <https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst>`_. - -Applications receive a temporary reference to a ``mongoc_topology_description_t`` as a parameter to an SDAM Monitoring callback. See :doc:`Introduction to Application Performance Monitoring <application-performance-monitoring>`. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_topology_description_get_servers - mongoc_topology_description_has_readable_server - mongoc_topology_description_has_writable_server - mongoc_topology_description_type - diff --git a/lib/mongoc/libmongoc/doc/mongoc_topology_description_type.rst b/lib/mongoc/libmongoc/doc/mongoc_topology_description_type.rst deleted file mode 100644 index 14c59beb26fbadcd635aeb907cf815710583ebf8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_topology_description_type.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_topology_description_type - -mongoc_topology_description_type() -================================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_topology_description_type (const mongoc_topology_description_t *td); - -Parameters ----------- - -* ``td``: A :symbol:`mongoc_topology_description_t`. - -Description ------------ - -This function returns a string, one of the topology types defined in the Server Discovery And Monitoring Spec: - -* Unknown -* Single -* Sharded -* ReplicaSetNoPrimary -* ReplicaSetWithPrimary - diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opt_t.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opt_t.rst deleted file mode 100644 index a1e41104b7583a50060b4b2571e55cd1462cf86a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opt_t.rst +++ /dev/null @@ -1,51 +0,0 @@ -:man_page: mongoc_transaction_opt_t - -mongoc_transaction_opt_t -======================== - -.. code-block:: c - - #include <mongoc/mongoc.h> - - typedef struct _mongoc_transaction_opt_t mongoc_transaction_opt_t; - -Synopsis --------- - -Options for starting a multi-document transaction. - -When a session is first created with :symbol:`mongoc_client_start_session`, it inherits from the client the read concern, write concern, and read preference with which to start transactions. Each of these fields can be overridden independently. Create a :symbol:`mongoc_transaction_opt_t` with :symbol:`mongoc_transaction_opts_new`, and pass a non-NULL option to any of the :symbol:`mongoc_transaction_opt_t` setter functions: - -* :symbol:`mongoc_transaction_opts_set_read_concern` -* :symbol:`mongoc_transaction_opts_set_write_concern` -* :symbol:`mongoc_transaction_opts_set_read_prefs` - -Pass the resulting transaction options to :symbol:`mongoc_client_session_start_transaction`. Each field set in the transaction options overrides the inherited client configuration. - -Example -------- - -.. literalinclude:: ../examples/example-transaction.c - :language: c - :caption: example-transaction.c - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_transaction_opts_new - mongoc_transaction_opts_get_read_concern - mongoc_transaction_opts_set_read_concern - mongoc_transaction_opts_get_write_concern - mongoc_transaction_opts_set_write_concern - mongoc_transaction_opts_get_read_prefs - mongoc_transaction_opts_set_read_prefs - mongoc_transaction_opts_get_max_commit_time_ms - mongoc_transaction_opts_set_max_commit_time_ms - mongoc_transaction_opts_clone - mongoc_transaction_opts_destroy diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_clone.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_clone.rst deleted file mode 100644 index 4eb7c60d90a11a4318d5001c238d56ccec1e718f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_clone.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_transaction_opts_clone - -mongoc_transaction_opts_clone() -=============================== - -Synopsis --------- - -.. code-block:: c - - mongoc_transaction_opt_t * - mongoc_transaction_opts_clone (const mongoc_transaction_opt_t *opts); - -Create a copy of a transaction options struct. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_destroy.rst deleted file mode 100644 index 4e972a9b5f2d01f035b19996401549d5d4818738..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_destroy.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_transaction_opts_destroy - -mongoc_transaction_opts_destroy() -================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_transaction_opts_destroy (mongoc_transaction_opt_t *opts); - -Free a :symbol:`mongoc_transaction_opt_t`. Does nothing if ``opts`` is NULL. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_max_commit_time_ms.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_max_commit_time_ms.rst deleted file mode 100644 index 06f029f02da38b3612d4452410d9a34b33bf91ff..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_max_commit_time_ms.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_transaction_opts_get_max_commit_time_ms - -mongoc_transaction_opts_get_max_commit_time_ms() -================================================ - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_transaction_opts_get_max_commit_time_ms (const mongoc_transaction_opt_t *opts); - -Return the transaction options' max commit time, in milliseconds. See :symbol:`mongoc_transaction_opts_set_max_commit_time_ms()`. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_read_concern.rst deleted file mode 100644 index 8ecc6d05017cdbd7dc849ff406ff93e999756dc2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_read_concern.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_transaction_opts_get_read_concern - -mongoc_transaction_opts_get_read_concern() -========================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_concern_t * - mongoc_transaction_opts_get_read_concern (const mongoc_transaction_opt_t *opts); - -Return the transaction options' :symbol:`mongoc_read_concern_t`. The returned value is valid only for the lifetime of ``opts``. See :symbol:`mongoc_transaction_opts_set_read_concern()`. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_read_prefs.rst deleted file mode 100644 index 844a8d85a74c9bed29ab9978fc87acab4bc28b9a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_read_prefs.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_transaction_opts_get_read_prefs - -mongoc_transaction_opts_get_read_prefs() -======================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_prefs_t * - mongoc_transaction_opts_get_read_prefs (const mongoc_transaction_opt_t *opts); - -Return the transaction options' :symbol:`mongoc_read_prefs_t`. The returned value is valid only for the lifetime of ``opts``. See :symbol:`mongoc_transaction_opts_set_read_prefs()`. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_write_concern.rst deleted file mode 100644 index 7d58d2ce69c2de20b9ded7982e997ace642c687f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_get_write_concern.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_transaction_opts_get_write_concern - -mongoc_transaction_opts_get_write_concern() -=========================================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_write_concern_t * - mongoc_transaction_opts_get_write_concern (const mongoc_transaction_opt_t *opts); - -Return the transaction options' :symbol:`mongoc_write_concern_t`. The returned value is valid only for the lifetime of ``opts``. See :symbol:`mongoc_transaction_opts_set_write_concern()`. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_new.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_new.rst deleted file mode 100644 index 866af17efb1105cae17c0952c226ecb3f7d1c278..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_new.rst +++ /dev/null @@ -1,19 +0,0 @@ -:man_page: mongoc_transaction_opts_new - -mongoc_transaction_opts_new() -============================= - -Synopsis --------- - -.. code-block:: c - - mongoc_transaction_opt_t * - mongoc_transaction_opts_new (void); - -Create a :symbol:`mongoc_transaction_opt_t` to configure multi-document transactions. The struct must be freed with :symbol:`mongoc_transaction_opts_destroy`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_max_commit_time_ms.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_max_commit_time_ms.rst deleted file mode 100644 index 8de4cf7575fabac8b8a07942e19555c897d8e480..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_max_commit_time_ms.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_transaction_opts_set_max_commit_time_ms - -mongoc_transaction_opts_set_max_commit_time_ms() -================================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_transaction_opts_set_max_commit_time_ms (mongoc_transaction_opt_t *opts, - int64_t max_commit_time_ms); - -Configure the transaction's max commit time, in milliseconds. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. -* ``int64_t``: Timeout for commitTransaction, in milliseconds. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_read_concern.rst deleted file mode 100644 index 5f77bce401e356a2bc63ed963cc2b6e4ff8f132f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_read_concern.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_transaction_opts_set_read_concern - -mongoc_transaction_opts_set_read_concern() -========================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_transaction_opts_set_read_concern (mongoc_transaction_opt_t *opts, - const mongoc_read_concern_t *read_concern); - -Configure the transaction's read concern. The argument is copied into the struct and can be freed after calling this function. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. -* ``read_concern``: A :symbol:`mongoc_read_concern_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_read_prefs.rst deleted file mode 100644 index c4cc46a0b027d60e9975769108edff57e9b7a84f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_read_prefs.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_transaction_opts_set_read_prefs - -mongoc_transaction_opts_set_read_prefs() -======================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_transaction_opts_set_read_prefs (mongoc_transaction_opt_t *opts, - const mongoc_read_prefs_t *read_prefs); - -Configure the transaction's read preference. The argument is copied into the struct and can be freed after calling this function. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. -* ``read_prefs``: A :symbol:`mongoc_read_prefs_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_write_concern.rst deleted file mode 100644 index 30608641f9d7b03c9451bd7ad126f693a1159dc4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_opts_set_write_concern.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_transaction_opts_set_write_concern - -mongoc_transaction_opts_set_write_concern() -=========================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_transaction_opts_set_write_concern (mongoc_transaction_opt_t *opts, - const mongoc_write_concern_t *write_concern); - -Configure the transaction's write concern. The argument is copied into the struct and can be freed after calling this function. - -Parameters ----------- - -* ``opts``: A :symbol:`mongoc_transaction_opt_t`. -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -.. only:: html - - .. taglist:: See Also: - :tags: session diff --git a/lib/mongoc/libmongoc/doc/mongoc_transaction_state_t.rst b/lib/mongoc/libmongoc/doc/mongoc_transaction_state_t.rst deleted file mode 100644 index f93f1ad2a435c0cddc65d574fe66d434c7aab14f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_transaction_state_t.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_transaction_state_t - -mongoc_transaction_state_t -========================== - -Constants for transaction states - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_TRANSACTION_NONE = 0, - MONGOC_TRANSACTION_STARTING = 1, - MONGOC_TRANSACTION_IN_PROGRESS = 2, - MONGOC_TRANSACTION_COMMITTED = 3, - MONGOC_TRANSACTION_ABORTED = 4, - } mongoc_transaction_state_t; - -Description ------------ - -These constants describe the current transaction state of a session. - -Flag Values ------------ - -================================== ============================================================================= -MONGOC_TRANSACTION_NONE There is no transaction in progress. -MONGOC_TRANSACTION_STARTING A transaction has been started, but no operation has been sent to the server. -MONGOC_TRANSACTION_IN_PROGRESS A transaction is in progress. -MONGOC_TRANSACTION_COMMITTED The transaction was committed. -MONGOC_TRANSACTION_ABORTED The transaction was aborted. -================================== ============================================================================= diff --git a/lib/mongoc/libmongoc/doc/mongoc_update_flags_t.rst b/lib/mongoc/libmongoc/doc/mongoc_update_flags_t.rst deleted file mode 100644 index 991d1cc43b1c08c09bdb66ddaca04739fbede7c9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_update_flags_t.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_update_flags_t - -mongoc_update_flags_t -===================== - -Flags for update operations - -Synopsis --------- - -.. code-block:: c - - typedef enum { - MONGOC_UPDATE_NONE = 0, - MONGOC_UPDATE_UPSERT = 1 << 0, - MONGOC_UPDATE_MULTI_UPDATE = 1 << 1, - } mongoc_update_flags_t; - - #define MONGOC_UPDATE_NO_VALIDATE (1U << 31) - -Description ------------ - -These flags correspond to the MongoDB wire protocol. They may be bitwise or'd together. The allow for modifying the way an update is performed in the MongoDB server. - -Flag Values ------------ - -========================== ======================================================================================================================================== -MONGOC_UPDATE_NONE No update flags set. -MONGOC_UPDATE_UPSERT If an upsert should be performed. -MONGOC_UPDATE_MULTI_UPDATE If more than a single matching document should be updated. By default only the first document is updated. -MONGOC_UPDATE_NO_VALIDATE Do not perform client side BSON validations when performing an update. This is useful if you already know your BSON documents are valid. -========================== ======================================================================================================================================== - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_copy.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_copy.rst deleted file mode 100644 index e1b570f1cba85fbb96615a261e2a66257064fe8d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_copy.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_copy - -mongoc_uri_copy() -================= - -Synopsis --------- - -.. code-block:: c - - mongoc_uri_t * - mongoc_uri_copy (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Copies the entire contents of a URI. - -Returns -------- - -A newly allocated :symbol:`mongoc_uri_t` that should be freed with :symbol:`mongoc_uri_destroy()`. May return ``NULL`` on invalid host. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_destroy.rst deleted file mode 100644 index b4ee36336064a25f4b8bb0d72d495c544b0412fc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_uri_destroy - -mongoc_uri_destroy() -==================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_uri_destroy (mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Frees all resources associated with a uri. Does nothing if ``uri`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_auth_mechanism.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_auth_mechanism.rst deleted file mode 100644 index edc99fb9c9e7cd46e14db54ba8eb98c3b7dd2f76..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_auth_mechanism.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_uri_get_auth_mechanism - -mongoc_uri_get_auth_mechanism() -=============================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches the ``authMechanism`` parameter to an URI if provided. - -Returns -------- - -A string which should not be modified or freed. Returns ``NULL`` if the ``authMechanism`` parameter was not provided to ``uri``. - -.. only:: html - - .. taglist:: See Also: - :tags: authmechanism diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_auth_source.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_auth_source.rst deleted file mode 100644 index 64ef42859f530758cd13be5b0c83b78fc5af1a27..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_auth_source.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_uri_get_auth_source - -mongoc_uri_get_auth_source() -============================ - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_auth_source (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches the ``authSource`` parameter of an URI if provided. - -Returns -------- - -A string which should not be modified or freed if the ``authSource`` parameter is provided, otherwise ``NULL``. - -.. only:: html - - .. taglist:: See Also: - :tags: authmechanism diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_compressors.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_compressors.rst deleted file mode 100644 index 057c8ad1f2d0ea99ad0e933eb5b74f913270511c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_compressors.rst +++ /dev/null @@ -1,42 +0,0 @@ -:man_page: mongoc_uri_get_compressors - -mongoc_uri_get_compressors() -============================ - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_uri_get_compressors (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Returns a bson document with the enabled compressors as the keys if ``uri`` has compressors provided, otherwise ``NULL``. - -Example -------- - -.. code-block:: c - - mongoc_client_t *client; - mongoc_uri_t *uri; - - uri = mongoc_uri_new ("mongodb://localhost/?compressors=zlib,snappy,zstd"); - - if (bson_has_field (mongoc_uri_get_compressors (uri), "snappy")) { - /* snappy enabled */ - } - -Returns -------- - -A bson_t * which should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_database.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_database.rst deleted file mode 100644 index e99007a55050402175b7f782e8ec3bb3bf7e97e1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_database.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_database - -mongoc_uri_get_database() -========================= - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_database (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches the database portion of an URI if provided. This is the portion after the ``/`` but before the ``?``. - -Returns -------- - -A string which should not be modified or freed or ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_hosts.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_hosts.rst deleted file mode 100644 index 986233be0328f4a2d43e3534cd31a08cf88da636..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_hosts.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_uri_get_hosts - -mongoc_uri_get_hosts() -====================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_host_list_t * - mongoc_uri_get_hosts (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches a linked list of hosts that were defined in the URI (the comma-separated host section). - -Returns -------- - -A linked list of :symbol:`mongoc_host_list_t` structures that should not be modified or freed. Returns ``NULL`` if this URI's scheme is "mongodb+srv://". diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_mechanism_properties.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_mechanism_properties.rst deleted file mode 100644 index c750c9f6f6a700496e3091820e6c0a43cb0bcc34..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_mechanism_properties.rst +++ /dev/null @@ -1,63 +0,0 @@ -:man_page: mongoc_uri_get_mechanism_properties - -mongoc_uri_get_mechanism_properties() -===================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri, - bson_t *properties /* OUT */); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``properties``: An uninitialized :symbol:`bson:bson_t`. - -Description ------------ - -Fetches the "authMechanismProperties" options set on this :symbol:`mongoc_uri_t`. The out-parameter ``properties`` should be an uninitialized, stack-allocated :symbol:`bson:bson_t`. It is statically initialized with :symbol:`bson:bson_init_static` to point to the internal data of ``uri``, so its contents must not be modified and it becomes invalid after ``uri`` is destroyed. - -Returns -------- - -If no "authMechanismProperties" have been set on ``uri``, this functions returns false and ``properties`` remains uninitialized. - -Example -------- - -.. code-block:: c - - mongoc_uri_t *uri; - bson_t props; - - uri = mongoc_uri_new ( - "mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI" - "&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true"); - - if (mongoc_uri_get_mechanism_properties (uri, &props)) { - char *json = bson_as_canonical_extended_json (&props, NULL); - printf ("%s\n", json); - bson_free (json); - } else { - printf ("No authMechanismProperties.\n"); - } - -This code produces the output: - -.. code-block:: none - - { "SERVICE_NAME" : "other", "CANONICALIZE_HOST_NAME" : "true" } - -See Also --------- - -.. only:: html - - .. taglist:: See Also: - :tags: authmechanism diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_bool.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_bool.rst deleted file mode 100644 index 5a83cca7e13708e3733e6de59d3a42c871317012..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_bool.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_uri_get_option_as_bool - -mongoc_uri_get_option_as_bool() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri, - const char *option, - bool fallback); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``option``: The name of an option, case insensitive. -* ``fallback``: A default value to return. - -Description ------------ - -Returns the value of the URI option if it is set and of the correct type (bool). If not set, or set to an invalid type, returns ``fallback``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_int32.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_int32.rst deleted file mode 100644 index 48e6c13531f86a38fcbed8d0a7d56bc27add8f1c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_int32.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_uri_get_option_as_int32 - -mongoc_uri_get_option_as_int32() -================================ - -Synopsis --------- - -.. code-block:: c - - int32_t - mongoc_uri_get_option_as_int32 (const mongoc_uri_t *uri, - const char *option, - int32_t fallback); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``option``: The name of an option, case insensitive. -* ``fallback``: A default value to return. - -Description ------------ - -Returns the value of the URI option if it is set and of the correct type (integer). Returns ``fallback`` if the option is not set, set to an invalid type, or zero. - -Zero is considered "unset", so URIs can be constructed like so, and still accept default values: - -.. code-block:: c - - bson_strdup_printf ("mongodb://localhost/?connectTimeoutMS=%d", myvalue) - -If ``myvalue`` is non-zero it is the connection timeout; if it is zero the driver uses the default timeout. - -When reading an option that is an int64, this function will return the value as ``int32_t``. If the value is outside the range of a 32-bit integer, a warning will be emitted and ``fallback`` is returned instead. - -See Also --------- - -* :symbol:`mongoc_uri_get_option_as_int64()` diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_int64.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_int64.rst deleted file mode 100644 index 8c057273fcd3171aa8160058239f65482f605eaa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_int64.rst +++ /dev/null @@ -1,39 +0,0 @@ -:man_page: mongoc_uri_get_option_as_int64 - -mongoc_uri_get_option_as_int64() -================================ - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_uri_get_option_as_int64 (const mongoc_uri_t *uri, - const char *option, - int64_t fallback); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``option``: The name of an option, case insensitive. -* ``fallback``: A default value to return. - -Description ------------ - -Returns the value of the URI option if it is set and of the correct type (integer). Returns ``fallback`` if the option is not set, set to an invalid type, or zero. - -Zero is considered "unset", so URIs can be constructed like so, and still accept default values: - -.. code-block:: c - - bson_strdup_printf ("mongodb://localhost/?wTimeoutMS=%" PRId64, myvalue) - -If ``myvalue`` is non-zero it is the write concern timeout; if it is zero the driver uses the default timeout. - -See Also --------- - -* :symbol:`mongoc_uri_get_option_as_int32()` diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_utf8.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_utf8.rst deleted file mode 100644 index 48af0d01e2109823bf2b15e228b20b4ee12772f1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_option_as_utf8.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_uri_get_option_as_utf8 - -mongoc_uri_get_option_as_utf8() -=============================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri, - const char *option, - const char *fallback); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``option``: The name of an option, case insensitive. -* ``fallback``: A default value to return. - -Description ------------ - -Returns the value of the URI option if it is set and of the correct type (string). This value is a pointer into the URI's internal buffer, and is only valid until the URI is modified or freed. If the option is not set, or set to an invalid type, returns ``fallback``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_options.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_options.rst deleted file mode 100644 index 98e98ef0afb40e3f3427d061aa42624e9cc98b2a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_options.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_options - -mongoc_uri_get_options() -======================== - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_uri_get_options (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches a bson document containing all of the options provided after the ``?`` of a URI. - -Returns -------- - -A :symbol:`bson:bson_t` which should not be modified or freed if ``uri`` has options provided, otherwise ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_password.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_password.rst deleted file mode 100644 index ac237a8ce6f05d6809d65a707ff4faa667a605f0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_password.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_password - -mongoc_uri_get_password() -========================= - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_password (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches the password portion of an URI. - -Returns -------- - -A string which should not be modified or freed if ``uri`` has a password specified, otherwise ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_concern.rst deleted file mode 100644 index 646a59931a168073f10bf8b6ab1a774a7ca78e54..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_concern.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_read_concern - -mongoc_uri_get_read_concern() -============================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_concern_t * - mongoc_uri_get_read_concern (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches a read concern that is owned by the URI instance. This read concern is configured based on URI parameters. - -Returns -------- - -Returns a :symbol:`mongoc_read_concern_t` that should not be modified or freed if a read concern is provided to ``uri``, otherwise ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_prefs.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_prefs.rst deleted file mode 100644 index dc2de1a83886fdbfd3d4247234a2aee7b32ef1da..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_prefs.rst +++ /dev/null @@ -1,37 +0,0 @@ -:man_page: mongoc_uri_get_read_prefs - -mongoc_uri_get_read_prefs() -=========================== - -Synopsis --------- - -.. code-block:: c - - const bson_t * - mongoc_uri_get_read_prefs (const mongoc_uri_t *uri); - -Deprecated ----------- - -.. warning:: - - This function is deprecated and should not be used in new code. - -Please use :doc:`mongoc_uri_get_read_prefs_t() <mongoc_uri_get_read_prefs_t>` instead. - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches a bson document containing read preference tag information from a URI. Note that this does not include the read preference mode. - -Returns -------- - -Returns a bson document that should not be modified or freed if ``uri`` has read preferences, otherwise ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_prefs_t.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_prefs_t.rst deleted file mode 100644 index a6fedcbb47bfa6029f7ae6470e0a164e2db9e591..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_read_prefs_t.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_read_prefs_t - -mongoc_uri_get_read_prefs_t() -============================= - -Synopsis --------- - -.. code-block:: c - - const mongoc_read_prefs_t * - mongoc_uri_get_read_prefs_t (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches a read preference that is owned by the URI instance. This read preference concern is configured based on URI parameters. - -Returns -------- - -Returns a :symbol:`mongoc_read_prefs_t` that should not be modified or freed if ``uri`` has read preferences, otherwise ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_replica_set.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_replica_set.rst deleted file mode 100644 index 1e48672f2a9d848ee5bb4caa817ca8d1d6859ded..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_replica_set.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_replica_set - -mongoc_uri_get_replica_set() -============================ - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_replica_set (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches the ``replicaSet`` parameter of an URI. - -Returns -------- - -Returns a string which should not be modified or freed. Returns ``NULL`` if the ``replicaSet`` parameter was not provided to ``uri``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_service.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_service.rst deleted file mode 100644 index bd5d738ee8122aeab1aaa2c639181dcdf1806c81..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_service.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_uri_get_service - -mongoc_uri_get_service() -======================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_service (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Returns the SRV service name of a MongoDB URI. - -Returns -------- - -A string if this URI's scheme is "mongodb+srv://", or NULL if the scheme is "mongodb://". diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_ssl.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_ssl.rst deleted file mode 100644 index d56e1fbef497412e88c15e6047e920c7177966be..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_ssl.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_uri_get_ssl - -mongoc_uri_get_ssl() -==================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_get_ssl (const mongoc_uri_t *uri) - BSON_GNUC_DEPRECATED_FOR (mongoc_uri_get_tls); - -Deprecated ----------- - -.. warning:: - - This function is deprecated and should not be used in new code. - -Please use :doc:`mongoc_uri_get_tls() <mongoc_uri_get_tls>` instead. - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches a boolean indicating if TLS was specified for use in the URI. - -Returns -------- - -Returns a boolean, true indicating that TLS should be used. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_string.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_string.rst deleted file mode 100644 index 96d6470f85526939d4a6159aba753c098483a05f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_string.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_string - -mongoc_uri_get_string() -======================= - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_string (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches the URI as a string. - -Returns -------- - -Returns a string which should not be modified or freed. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_tls.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_tls.rst deleted file mode 100644 index 31c814c5119a991b68071b940ad6b192ec5a1f79..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_tls.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_tls - -mongoc_uri_get_tls() -==================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_get_tls (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches a boolean indicating if TLS was specified for use in the URI. - -Returns -------- - -Returns a boolean, true indicating that TLS should be used. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_username.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_username.rst deleted file mode 100644 index f8ee50eaf31d41ef69c325ce548b77a55b582875..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_username.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_username - -mongoc_uri_get_username() -========================= - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_uri_get_username (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches the username portion of a URI. - -Returns -------- - -Returns a string which should not be modified or freed if ``uri`` has a username provided, otherwise ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_get_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_get_write_concern.rst deleted file mode 100644 index c0ad944fa06d07cad687cb91b958c94655415b7e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_get_write_concern.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_get_write_concern - -mongoc_uri_get_write_concern() -============================== - -Synopsis --------- - -.. code-block:: c - - const mongoc_write_concern_t * - mongoc_uri_get_write_concern (const mongoc_uri_t *uri); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. - -Description ------------ - -Fetches a write concern that is owned by the URI instance. This write concern is configured based on URI parameters. - -Returns -------- - -Returns a :symbol:`mongoc_write_concern_t` that should not be modified or freed if ``uri`` has a write concern provided, otherwise ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_new.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_new.rst deleted file mode 100644 index d9ab75422f1bee750028958b8407323434031309..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_new.rst +++ /dev/null @@ -1,33 +0,0 @@ -:man_page: mongoc_uri_new - -mongoc_uri_new() -================ - -Synopsis --------- - -.. code-block:: c - - mongoc_uri_t * - mongoc_uri_new (const char *uri_string) BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``uri_string``: A string containing a URI. - -Description ------------ - -Calls :symbol:`mongoc_uri_new_with_error`. - -Returns -------- - -A newly allocated :symbol:`mongoc_uri_t` if successful. Otherwise ``NULL``, using -MONGOC_WARNING on error. - -.. warning:: - - Failure to handle the result of this function is a programming error. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_new_for_host_port.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_new_for_host_port.rst deleted file mode 100644 index e01efefff278703e94b8776de8b67d3b2e13dba5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_new_for_host_port.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_uri_new_for_host_port - -mongoc_uri_new_for_host_port() -============================== - -Synopsis --------- - -.. code-block:: c - - mongoc_uri_t * - mongoc_uri_new_for_host_port (const char *hostname, uint16_t port); - -Parameters ----------- - -* ``hostname``: A string containing the hostname. -* ``port``: A uint16_t. - -Description ------------ - -Creates a new :symbol:`mongoc_uri_t` based on the hostname and port provided. - -Returns -------- - -Returns a newly allocated :symbol:`mongoc_uri_t` that should be freed with :symbol:`mongoc_uri_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_new_with_error.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_new_with_error.rst deleted file mode 100644 index 8576c29f75beed662877893781c32a3015b19f4d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_new_with_error.rst +++ /dev/null @@ -1,58 +0,0 @@ -:man_page: mongoc_uri_new_with_error - -mongoc_uri_new_with_error() -=========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_uri_t * - mongoc_uri_new_with_error (const char *uri_string, - bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT; - -Parameters ----------- - -* ``uri_string``: A string containing a URI. -* ``error``: An optional location for a :symbol:`bson_error_t <errors>` or ``NULL``. - -Description ------------ - -Parses a string containing a MongoDB style URI connection string. - -Returns -------- - -A newly allocated :symbol:`mongoc_uri_t` if successful. Otherwise ``NULL`` -populating ``error`` with the error description. - -.. warning:: - - Failure to handle the result of this function is a programming error. - -Examples --------- - -Examples of some valid MongoDB connection strings can be seen below. - -``"mongodb://localhost/"`` - -``"mongodb://localhost/?replicaSet=myreplset"`` - -``"mongodb://myuser:mypass@localhost/"`` - -``"mongodb://kerberosuser%40EXAMPLE.COM@example.com/?authMechanism=GSSAPI"`` - -``"mongodb://[::1]:27017/"`` - -``"mongodb://10.0.0.1:27017,10.0.0.1:27018,[::1]:27019/?ssl=true"`` - -``"mongodb://%2Ftmp%2Fmongodb-27017.sock"`` - -``"mongodb://user:pass@%2Ftmp%2Fmongodb-27017.sock"`` - -``"mongodb://localhost,[::1]/mydb?authSource=mydb"`` - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_bool.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_bool.rst deleted file mode 100644 index 87d5251faf1ee6dfc48534df3da1db0f8aac1636..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_bool.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_uri_option_is_bool - -mongoc_uri_option_is_bool() -=========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_option_is_bool (const char *option); - -Parameters ----------- - -* ``option``: The name of an option, case insensitive. - -Description ------------ - -Returns true if the option is a known MongoDB URI option of boolean type. For example, "ssl=false" is a valid MongoDB URI option, so ``mongoc_uri_option_is_bool ("ssl")`` is true. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_int32.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_int32.rst deleted file mode 100644 index 521ce42f83dfa36908f25b1c0ede09ed773ce7c1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_int32.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_uri_option_is_int32 - -mongoc_uri_option_is_int32() -============================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_option_is_int32 (const char *option); - -Parameters ----------- - -* ``option``: The name of an option, case insensitive. - -Description ------------ - -Returns true if the option is a known MongoDB URI option of integer type. For example, "zlibCompressionLevel=5" is a valid integer MongoDB URI option, so ``mongoc_uri_option_is_int32 ("zlibCompressionLevel")`` is true. This will also return true for all 64-bit integer options. - -See Also --------- - -* :symbol:`mongoc_uri_option_is_int64()` diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_int64.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_int64.rst deleted file mode 100644 index 7dbced4a204140583f756891a1067aa0fc516bef..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_int64.rst +++ /dev/null @@ -1,27 +0,0 @@ -:man_page: mongoc_uri_option_is_int64 - -mongoc_uri_option_is_int64() -============================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_option_is_int64 (const char *option); - -Parameters ----------- - -* ``option``: The name of an option, case insensitive. - -Description ------------ - -Returns true if the option is a known MongoDB URI option of 64-bit integer type. For example, "wTimeoutMS=100" is a valid 64-bit integer MongoDB URI option, so ``mongoc_uri_option_is_int64 ("wTimeoutMS")`` is true. - -See Also --------- - -* :symbol:`mongoc_uri_option_is_int32()` diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_utf8.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_utf8.rst deleted file mode 100644 index 18bd7714e5a1e3ed0114ea827186ef6f531d1d08..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_option_is_utf8.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_uri_option_is_utf8 - -mongoc_uri_option_is_utf8() -=========================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_option_is_utf8 (const char *option); - -Parameters ----------- - -* ``option``: The name of an option, case insensitive. - -Description ------------ - -Returns true if the option is a known MongoDB URI option of string type. For example, "replicaSet=my_rs" is a valid MongoDB URI option, so ``mongoc_uri_option_is_utf8 ("replicaSet")`` is true. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_auth_mechanism.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_auth_mechanism.rst deleted file mode 100644 index c608b1ca0f8e696cd06ab2c4c47365014c16b0b5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_auth_mechanism.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_uri_set_auth_mechanism - -mongoc_uri_set_auth_mechanism() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_auth_mechanism (mongoc_uri_t *uri, const char *value); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``value``: The new "authMechanism" value. - -Description ------------ - -Sets the "authMechanism" URI option, such as "SCRAM-SHA-1" or "GSSAPI", after the URI has been parsed from a string. - -Updates the option in-place if already set, otherwise appends it to the URI's :symbol:`bson:bson_t` of options. - -Returns -------- - -Returns false if the option cannot be set, for example if ``value`` is not valid UTF-8. - -.. only:: html - - .. taglist:: See Also: - :tags: authmechanism diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_auth_source.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_auth_source.rst deleted file mode 100644 index 01455cad1aa559423cd4fa9600dd402b2e67b95b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_auth_source.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_uri_set_auth_source - -mongoc_uri_set_auth_source() -============================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_auth_source (mongoc_uri_t *uri, const char *value); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``value``: The new "authSource" value. - -Description ------------ - -Sets the "authSource" URI option, after the URI has been parsed from a string. - -Updates the option in-place if already set, otherwise appends it to the URI's :symbol:`bson:bson_t` of options. - -Returns -------- - -Returns false if the option cannot be set, for example if ``value`` is not valid UTF-8. - -.. only:: html - - .. taglist:: See Also: - :tags: authmechanism diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_compressors.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_compressors.rst deleted file mode 100644 index 774e2817747861892fe542f0e3dea5db149d7b12..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_compressors.rst +++ /dev/null @@ -1,45 +0,0 @@ -:man_page: mongoc_uri_set_compressors - -mongoc_uri_set_compressors() -============================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_compressors (mongoc_uri_t *uri, const char *compressors); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``compressors``: One or more comma (,) separated compressors. - -Description ------------ - -Sets the URI's compressors, after the URI has been parsed from a string. -Will overwrite any previously set value. - -Example -------- - -.. code-block:: c - - mongoc_client_t *client; - mongoc_uri_t *uri; - - uri = mongoc_uri_new ("mongodb://localhost/"); - mongoc_uri_set_compressors (uri, "snappy,zlib,zstd"); - mongoc_client_new_from_uri (uri); - /* Snappy & zlib & zstd compressors are enabled */ - -Returns -------- - -Returns false if the option cannot be set, for example if ``compressors`` is not valid UTF-8. -Logs a warning to stderr with the :doc:`MONGOC_WARNING <logging>` macro -if compressor is not available. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_database.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_database.rst deleted file mode 100644 index 73a0fb326a5871165b3d1103d106bdaabf31e22f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_database.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_uri_set_database - -mongoc_uri_set_database() -========================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_database (mongoc_uri_t *uri, const char *database); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``database``: The new database name. - -Description ------------ - -Sets the URI's database, after the URI has been parsed from a string. - -The driver authenticates to this database if the connection string includes authentication credentials. This database is also the return value of :symbol:`mongoc_client_get_default_database`. - -Returns -------- - -Returns false if the option cannot be set, for example if ``database`` is not valid UTF-8. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_mechanism_properties.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_mechanism_properties.rst deleted file mode 100644 index 7f91e1fe22990a4981efc335f34ee688e1fa8166..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_mechanism_properties.rst +++ /dev/null @@ -1,59 +0,0 @@ -:man_page: mongoc_uri_set_mechanism_properties - -mongoc_uri_set_mechanism_properties() -===================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_mechanism_properties (mongoc_uri_t *uri, - const bson_t *properties); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``properties``: A :symbol:`bson:bson_t` . - -Description ------------ - -Replaces all the options in URI's "authMechanismProperties" after the URI has been parsed from a string. - -Returns -------- - -Returns false if the option cannot be set, for example if ``properties`` is not valid BSON data. - -Example -------- - -.. code-block:: c - - mongoc_uri_t *uri; - bson_t props = BSON_INITIALIZER; - - uri = mongoc_uri_new ( - "mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI" - "&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true"); - - /* replace all options: replace service name "other" with "my_service", unset - * "CANONICALIZE_HOST_NAME" and accept its default. - */ - BSON_APPEND_UTF8 (&props, "SERVICE_NAME", "my_service"); - mongoc_uri_set_mechanism_properties (uri, &props); - - bson_destroy (&props); - -See Also --------- - -:ref:`GSSAPI (Kerberos) Authentication <authentication_kerberos>` and :symbol:`mongoc_uri_get_mechanism_properties` - -.. only:: html - - .. taglist:: See Also: - :tags: authmechanism diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_bool.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_bool.rst deleted file mode 100644 index 3042d01d84676399c1b45fbff371fc30b1fbf4bf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_bool.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_uri_set_option_as_bool - -mongoc_uri_set_option_as_bool() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_option_as_bool (const mongoc_uri_t *uri, - const char *option, - bool value); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``option``: The name of an option, case insensitive. -* ``value``: The new value. - -Description ------------ - -Sets an individual URI option, after the URI has been parsed from a string. - -Only known options of type bool can be set. - -Updates the option in-place if already set, otherwise appends it to the URI's :symbol:`bson:bson_t` of options. - -Returns -------- - -True if successfully set (the named option is a known option of type bool). - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_int32.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_int32.rst deleted file mode 100644 index 61a7c8600df06cafbf4097ca62f09a384dca66f8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_int32.rst +++ /dev/null @@ -1,40 +0,0 @@ -:man_page: mongoc_uri_set_option_as_int32 - -mongoc_uri_set_option_as_int32() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_option_as_int32 (const mongoc_uri_t *uri, - const char *option, - int32_t value); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``option``: The name of an option, case insensitive. -* ``value``: The new value. - -Description ------------ - -Sets an individual URI option, after the URI has been parsed from a string. - -Only known options of type integer can be set. Some integer options, such as :ref:`minHeartbeatFrequencyMS <sdam_uri_options>`, have additional constraints. - -Updates the option in-place if already set, otherwise appends it to the URI's :symbol:`bson:bson_t` of options. - -Returns -------- - -True if successfully set (the named option is a known option of type int32 or int64). - -See Also --------- - -* :symbol:`mongoc_uri_set_option_as_int64()` diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_int64.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_int64.rst deleted file mode 100644 index 5e66d15b01c2f92d6726eb75bac06f859e42b8e6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_int64.rst +++ /dev/null @@ -1,41 +0,0 @@ -:man_page: mongoc_uri_set_option_as_int64 - -mongoc_uri_set_option_as_int64() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_option_as_int64 (const mongoc_uri_t *uri, - const char *option, - int64_t value); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``option``: The name of an option, case insensitive. -* ``value``: The new value. - -Description ------------ - -Sets an individual URI option, after the URI has been parsed from a string. - -Only known options of type int32 or int64 can be set. For 32-bit integer options, the function returns ``false`` when trying to set a 64-bit value that exceeds the range of an ``int32_t``. Values that fit into an ``int32_t`` will be set correctly. In both cases, a warning will be emitted. - -Updates the option in-place if already set, otherwise appends it to the URI's :symbol:`bson:bson_t` of options. - -Returns -------- - -True if successfully set (the named option is a known option of type int64). - -See Also --------- - -* :symbol:`mongoc_uri_option_is_int64()` -* :symbol:`mongoc_uri_set_option_as_int32()` diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_utf8.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_utf8.rst deleted file mode 100644 index bf71b5060fdd4c3a4990ee388ee32b72900f40d4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_option_as_utf8.rst +++ /dev/null @@ -1,36 +0,0 @@ -:man_page: mongoc_uri_set_option_as_utf8 - -mongoc_uri_set_option_as_utf8() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_option_as_utf8 (const mongoc_uri_t *uri, - const char *option, - utf8 value); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``option``: The name of an option, case insensitive. -* ``value``: The new value. - -Description ------------ - -Sets an individual URI option, after the URI has been parsed from a string. - -Only known string-type options can be set. - -Updates the option in-place if already set, otherwise appends it to the URI's :symbol:`bson:bson_t` of options. - -Returns -------- - -True if successfully set (the named option is a known option of string type). - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_password.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_password.rst deleted file mode 100644 index cae1177317f53d4e503f7bbcc6c18e9048cb1d0f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_password.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_uri_set_password - -mongoc_uri_set_password() -========================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_password (mongoc_uri_t *uri, const char *password); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``password``: The new password. - -Description ------------ - -Sets the URI's password, after the URI has been parsed from a string. The driver authenticates with this password if the username is also set. - -Returns -------- - -Returns false if the option cannot be set, for example if ``password`` is not valid UTF-8. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_read_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_read_concern.rst deleted file mode 100644 index 1d36ceb98b32a06eb916eba17a88fa0086efea29..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_read_concern.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_uri_set_read_concern - -mongoc_uri_set_read_concern() -============================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_uri_set_read_concern (mongoc_uri_t *uri, - const mongoc_read_concern_t *rc); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``rc``: A :symbol:`mongoc_read_concern_t`. - -Description ------------ - -Sets a MongoDB URI's read concern option, after the URI has been parsed from a string. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_read_prefs_t.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_read_prefs_t.rst deleted file mode 100644 index af5e900492a759fcce2bc65c2b240e40f1deff6d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_read_prefs_t.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_uri_set_read_prefs_t - -mongoc_uri_set_read_prefs_t() -============================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_uri_set_read_prefs_t (mongoc_uri_t *uri, - const mongoc_read_prefs_t *prefs); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``rc``: A :symbol:`mongoc_read_prefs_t`. - -Description ------------ - -Sets a MongoDB URI's read preferences, after the URI has been parsed from a string. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_username.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_username.rst deleted file mode 100644 index cf4d598d429df08e7b9fbb04792e9dd8f9895218..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_username.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_uri_set_username - -mongoc_uri_set_username() -========================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_uri_set_username (mongoc_uri_t *uri, const char *username); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``username``: The new username. - -Description ------------ - -Sets the URI's username, after the URI has been parsed from a string. The driver authenticates with this username if the password is also set. - -Returns -------- - -Returns false if the option cannot be set, for example if ``username`` is not valid UTF-8. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_set_write_concern.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_set_write_concern.rst deleted file mode 100644 index 80b865e54f246377a288fc840676456022db59b0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_set_write_concern.rst +++ /dev/null @@ -1,25 +0,0 @@ -:man_page: mongoc_uri_set_write_concern - -mongoc_uri_set_write_concern() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_uri_set_write_concern (mongoc_uri_t *uri, - const mongoc_write_concern_t *wc); - -Parameters ----------- - -* ``uri``: A :symbol:`mongoc_uri_t`. -* ``rc``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Sets a MongoDB URI's write concern option, after the URI has been parsed from a string. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_t.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_t.rst deleted file mode 100644 index a474ddfa215dd570a02bf618f04d5f08706281b5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_t.rst +++ /dev/null @@ -1,334 +0,0 @@ -:man_page: mongoc_uri_t - -mongoc_uri_t -============ - -Synopsis --------- - -.. code-block:: c - - typedef struct _mongoc_uri_t mongoc_uri_t; - -Description ------------ - -``mongoc_uri_t`` provides an abstraction on top of the MongoDB connection URI format. It provides standardized parsing as well as convenience methods for extracting useful information such as replica hosts or authorization information. - -See `Connection String URI Reference <http://docs.mongodb.org/manual/reference/connection-string/>`_ on the MongoDB website for more information. - -Format ------- - -.. code-block:: none - - mongodb[+srv]:// <1> - [username:password@] <2> - host1 <3> - [:port1] <4> - [,host2[:port2],...[,hostN[:portN]]] <5> - [/[database] <6> - [?options]] <7> - -#. "mongodb" is the specifier of the MongoDB protocol. Use "mongodb+srv" with a single service name in place of "host1" to specify the initial list of servers with an SRV record. -#. An optional username and password. -#. The only required part of the uri. This specifies either a hostname, IPv4 address, IPv6 address enclosed in "[" and "]", or UNIX domain socket. -#. An optional port number. Defaults to :27017. -#. Extra optional hosts and ports. You would specify multiple hosts, for example, for connections to replica sets. -#. The name of the database to authenticate if the connection string includes authentication credentials. If /database is not specified and the connection string includes credentials, defaults to the 'admin' database. -#. Connection specific options. - -.. note:: - - Option names are case-insensitive. Do not repeat the same option (e.g. "mongodb://localhost/db?opt=value1&OPT=value2") since this may have unexpected results. - -The MongoDB C Driver exposes constants for each supported connection option. These constants make it easier to discover connection options, but their string values can be used as well. - -For example, the following calls are equal. - -.. code-block:: c - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_APPNAME "=applicationName"); - uri = mongoc_uri_new ("mongodb://localhost/?appname=applicationName"); - uri = mongoc_uri_new ("mongodb://localhost/?appName=applicationName"); - -Replica Set Example -------------------- - -To describe a connection to a replica set named 'test' with the following mongod hosts: - -* ``db1.example.com`` on port ``27017`` -* ``db2.example.com`` on port ``2500`` - -You would use a connection string that resembles the following. - -.. code-block:: none - - mongodb://db1.example.com,db2.example.com:2500/?replicaSet=test - -SRV Example ------------ - -If you have configured an `SRV record <https://www.ietf.org/rfc/rfc2782.txt>`_ with a name like "_mongodb._tcp.server.example.com" whose records are a list of one or more MongoDB server hostnames, use a connection string like this: - -.. code-block:: c - - uri = mongoc_uri_new ("mongodb+srv://server.example.com/?replicaSet=rs&appName=applicationName"); - -The driver prefixes the service name with "_mongodb._tcp.", then performs a DNS SRV query to resolve the service name to one or more hostnames. If this query succeeds, the driver performs a DNS TXT query on the service name (without the "_mongodb._tcp" prefix) for additional URI options configured as TXT records. - -On Unix, the MongoDB C Driver relies on libresolv to look up SRV and TXT records. If libresolv is unavailable, then using a "mongodb+srv" URI will cause an error. If your libresolv lacks ``res_nsearch`` then the driver will fall back to ``res_search``, which is not thread-safe. - -IPv4 and IPv6 -------------- - -.. include:: includes/ipv4-and-ipv6.txt - -Connection Options ------------------- - -========================================== ================================= ============================================================================================================================================================================================================================================ -Constant Key Description -========================================== ================================= ============================================================================================================================================================================================================================================ -MONGOC_URI_RETRYREADS retryreads If "true" and the server is a MongoDB 3.6+ standalone, replica set, or sharded cluster, the driver safely retries a read that failed due to a network error or replica set failover. -MONGOC_URI_RETRYWRITES retrywrites If "true" and the server is a MongoDB 3.6+ replica set or sharded cluster, the driver safely retries a write that failed due to a network error or replica set failover. Only inserts, updates of single documents, or deletes of single - documents are retried. -MONGOC_URI_APPNAME appname The client application name. This value is used by MongoDB when it logs connection information and profile information, such as slow queries. -MONGOC_URI_TLS tls {true|false}, indicating if TLS must be used. (See also :symbol:`mongoc_client_set_ssl_opts` and :symbol:`mongoc_client_pool_set_ssl_opts`.) -MONGOC_URI_COMPRESSORS compressors Comma separated list of compressors, if any, to use to compress the wire protocol messages. Snappy, zlib, and zstd are optional build time dependencies, and enable the "snappy", "zlib", and "zstd" values respectively. Defaults to empty (no compressors). -MONGOC_URI_CONNECTTIMEOUTMS connecttimeoutms This setting applies to new server connections. It is also used as the socket timeout for server discovery and monitoring operations. The default is 10,000 ms (10 seconds). -MONGOC_URI_SOCKETTIMEOUTMS sockettimeoutms The time in milliseconds to attempt to send or receive on a socket before the attempt times out. The default is 300,000 (5 minutes). -MONGOC_URI_REPLICASET replicaset The name of the Replica Set that the driver should connect to. -MONGOC_URI_ZLIBCOMPRESSIONLEVEL zlibcompressionlevel When the MONGOC_URI_COMPRESSORS includes "zlib" this options configures the zlib compression level, when the zlib compressor is used to compress client data. -========================================== ================================= ============================================================================================================================================================================================================================================ - -Setting any of the \*timeoutMS options above to ``0`` will be interpreted as "use the default value". - -Authentication Options ----------------------- - -========================================== ================================= ========================================================================================================================================================================================================================= -Constant Key Description -========================================== ================================= ========================================================================================================================================================================================================================= -MONGOC_URI_AUTHMECHANISM authmechanism Specifies the mechanism to use when authenticating as the provided user. See :doc:`Authentication <authentication>` for supported values. -MONGOC_URI_AUTHMECHANISMPROPERTIES authmechanismproperties Certain authentication mechanisms have additional options that can be configured. These options should be provided as comma separated option_key:option_value pair and provided as authMechanismProperties. -MONGOC_URI_AUTHSOURCE authsource The authSource defines the database that should be used to authenticate to. It is unnecessary to provide this option the database name is the same as the database used in the URI. -========================================== ================================= ========================================================================================================================================================================================================================= - -Mechanism Properties -~~~~~~~~~~~~~~~~~~~~ - -========================================== ================================= ========================================================================================================================================================================================================================= -Constant Key Description -========================================== ================================= ========================================================================================================================================================================================================================= -MONGOC_URI_CANONICALIZEHOSTNAME canonicalizehostname Use the canonical hostname of the service, rather than its configured alias, when authenticating with Cyrus-SASL Kerberos. -MONGOC_URI_GSSAPISERVICENAME gssapiservicename Use alternative service name. The default is ``mongodb``. -========================================== ================================= ========================================================================================================================================================================================================================= - -TLS Options ------------ - -========================================== ================================= ==================================================================================================================================================================================================================================================================================================================== -Constant Key Description -========================================== ================================= ==================================================================================================================================================================================================================================================================================================================== -MONGOC_URI_TLSCERTIFICATEKEYFILE tlscertificatekeyfile Path to PEM formatted Private Key, with its Public Certificate concatenated at the end. -MONGOC_URI_TLSCERTIFICATEKEYPASSWORD tlscertificatekeypassword The password, if any, to use to unlock encrypted Private Key. -MONGOC_URI_TLSCERTIFICATEAUTHORITYFILE tlscertificateauthorityfile One, or a bundle of, Certificate Authorities whom should be considered to be trusted. -MONGOC_URI_TLSALLOWINVALIDCERTIFICATES tlsallowinvalidcertificates Accept and ignore certificate verification errors (e.g. untrusted issuer, expired, etc etc) -MONGOC_URI_TLSALLOWINVALIDHOSTNAMES tlsallowinvalidhostnames Ignore hostname verification of the certificate (e.g. Man In The Middle, using valid certificate, but issued for another hostname) -MONGOC_URI_TLSINSECURE tlsinsecure {true|false}, indicating if insecure TLS options should be used. Currently this implies MONGOC_URI_TLSALLOWINVALIDCERTIFICATES and MONGOC_URI_TLSALLOWINVALIDHOSTNAMES. -========================================== ================================= ==================================================================================================================================================================================================================================================================================================================== - -See :symbol:`mongoc_ssl_opt_t` for details about these options and about building libmongoc with SSL support. - -Deprecated SSL Options ----------------------- - -The following options have been deprecated and may be removed from future releases of libmongoc. - -========================================== ================================= ======================================= ================================= -Constant Key Deprecated For Key -========================================== ================================= ======================================= ================================= -MONGOC_URI_SSL ssl MONGOC_URI_TLS tls -MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE sslclientcertificatekeyfile MONGOC_URI_TLSCERTIFICATEKEYFILE tlscertificatekeyfile -MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD sslclientcertificatekeypassword MONGOC_URI_TLSCERTIFICATEKEYPASSWORD tlscertificatekeypassword -MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE sslcertificateauthorityfile MONGOC_URI_TLSCERTIFICATEAUTHORITYFILE tlscertificateauthorityfile -MONGOC_URI_SSLALLOWINVALIDCERTIFICATES sslallowinvalidcertificates MONGOC_URI_TLSALLOWINVALIDCERTIFICATES tlsallowinvalidcertificates -MONGOC_URI_SSLALLOWINVALIDHOSTNAMES sslallowinvalidhostnames MONGOC_URI_TLSALLOWINVALIDHOSTNAMES tlsallowinvalidhostnames -========================================== ================================= ======================================= ================================= - - -.. _sdam_uri_options: - -Server Discovery, Monitoring, and Selection Options ---------------------------------------------------- - -Clients in a :symbol:`mongoc_client_pool_t` share a topology scanner that runs on a background thread. The thread wakes every ``heartbeatFrequencyMS`` (default 10 seconds) to scan all MongoDB servers in parallel. Whenever an application operation requires a server that is not known--for example, if there is no known primary and your application attempts an insert--the thread rescans all servers every half-second. In this situation the pooled client waits up to ``serverSelectionTimeoutMS`` (default 30 seconds) for the thread to find a server suitable for the operation, then returns an error with domain ``MONGOC_ERROR_SERVER_SELECTION``. - -Technically, the total time an operation may wait while a pooled client scans the topology is controlled both by ``serverSelectionTimeoutMS`` and ``connectTimeoutMS``. The longest wait occurs if the last scan begins just at the end of the selection timeout, and a slow or down server requires the full connection timeout before the client gives up. - -A non-pooled client is single-threaded. Every ``heartbeatFrequencyMS``, it blocks the next application operation while it does a parallel scan. This scan takes as long as needed to check the slowest server: roughly ``connectTimeoutMS``. Therefore the default ``heartbeatFrequencyMS`` for single-threaded clients is greater than for pooled clients: 60 seconds. - -By default, single-threaded (non-pooled) clients scan only once when an operation requires a server that is not known. If you attempt an insert and there is no known primary, the client checks all servers once trying to find it, then succeeds or returns an error with domain ``MONGOC_ERROR_SERVER_SELECTION``. But if you set ``serverSelectionTryOnce`` to "false", the single-threaded client loops, checking all servers every half-second, until ``serverSelectionTimeoutMS``. - -The total time an operation may wait for a single-threaded client to scan the topology is determined by ``connectTimeoutMS`` in the try-once case, or ``serverSelectionTimeoutMS`` and ``connectTimeoutMS`` if ``serverSelectionTryOnce`` is set "false". - -========================================== ================================= ========================================================================================================================================================================================================================= -Constant Key Description -========================================== ================================= ========================================================================================================================================================================================================================= -MONGOC_URI_HEARTBEATFREQUENCYMS heartbeatfrequencyms The interval between server monitoring checks. Defaults to 10,000ms (10 seconds) in pooled (multi-threaded) mode, 60,000ms (60 seconds) in non-pooled mode (single-threaded). -MONGOC_URI_SERVERSELECTIONTIMEOUTMS serverselectiontimeoutms A timeout in milliseconds to block for server selection before throwing an exception. The default is 30,0000ms (30 seconds). -MONGOC_URI_SERVERSELECTIONTRYONCE serverselectiontryonce If "true", the driver scans the topology exactly once after server selection fails, then either selects a server or returns an error. If it is false, then the driver repeatedly searches for a suitable server for up to ``serverSelectionTimeoutMS`` milliseconds (pausing a half second between attempts). The default for ``serverSelectionTryOnce`` is "false" for pooled clients, otherwise "true". Pooled clients ignore serverSelectionTryOnce; they signal the thread to rescan the topology every half-second until serverSelectionTimeoutMS expires. -MONGOC_URI_SOCKETCHECKINTERVALMS socketcheckintervalms Only applies to single threaded clients. If a socket has not been used within this time, its connection is checked with a quick "isMaster" call before it is used again. Defaults to 5,000ms (5 seconds). -========================================== ================================= ========================================================================================================================================================================================================================= - -Setting any of the \*TimeoutMS options above to ``0`` will be interpreted as "use the default value". - -.. _connection_pool_options: - -Connection Pool Options ------------------------ - -These options govern the behavior of a :symbol:`mongoc_client_pool_t`. They are ignored by a non-pooled :symbol:`mongoc_client_t`. - -========================================== ================================= ========================================================================================================================================================================================================================= -Constant Key Description -========================================== ================================= ========================================================================================================================================================================================================================= -MONGOC_URI_MAXPOOLSIZE maxpoolsize The maximum number of clients created by a :symbol:`mongoc_client_pool_t` total (both in the pool and checked out). The default value is 100. Once it is reached, :symbol:`mongoc_client_pool_pop` blocks until another thread pushes a client. -MONGOC_URI_MINPOOLSIZE minpoolsize Deprecated. This option's behavior does not match its name, and its actual behavior will likely hurt performance. -MONGOC_URI_MAXIDLETIMEMS maxidletimems Not implemented. -MONGOC_URI_WAITQUEUEMULTIPLE waitqueuemultiple Not implemented. -MONGOC_URI_WAITQUEUETIMEOUTMS waitqueuetimeoutms Not implemented. -========================================== ================================= ========================================================================================================================================================================================================================= - -.. _mongoc_uri_t_write_concern_options: - -Write Concern Options ---------------------- - -========================================== ================================= ======================================================================================================================================================================= -Constant Key Description -========================================== ================================= ======================================================================================================================================================================= -MONGOC_URI_W w Determines the write concern (guarantee). Valid values: - - * 0 = The driver will not acknowledge write operations but will pass or handle any network and socket errors that it receives to the client. If you disable write concern but enable the getLastError command’s w option, w overrides the w option. - * 1 = Provides basic acknowledgement of write operations. By specifying 1, you require that a standalone mongod instance, or the primary for replica sets, acknowledge all write operations. For drivers released after the default write concern change, this is the default write concern setting. - * majority = For replica sets, if you specify the special majority value to w option, write operations will only return successfully after a majority of the configured replica set members have acknowledged the write operation. - * n = For replica sets, if you specify a number n greater than 1, operations with this write concern return only after n members of the set have acknowledged the write. If you set n to a number that is greater than the number of available set members or members that hold data, MongoDB will wait, potentially indefinitely, for these members to become available. - * tags = For replica sets, you can specify a tag set to require that all members of the set that have these tags configured return confirmation of the write operation. -MONGOC_URI_WTIMEOUTMS wtimeoutms The time in milliseconds to wait for replication to succeed, as specified in the w option, before timing out. When wtimeoutMS is 0, write operations will never time out. -MONGOC_URI_JOURNAL journal Controls whether write operations will wait until the mongod acknowledges the write operations and commits the data to the on disk journal. - - * true = Enables journal commit acknowledgement write concern. Equivalent to specifying the getLastError command with the j option enabled. - * false = Does not require that mongod commit write operations to the journal before acknowledging the write operation. This is the default option for the journal parameter. -========================================== ================================= ======================================================================================================================================================================= - -.. _mongoc_uri_t_read_concern_options: - -Read Concern Options --------------------- - -========================================== ================================= ========================================================================================================================================================================================================================= -Constant Key Description -========================================== ================================= ========================================================================================================================================================================================================================= -MONGOC_URI_READCONCERNLEVEL readconcernlevel The level of isolation for read operations. If the level is left unspecified, the server default will be used. See `readConcern in the MongoDB Manual <https://docs.mongodb.org/master/reference/readConcern/>`_ for details. -========================================== ================================= ========================================================================================================================================================================================================================= - -.. _mongoc_uri_t_read_prefs_options: - -Read Preference Options ------------------------ - -When connected to a replica set, the driver chooses which member to query using the read preference: - -#. Choose members whose type matches "readPreference". -#. From these, if there are any tags sets configured, choose members matching the first tag set. If there are none, fall back to the next tag set and so on, until some members are chosen or the tag sets are exhausted. -#. From the chosen servers, distribute queries randomly among the server with the fastest round-trip times. These include the server with the fastest time and any whose round-trip time is no more than "localThresholdMS" slower. - -========================================== ================================= ======================================================================================================================================================================= -Constant Key Description -========================================== ================================= ======================================================================================================================================================================= -MONGOC_URI_READPREFERENCE readpreference Specifies the replica set read preference for this connection. This setting overrides any slaveOk value. The read preference values are the following: - - * primary (default) - * primaryPreferred - * secondary - * secondaryPreferred - * nearest -MONGOC_URI_READPREFERENCETAGS readpreferencetags A representation of a tag set. See also :ref:`mongoc-read-prefs-tag-sets`. -MONGOC_URI_LOCALTHRESHOLDMS localthresholdms How far to distribute queries, beyond the server with the fastest round-trip time. By default, only servers within 15ms of the fastest round-trip time receive queries. -MONGOC_URI_MAXSTALENESSSECONDS maxstalenessseconds The maximum replication lag, in wall clock time, that a secondary can suffer and still be eligible. The smallest allowed value for maxStalenessSeconds is 90 seconds. -========================================== ================================= ======================================================================================================================================================================= - -.. note:: - - When connecting to more than one mongos, libmongoc's localThresholdMS applies only to the selection of mongos servers. The threshold for selecting among replica set members in shards is controlled by the `mongos's localThreshold command line option <https://docs.mongodb.com/manual/reference/program/mongos/#cmdoption-localthreshold>`_. - -Legacy Options --------------- - -For historical reasons, the following options are available. They should however not be used. - -========================================== ================================= ======================================================================================================================================================================= -Constant Key Description -========================================== ================================= ======================================================================================================================================================================= -MONGOC_URI_SAFE safe {true|false} Same as w={1|0} -MONGOC_URI_SLAVEOK slaveok When set, same as readPreference=secondaryPreferred -========================================== ================================= ======================================================================================================================================================================= - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_uri_copy - mongoc_uri_destroy - mongoc_uri_get_auth_mechanism - mongoc_uri_get_auth_source - mongoc_uri_get_compressors - mongoc_uri_get_database - mongoc_uri_get_hosts - mongoc_uri_get_mechanism_properties - mongoc_uri_get_option_as_bool - mongoc_uri_get_option_as_int32 - mongoc_uri_get_option_as_int64 - mongoc_uri_get_option_as_utf8 - mongoc_uri_get_options - mongoc_uri_get_password - mongoc_uri_get_read_concern - mongoc_uri_get_read_prefs - mongoc_uri_get_read_prefs_t - mongoc_uri_get_replica_set - mongoc_uri_get_service - mongoc_uri_get_ssl - mongoc_uri_get_string - mongoc_uri_get_tls - mongoc_uri_get_username - mongoc_uri_get_write_concern - mongoc_uri_new - mongoc_uri_new_for_host_port - mongoc_uri_new_with_error - mongoc_uri_option_is_bool - mongoc_uri_option_is_int32 - mongoc_uri_option_is_int64 - mongoc_uri_option_is_utf8 - mongoc_uri_set_auth_mechanism - mongoc_uri_set_auth_source - mongoc_uri_set_compressors - mongoc_uri_set_database - mongoc_uri_set_mechanism_properties - mongoc_uri_set_option_as_bool - mongoc_uri_set_option_as_int32 - mongoc_uri_set_option_as_int64 - mongoc_uri_set_option_as_utf8 - mongoc_uri_set_password - mongoc_uri_set_read_concern - mongoc_uri_set_read_prefs_t - mongoc_uri_set_username - mongoc_uri_set_write_concern - mongoc_uri_unescape - diff --git a/lib/mongoc/libmongoc/doc/mongoc_uri_unescape.rst b/lib/mongoc/libmongoc/doc/mongoc_uri_unescape.rst deleted file mode 100644 index cc79e54144a39d4374fc162082c3a88b9f2decc6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_uri_unescape.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_uri_unescape - -mongoc_uri_unescape() -===================== - -Synopsis --------- - -.. code-block:: c - - char * - mongoc_uri_unescape (const char *escaped_string); - -Parameters ----------- - -* ``escaped_string``: A utf8 encoded string. - -Description ------------ - -Unescapes an URI encoded string. For example, "%40" would become "@". - -Returns -------- - -Returns a newly allocated string that should be freed with :symbol:`bson:bson_free()`. If ``escaped_string`` contains an invalid UTF-8 character or an invalid escape sequence, returns ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_version.rst b/lib/mongoc/libmongoc/doc/mongoc_version.rst deleted file mode 100644 index cabd3c7d14619d7ed15cf6f3a5654403408b411d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_version.rst +++ /dev/null @@ -1,50 +0,0 @@ -:man_page: mongoc_version - -Version Checks -============== - -Conditional compilation based on mongoc version - -Description ------------ - -The following preprocessor macros can be used to perform various checks based on the version of the library you are compiling against. -This may be useful if you only want to enable a feature on a certain version of the library. - -.. parsed-literal:: - - #include <mongoc/mongoc.h> - - #define MONGOC_MAJOR_VERSION (x) - #define MONGOC_MINOR_VERSION (y) - #define MONGOC_MICRO_VERSION (z) - #define MONGOC_VERSION_S "x.y.z" - #define MONGOC_VERSION_HEX ((1 << 24) | (0 << 16) | (0 << 8) | 0) - #define MONGOC_CHECK_VERSION(major, minor, micro) - -Only compile a block on MongoDB C Driver 1.1.0 and newer. - -.. code-block:: c - - #if MONGOC_CHECK_VERSION(1, 1, 0) - static void - do_something (void) - { - } - #endif - -.. only:: html - - Run-Time Version Checks - ----------------------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_check_version - mongoc_get_major_version - mongoc_get_micro_version - mongoc_get_minor_version - mongoc_get_version - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_append.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_append.rst deleted file mode 100644 index 1ba8a88460c2854333a9faff7c887705d55287de..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_append.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_write_concern_append - -mongoc_write_concern_append() -============================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_write_concern_append (mongoc_write_concern_t *write_concern, - bson_t *command); - -Parameters ----------- - -* ``write_concern``: A pointer to a :symbol:`mongoc_write_concern_t`. -* ``command``: A pointer to a :symbol:`bson:bson_t`. - -Description ------------ - -This function appends a write concern to command options. It is useful for appending a write concern to command options before passing them to :symbol:`mongoc_client_write_command_with_opts` or a related function that takes an options document. - -Returns -------- - -Returns true on success. If any arguments are invalid, returns false and logs an error. - -Example -------- - -See the example code for :symbol:`mongoc_client_write_command_with_opts`. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_copy.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_copy.rst deleted file mode 100644 index 27f4604c31a43bbe75055743bea63107c8c683b6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_copy.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_write_concern_copy - -mongoc_write_concern_copy() -=========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_write_concern_t * - mongoc_write_concern_copy (const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Performs a deep copy of ``write_concern``. - -Returns -------- - -Returns a newly allocated copy of ``write_concern`` that should be freed with :symbol:`mongoc_write_concern_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_destroy.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_destroy.rst deleted file mode 100644 index ead9f377ab5f7b136711fbd05fae15f6e89d293c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_destroy.rst +++ /dev/null @@ -1,22 +0,0 @@ -:man_page: mongoc_write_concern_destroy - -mongoc_write_concern_destroy() -============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_write_concern_destroy (mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Frees all resources associated with the write concern structure. Does nothing if ``write_concern`` is NULL. diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_fsync.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_fsync.rst deleted file mode 100644 index df33b67913c46f430050d4af75eb6f4f3a41e2df..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_fsync.rst +++ /dev/null @@ -1,35 +0,0 @@ -:man_page: mongoc_write_concern_get_fsync - -mongoc_write_concern_get_fsync() -================================ - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_write_concern_get_fsync (const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Fetches if an fsync should be performed before returning success on a write operation. - -Returns -------- - -Returns true if ``fsync`` is set as part of the write concern. - -Deprecated ----------- - -.. warning:: - - The ``fsync`` write concern is deprecated; use ``journal`` instead. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_journal.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_journal.rst deleted file mode 100644 index 6030c1d49e594466b29fb61ca1d7b13a48cb40bb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_journal.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_write_concern_get_journal - -mongoc_write_concern_get_journal() -================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_write_concern_get_journal (const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Fetches if the write should be journaled before indicating success. - -Returns -------- - -Returns true if the write should be journaled. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_w.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_w.rst deleted file mode 100644 index a44ab72e05666ae67f74d4dd00a950531bfecd95..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_w.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_write_concern_get_w - -mongoc_write_concern_get_w() -============================ - -Synopsis --------- - -.. code-block:: c - - int32_t - mongoc_write_concern_get_w (const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Fetches the ``w`` parameter of the write concern. - -Returns -------- - -Returns an integer containing the w value. If wmajority is set, this would be MONGOC_WRITE_CONCERN_W_MAJORITY. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wmajority.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wmajority.rst deleted file mode 100644 index 3dc186c5c6524aa8222191a406cf81e396f2d623..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wmajority.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_write_concern_get_wmajority - -mongoc_write_concern_get_wmajority() -==================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_write_concern_get_wmajority ( - const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Fetches if the write should be written to a majority of nodes before indicating success. - -Returns -------- - -Returns true if wmajority is set. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtag.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtag.rst deleted file mode 100644 index 12ec032eb82b15bbc0ac7d7c10b303afb816178a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtag.rst +++ /dev/null @@ -1,28 +0,0 @@ -:man_page: mongoc_write_concern_get_wtag - -mongoc_write_concern_get_wtag() -=============================== - -Synopsis --------- - -.. code-block:: c - - const char * - mongoc_write_concern_get_wtag (const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -A string containing the wtag setting if it has been set. Otherwise returns ``NULL``. - -Returns -------- - -Returns a string which should not be modified or freed, or ``NULL``. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtimeout.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtimeout.rst deleted file mode 100644 index 9dfc0de6c4d9e805de9b780c0fde5507aa2adda6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtimeout.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_write_concern_get_wtimeout - -mongoc_write_concern_get_wtimeout() -=================================== - -Synopsis --------- - -.. code-block:: c - - int32_t - mongoc_write_concern_get_wtimeout (const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Get the timeout in milliseconds that the server should wait before returning with a write concern timeout. - -A value of 0 indicates no write timeout. - -See also: :symbol:`mongoc_write_concern_set_wtimeout` and :symbol:`mongoc_write_concern_get_wtimeout_int64`. - -Returns -------- - -Returns an 32-bit signed integer containing the timeout. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtimeout_int64.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtimeout_int64.rst deleted file mode 100644 index bb115e870cb8f86cfa934e15cf474697c548054f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_get_wtimeout_int64.rst +++ /dev/null @@ -1,32 +0,0 @@ -:man_page: mongoc_write_concern_get_wtimeout_int64 - -mongoc_write_concern_get_wtimeout_int64() -========================================= - -Synopsis --------- - -.. code-block:: c - - int64_t - mongoc_write_concern_get_wtimeout_int64 (const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Get the timeout in milliseconds that the server should wait before returning with a write concern timeout. - -A value of 0 indicates no write timeout. - -See also: :symbol:`mongoc_write_concern_set_wtimeout_int64`. - -Returns -------- - -Returns a 64-bit signed integer containing the timeout. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_acknowledged.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_acknowledged.rst deleted file mode 100644 index 8328e7c3cdcf605633829086fad6832322e1af37..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_acknowledged.rst +++ /dev/null @@ -1,26 +0,0 @@ -:man_page: mongoc_write_concern_is_acknowledged - -mongoc_write_concern_is_acknowledged() -====================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_write_concern_is_acknowledged ( - const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Test if this is an acknowledged or unacknowledged write concern. - -If ``write_concern`` is NULL, returns true. (In other words, writes are acknowledged by default.) - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_default.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_default.rst deleted file mode 100644 index e43f2ca7d52309f590d932b8b70bbeb52daa1750..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_default.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_write_concern_is_default - -mongoc_write_concern_is_default() -================================= - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_write_concern_is_default (mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A pointer to a :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Returns true if ``write_concern`` has not been modified from the default. For example, if no "w" option is set in the MongoDB URI and you have not called :symbol:`mongoc_client_set_write_concern()`, then -:symbol:`mongoc_write_concern_is_default()` is true for the write concern returned by :symbol:`mongoc_client_get_write_concern()`. diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_valid.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_valid.rst deleted file mode 100644 index 9506fdcfcda42196f435b0362dd0c64d37efa0c9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_is_valid.rst +++ /dev/null @@ -1,23 +0,0 @@ -:man_page: mongoc_write_concern_is_valid - -mongoc_write_concern_is_valid() -=============================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_write_concern_is_valid (const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Test if this write concern uses an invalid combination of options. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_journal_is_set.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_journal_is_set.rst deleted file mode 100644 index f024e1744cc3b2830717e874458f7c9c5e83b106..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_journal_is_set.rst +++ /dev/null @@ -1,24 +0,0 @@ -:man_page: mongoc_write_concern_journal_is_set - -mongoc_write_concern_journal_is_set() -===================================== - -Synopsis --------- - -.. code-block:: c - - bool - mongoc_write_concern_journal_is_set ( - const mongoc_write_concern_t *write_concern); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. - -Description ------------ - -Test whether this write concern's "journal" option was explicitly set or uses the default setting. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_new.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_new.rst deleted file mode 100644 index b7e1153ef73a26f1aefcb47552fb0b963e1d2b2a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_new.rst +++ /dev/null @@ -1,18 +0,0 @@ -:man_page: mongoc_write_concern_new - -mongoc_write_concern_new() -========================== - -Synopsis --------- - -.. code-block:: c - - mongoc_write_concern_t * - mongoc_write_concern_new (void); - -Returns -------- - -Creates a newly allocated write concern that can be configured based on user preference. This should be freed with :symbol:`mongoc_write_concern_destroy()` when no longer in use. - diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_fsync.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_fsync.rst deleted file mode 100644 index 15b18537655149e63857e49002ba49732068011c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_fsync.rst +++ /dev/null @@ -1,38 +0,0 @@ -:man_page: mongoc_write_concern_set_fsync - -mongoc_write_concern_set_fsync() -================================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_write_concern_set_fsync (mongoc_write_concern_t *write_concern, - bool fsync_); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``fsync_``: A boolean. - -Description ------------ - -Sets if a fsync must be performed before indicating write success. - -Beginning in version 1.9.0, this function can now alter the write concern after -it has been used in an operation. Previously, using the struct with an operation -would mark it as "frozen" and calling this function would log a warning instead -instead of altering the write concern. - -Deprecated ----------- - -.. warning:: - - The ``fsync`` write concern is deprecated. - -Please use :symbol:`mongoc_write_concern_set_journal()` instead. diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_journal.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_journal.rst deleted file mode 100644 index 3257d355065b104d25374fa56b7fb4a99f0a17c6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_journal.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_write_concern_set_journal - -mongoc_write_concern_set_journal() -================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_write_concern_set_journal (mongoc_write_concern_t *write_concern, - bool journal); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``journal``: A boolean. - -Description ------------ - -Sets if the write must have been journaled before indicating success. - -Beginning in version 1.9.0, this function can now alter the write concern after -it has been used in an operation. Previously, using the struct with an operation -would mark it as "frozen" and calling this function would log a warning instead -instead of altering the write concern. diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_w.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_w.rst deleted file mode 100644 index 756c6561a187fc9f09e94a91246b629271a53004..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_w.rst +++ /dev/null @@ -1,30 +0,0 @@ -:man_page: mongoc_write_concern_set_w - -mongoc_write_concern_set_w() -============================ - -Synopsis --------- - -.. code-block:: c - - void - mongoc_write_concern_set_w (mongoc_write_concern_t *write_concern, int32_t w); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``w``: A positive ``int32_t`` or zero. - -Description ------------ - -Sets the ``w`` value for the write concern. See :symbol:`mongoc_write_concern_t` for more information on this setting. - -Unacknowledged writes are not causally consistent. If you execute a write operation with a :symbol:`mongoc_write_concern_t` on which you have called :symbol:`mongoc_write_concern_set_w` with a value of 0, the write does not participate in causal consistency, even when executed with a :symbol:`mongoc_client_session_t`. - -Beginning in version 1.9.0, this function can now alter the write concern after -it has been used in an operation. Previously, using the struct with an operation -would mark it as "frozen" and calling this function would log a warning instead -instead of altering the write concern. diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wmajority.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wmajority.rst deleted file mode 100644 index 4440a1842b335ac35a61eae003f176afc85954e9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wmajority.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_write_concern_set_wmajority - -mongoc_write_concern_set_wmajority() -==================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_write_concern_set_wmajority (mongoc_write_concern_t *write_concern, - int32_t wtimeout_msec); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``wtimeout_msec``: A positive ``int32_t`` or zero. If you need to set wtimeout with an ``int64_t``, use :symbol:`mongoc_write_concern_set_wtimeout_int64`. - -Description ------------ - -Sets if the write must have been propagated to a majority of nodes before indicating write success. - -The timeout specifies how long, in milliseconds, the server should wait before indicating that the write has failed. This is not the same as a socket timeout. A value of zero may be used to indicate no timeout. - -Beginning in version 1.9.0, this function can now alter the write concern after -it has been used in an operation. Previously, using the struct with an operation -would mark it as "frozen" and calling this function would log a warning instead -instead of altering the write concern. diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtag.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtag.rst deleted file mode 100644 index 849346e4a153faa0056f8e489638578d0f3e2684..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtag.rst +++ /dev/null @@ -1,29 +0,0 @@ -:man_page: mongoc_write_concern_set_wtag - -mongoc_write_concern_set_wtag() -=============================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_write_concern_set_wtag (mongoc_write_concern_t *write_concern, - const char *tag); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``tag``: A string containing the write tag. - -Description ------------ - -Sets the write tag that must be satisfied for the write to indicate success. Write tags are preset write concerns configured on your MongoDB server. See :symbol:`mongoc_write_concern_t` for more information on this setting. - -Beginning in version 1.9.0, this function can now alter the write concern after -it has been used in an operation. Previously, using the struct with an operation -would mark it as "frozen" and calling this function would log a warning instead -instead of altering the write concern. diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtimeout.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtimeout.rst deleted file mode 100644 index 345c7b44bc03943ad7e5731fd32814f20ec3104c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtimeout.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_write_concern_set_wtimeout - -mongoc_write_concern_set_wtimeout() -=================================== - -Synopsis --------- - -.. code-block:: c - - void - mongoc_write_concern_set_wtimeout (mongoc_write_concern_t *write_concern, - int32_t wtimeout_msec); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``wtimeout_msec``: A positive ``int32_t`` or zero. - -Description ------------ - -Set the timeout in milliseconds that the server should wait before returning with a write concern timeout. This is not the same as a socket timeout. A value of zero may be used to indicate no write concern timeout. - -Beginning in version 1.9.0, this function can now alter the write concern after -it has been used in an operation. Previously, using the struct with an operation -would mark it as "frozen" and calling this function would log a warning instead -instead of altering the write concern. - -See also: :symbol:`mongoc_write_concern_get_wtimeout` and :symbol:`mongoc_write_concern_set_wtimeout_int64`. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtimeout_int64.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtimeout_int64.rst deleted file mode 100644 index 93706d0aa68305c7d2a1ff83f861f2a35e44225d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_set_wtimeout_int64.rst +++ /dev/null @@ -1,31 +0,0 @@ -:man_page: mongoc_write_concern_set_wtimeout_int64 - -mongoc_write_concern_set_wtimeout_int64() -========================================= - -Synopsis --------- - -.. code-block:: c - - void - mongoc_write_concern_set_wtimeout_int64 (mongoc_write_concern_t *write_concern, - int64_t wtimeout_msec); - -Parameters ----------- - -* ``write_concern``: A :symbol:`mongoc_write_concern_t`. -* ``wtimeout_msec``: A positive ``int64_t`` or zero. - -Description ------------ - -Set the timeout in milliseconds that the server should wait before returning with a write concern timeout. This is not the same as a socket timeout. A value of zero may be used to indicate no write concern timeout. - -Beginning in version 1.9.0, this function can now alter the write concern after -it has been used in an operation. Previously, using the struct with an operation -would mark it as "frozen" and calling this function would log a warning instead -instead of altering the write concern. - -See also: :symbol:`mongoc_write_concern_get_wtimeout_int64`. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/mongoc_write_concern_t.rst b/lib/mongoc/libmongoc/doc/mongoc_write_concern_t.rst deleted file mode 100644 index 7238555e9563e5794fc41c88b9d3e8a7bb56881c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/mongoc_write_concern_t.rst +++ /dev/null @@ -1,78 +0,0 @@ -:man_page: mongoc_write_concern_t - -mongoc_write_concern_t -====================== - -Write Concern abstraction - -Synopsis --------- - -``mongoc_write_concern_t`` tells the driver what level of acknowledgement to await from the server. The default, MONGOC_WRITE_CONCERN_W_DEFAULT, is right for the great majority of applications. - -You can specify a write concern on connection objects, database objects, collection objects, or per-operation. Data-modifying operations typically use the write concern of the object they operate on, and check the server response for a write concern error or write concern timeout. For example, :symbol:`mongoc_collection_drop_index` uses the collection's write concern, and a write concern error or timeout in the response is considered a failure. - -Exceptions to this principle are the generic command functions: - -* :symbol:`mongoc_client_command` -* :symbol:`mongoc_client_command_simple` -* :symbol:`mongoc_database_command` -* :symbol:`mongoc_database_command_simple` -* :symbol:`mongoc_collection_command` -* :symbol:`mongoc_collection_command_simple` - -These generic command functions do not automatically apply a write concern, and they do not check the server response for a write concern error or write concern timeout. - -See `Write Concern <http://docs.mongodb.org/manual/core/write-concern/>`_ on the MongoDB website for more information. - -Write Concern Levels --------------------- - -Set the write concern level with :symbol:`mongoc_write_concern_set_w`. - -========================================== =============================================================================================================================================================================================================== -MONGOC_WRITE_CONCERN_W_DEFAULT (1) By default, writes block awaiting acknowledgement from MongoDB. Acknowledged write concern allows clients to catch network, duplicate key, and other errors. -MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED (0) With this write concern, MongoDB does not acknowledge the receipt of write operation. Unacknowledged is similar to errors ignored; however, mongoc attempts to receive and handle network errors when possible. -MONGOC_WRITE_CONCERN_W_MAJORITY (majority) Block until a write has been propagated to a majority of the nodes in the replica set. -n Block until a write has been propagated to at least ``n`` nodes in the replica set. -========================================== =============================================================================================================================================================================================================== - -Deprecations ------------- - -The write concern ``MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED`` (value -1) is a deprecated synonym for ``MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED`` (value 0), and will be removed in the next major release. - -:symbol:`mongoc_write_concern_set_fsync` is deprecated. - -.. only:: html - - Functions - --------- - - .. toctree:: - :titlesonly: - :maxdepth: 1 - - mongoc_write_concern_append - mongoc_write_concern_copy - mongoc_write_concern_destroy - mongoc_write_concern_get_fsync - mongoc_write_concern_get_journal - mongoc_write_concern_get_w - mongoc_write_concern_get_wmajority - mongoc_write_concern_get_wtag - mongoc_write_concern_get_wtimeout - mongoc_write_concern_get_wtimeout_int64 - mongoc_write_concern_is_acknowledged - mongoc_write_concern_is_default - mongoc_write_concern_is_valid - mongoc_write_concern_journal_is_set - mongoc_write_concern_new - mongoc_write_concern_set_fsync - mongoc_write_concern_set_journal - mongoc_write_concern_set_w - mongoc_write_concern_set_wmajority - mongoc_write_concern_set_wtag - mongoc_write_concern_set_wtimeout - mongoc_write_concern_set_wtimeout_int64 - diff --git a/lib/mongoc/libmongoc/doc/static/CMakeLists.txt b/lib/mongoc/libmongoc/doc/static/CMakeLists.txt deleted file mode 100644 index c7f15a5119018e012adc6601c7bc382de720f7e8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/static/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -file (GLOB src_libmongoc_doc_static_DIST_pngs - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.png -) - -set_dist_list (src_libmongoc_doc_static_DIST - CMakeLists.txt - ${src_libmongoc_doc_static_DIST_pngs} -) diff --git a/lib/mongoc/libmongoc/doc/static/msvc-add-dependencies-static.png b/lib/mongoc/libmongoc/doc/static/msvc-add-dependencies-static.png deleted file mode 100644 index b70984e5b94463f3292966ed74d2fb4fc7a92343..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/doc/static/msvc-add-dependencies-static.png and /dev/null differ diff --git a/lib/mongoc/libmongoc/doc/static/msvc-add-dependencies.png b/lib/mongoc/libmongoc/doc/static/msvc-add-dependencies.png deleted file mode 100644 index 3fe2c7ae74660fb2096f6442aba0972d42f77aec..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/doc/static/msvc-add-dependencies.png and /dev/null differ diff --git a/lib/mongoc/libmongoc/doc/static/msvc-add-include-directories.png b/lib/mongoc/libmongoc/doc/static/msvc-add-include-directories.png deleted file mode 100644 index afd181272db5fc0d6457868e0c4849628a17a12b..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/doc/static/msvc-add-include-directories.png and /dev/null differ diff --git a/lib/mongoc/libmongoc/doc/static/msvc-create-project.png b/lib/mongoc/libmongoc/doc/static/msvc-create-project.png deleted file mode 100644 index 8c7f749c65be2289f93a0e5ddbc0568fe9b982ab..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/doc/static/msvc-create-project.png and /dev/null differ diff --git a/lib/mongoc/libmongoc/doc/static/msvc-set-path.png b/lib/mongoc/libmongoc/doc/static/msvc-set-path.png deleted file mode 100644 index c135b1a014a61186b2873a9caf80b972d2384c5e..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/doc/static/msvc-set-path.png and /dev/null differ diff --git a/lib/mongoc/libmongoc/doc/static/msvc-switch-architecture.png b/lib/mongoc/libmongoc/doc/static/msvc-switch-architecture.png deleted file mode 100644 index fdc52d1590a958d565d0a1f13aeb17f5bec62e4d..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/doc/static/msvc-switch-architecture.png and /dev/null differ diff --git a/lib/mongoc/libmongoc/doc/tutorial.rst b/lib/mongoc/libmongoc/doc/tutorial.rst deleted file mode 100644 index 16d452c9956ae26ea750eb33197f027ab0f5a359..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/tutorial.rst +++ /dev/null @@ -1,867 +0,0 @@ -:man_page: mongoc_tutorial - -Tutorial -======== - -This guide offers a brief introduction to the MongoDB C Driver. - -For more information on the C API, please refer to the :doc:`api`. - -.. contents:: - :depth: 2 - -Installing ----------- - -For detailed instructions on installing the MongoDB C Driver on a particular platform, please see the :doc:`installation guide <installing>`. - -Starting MongoDB ----------------- - -To run the examples in this tutorial, MongoDB must be installed and running on ``localhost`` on the default port, 27017. To check if it is up and running, connect to it with the MongoDB shell. - -.. code-block:: none - - $ mongo --host localhost --port 27017 - MongoDB shell version: 3.0.6 - connecting to: localhost:27017/test - > - -Include and link libmongoc in your C program --------------------------------------------- - -Include mongoc.h -^^^^^^^^^^^^^^^^ - -All libmongoc's functions and types are available in one header file. Simply include ``mongoc/mongoc.h``: - -.. code-block:: c - - #include <mongoc/mongoc.h> - -CMake -''''' - -The libmongoc installation includes a `CMake config-file package`_, so you can use CMake's `find_package`_ command to import libmongoc's CMake target and link to libmongoc (as a shared library): - -.. literalinclude:: ../examples/cmake/find_package/CMakeLists.txt - :caption: CMakeLists.txt - :start-after: -- sphinx-include-start -- - -You can also use libmongoc as a static library instead: Use the ``mongo::mongoc_static`` CMake target: - -.. literalinclude:: ../examples/cmake/find_package_static/CMakeLists.txt - :start-after: -- sphinx-include-start -- - :emphasize-lines: 2 - -.. _CMake config-file package: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#config-file-packages -.. _find_package: https://cmake.org/cmake/help/latest/command/find_package.html - -pkg-config -'''''''''' - -If you're not using CMake, use `pkg-config`_ on the command line to set header and library paths: - -.. literalinclude:: ../examples/compile-with-pkg-config.sh - :start-after: -- sphinx-include-start -- - -Or to statically link to libmongoc: - -.. literalinclude:: ../examples/compile-with-pkg-config-static.sh - :start-after: -- sphinx-include-start -- - -.. _pkg-config: https://www.freedesktop.org/wiki/Software/pkg-config/ - -Specifying header and include paths manually -'''''''''''''''''''''''''''''''''''''''''''' - -If you aren't using CMake or pkg-config, paths and libraries can be managed manually. - -.. code-block:: none - - $ gcc -o hello_mongoc hello_mongoc.c \ - -I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 \ - -lmongoc-1.0 -lbson-1.0 - $ ./hello_mongoc - { "ok" : 1.000000 } - -For Windows users, the code can be compiled and run with the following commands. (This assumes that the MongoDB C Driver has been installed to ``C:\mongo-c-driver``; change the include directory as needed.) - -.. code-block:: none - - C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 hello_mongoc.c - C:\> hello_mongoc - { "ok" : 1.000000 } - -.. _tutorial_connecting: - -Use libmongoc in a Microsoft Visual Studio Project --------------------------------------------------- - -See the :doc:`libmongoc and Visual Studio guide <visual-studio-guide>`. - -.. _making-a-connection: - -Making a Connection -------------------- - -Access MongoDB with a :symbol:`mongoc_client_t`. It transparently connects to standalone servers, replica sets and sharded clusters on demand. To perform operations on a database or collection, create a :symbol:`mongoc_database_t` or :symbol:`mongoc_collection_t` struct from the :symbol:`mongoc_client_t`. - -At the start of an application, call :symbol:`mongoc_init` before any other libmongoc functions. At the end, call the appropriate destroy function for each collection, database, or client handle, in reverse order from how they were constructed. Call :symbol:`mongoc_cleanup` before exiting. - -The example below establishes a connection to a standalone server on ``localhost``, registers the client application as "connect-example," and performs a simple command. - -More information about database operations can be found in the :ref:`CRUD Operations <tutorial_crud_operations>` and :ref:`Executing Commands <tutorial_executing_commands>` sections. Examples of connecting to replica sets and sharded clusters can be found on the :doc:`Advanced Connections <advanced-connections>` page. - -.. literalinclude:: ../examples/hello_mongoc.c - :caption: hello_mongoc.c - :language: c - :start-after: -- sphinx-include-start -- - -Creating BSON Documents ------------------------ - -Documents are stored in MongoDB's data format, BSON. The C driver uses :doc:`libbson <bson:index>` to create BSON documents. There are several ways to construct them: appending key-value pairs, using BCON, or parsing JSON. - -Appending BSON -^^^^^^^^^^^^^^ - -A BSON document, represented as a :doc:`bson_t <bson:bson_t>` in code, can be constructed one field at a time using libbson's append functions. - -For example, to create a document like this: - -.. code-block:: none - - { - born : ISODate("1906-12-09"), - died : ISODate("1992-01-01"), - name : { - first : "Grace", - last : "Hopper" - }, - languages : [ "MATH-MATIC", "FLOW-MATIC", "COBOL" ], - degrees: [ { degree: "BA", school: "Vassar" }, { degree: "PhD", school: "Yale" } ] - } - -Use the following code: - -.. code-block:: c - - #include <bson/bson.h> - - int - main (int argc, - char *argv[]) - { - struct tm born = { 0 }; - struct tm died = { 0 }; - const char *lang_names[] = {"MATH-MATIC", "FLOW-MATIC", "COBOL"}; - const char *schools[] = {"Vassar", "Yale"}; - const char *degrees[] = {"BA", "PhD"}; - uint32_t i; - char buf[16]; - const char *key; - size_t keylen; - bson_t *document; - bson_t child; - bson_t child2; - char *str; - - document = bson_new (); - - /* - * Append { "born" : ISODate("1906-12-09") } to the document. - * Passing -1 for the length argument tells libbson to calculate the string length. - */ - born.tm_year = 6; /* years are 1900-based */ - born.tm_mon = 11; /* months are 0-based */ - born.tm_mday = 9; - bson_append_date_time (document, "born", -1, mktime (&born) * 1000); - - /* - * Append { "died" : ISODate("1992-01-01") } to the document. - */ - died.tm_year = 92; - died.tm_mon = 0; - died.tm_mday = 1; - - /* - * For convenience, this macro passes length -1 by default. - */ - BSON_APPEND_DATE_TIME (document, "died", mktime (&died) * 1000); - - /* - * Append a subdocument. - */ - BSON_APPEND_DOCUMENT_BEGIN (document, "name", &child); - BSON_APPEND_UTF8 (&child, "first", "Grace"); - BSON_APPEND_UTF8 (&child, "last", "Hopper"); - bson_append_document_end (document, &child); - - /* - * Append array of strings. Generate keys "0", "1", "2". - */ - BSON_APPEND_ARRAY_BEGIN (document, "languages", &child); - for (i = 0; i < sizeof lang_names / sizeof (char *); ++i) { - keylen = bson_uint32_to_string (i, &key, buf, sizeof buf); - bson_append_utf8 (&child, key, (int) keylen, lang_names[i], -1); - } - bson_append_array_end (document, &child); - - /* - * Array of subdocuments: - * degrees: [ { degree: "BA", school: "Vassar" }, ... ] - */ - BSON_APPEND_ARRAY_BEGIN (document, "degrees", &child); - for (i = 0; i < sizeof degrees / sizeof (char *); ++i) { - keylen = bson_uint32_to_string (i, &key, buf, sizeof buf); - bson_append_document_begin (&child, key, (int) keylen, &child2); - BSON_APPEND_UTF8 (&child2, "degree", degrees[i]); - BSON_APPEND_UTF8 (&child2, "school", schools[i]); - bson_append_document_end (&child, &child2); - } - bson_append_array_end (document, &child); - - /* - * Print the document as a JSON string. - */ - str = bson_as_canonical_extended_json (document, NULL); - printf ("%s\n", str); - bson_free (str); - - /* - * Clean up allocated bson documents. - */ - bson_destroy (document); - return 0; - } - -See the :doc:`libbson documentation <bson:bson_t>` for all of the types that can be appended to a :symbol:`bson:bson_t`. - -Using BCON -^^^^^^^^^^ - -*BSON C Object Notation*, BCON for short, is an alternative way of constructing BSON documents in a manner closer to the intended format. It has less type-safety than BSON's append functions but results in less code. - -.. code-block:: c - - #include <bson/bson.h> - - int - main (int argc, - char *argv[]) - { - struct tm born = { 0 }; - struct tm died = { 0 }; - bson_t *document; - char *str; - - born.tm_year = 6; - born.tm_mon = 11; - born.tm_mday = 9; - - died.tm_year = 92; - died.tm_mon = 0; - died.tm_mday = 1; - - document = BCON_NEW ( - "born", BCON_DATE_TIME (mktime (&born) * 1000), - "died", BCON_DATE_TIME (mktime (&died) * 1000), - "name", "{", - "first", BCON_UTF8 ("Grace"), - "last", BCON_UTF8 ("Hopper"), - "}", - "languages", "[", - BCON_UTF8 ("MATH-MATIC"), - BCON_UTF8 ("FLOW-MATIC"), - BCON_UTF8 ("COBOL"), - "]", - "degrees", "[", - "{", "degree", BCON_UTF8 ("BA"), "school", BCON_UTF8 ("Vassar"), "}", - "{", "degree", BCON_UTF8 ("PhD"), "school", BCON_UTF8 ("Yale"), "}", - "]"); - - /* - * Print the document as a JSON string. - */ - str = bson_as_canonical_extended_json (document, NULL); - printf ("%s\n", str); - bson_free (str); - - /* - * Clean up allocated bson documents. - */ - bson_destroy (document); - return 0; - } - -Notice that BCON can create arrays, subdocuments and arbitrary fields. - -Creating BSON from JSON -^^^^^^^^^^^^^^^^^^^^^^^ - -For *single* documents, BSON can be created from JSON strings via :doc:`bson_new_from_json <bson:bson_new_from_json>`. - -.. code-block:: c - - #include <bson/bson.h> - - int - main (int argc, - char *argv[]) - { - bson_error_t error; - bson_t *bson; - char *string; - - const char *json = "{\"name\": {\"first\":\"Grace\", \"last\":\"Hopper\"}}"; - bson = bson_new_from_json ((const uint8_t *)json, -1, &error); - - if (!bson) { - fprintf (stderr, "%s\n", error.message); - return EXIT_FAILURE; - } - - string = bson_as_canonical_extended_json (bson, NULL); - printf ("%s\n", string); - bson_free (string); - - return 0; - } - -To initialize BSON from a sequence of JSON documents, use :doc:`bson_json_reader_t <bson:bson_json_reader_t>`. - -.. _tutorial_crud_operations: - -Basic CRUD Operations ---------------------- - -This section demonstrates the basics of using the C Driver to interact with MongoDB. - -Inserting a Document -^^^^^^^^^^^^^^^^^^^^ - -To insert documents into a collection, first obtain a handle to a ``mongoc_collection_t`` via a ``mongoc_client_t``. Then, use :symbol:`mongoc_collection_insert_one` to add BSON documents to the collection. This example inserts into the database "mydb" and collection "mycoll". - -When finished, ensure that allocated structures are freed by using their respective destroy functions. - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - int - main (int argc, - char *argv[]) - { - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - bson_oid_t oid; - bson_t *doc; - - mongoc_init (); - - client = mongoc_client_new ("mongodb://localhost:27017/?appname=insert-example"); - collection = mongoc_client_get_collection (client, "mydb", "mycoll"); - - doc = bson_new (); - bson_oid_init (&oid, NULL); - BSON_APPEND_OID (doc, "_id", &oid); - BSON_APPEND_UTF8 (doc, "hello", "world"); - - if (!mongoc_collection_insert_one ( - collection, doc, NULL, NULL, &error)) { - fprintf (stderr, "%s\n", error.message); - } - - bson_destroy (doc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return 0; - } - -Compile the code and run it: - -.. code-block:: none - - $ gcc -o insert insert.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./insert - -On Windows: - -.. code-block:: none - - C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 insert.c - C:\> insert - -To verify that the insert succeeded, connect with the MongoDB shell. - -.. code-block:: none - - $ mongo - MongoDB shell version: 3.0.6 - connecting to: test - > use mydb - switched to db mydb - > db.mycoll.find() - { "_id" : ObjectId("55ef43766cb5f36a3bae6ee4"), "hello" : "world" } - > - -.. _tutorial_find: - -Finding a Document -^^^^^^^^^^^^^^^^^^ - -To query a MongoDB collection with the C driver, use the function :doc:`mongoc_collection_find_with_opts() <mongoc_collection_find_with_opts>`. This returns a :doc:`cursor <mongoc_cursor_t>` to the matching documents. The following examples iterate through the result cursors and print the matches to ``stdout`` as JSON strings. - -Use a document as a query specifier; for example, - -.. code-block:: none - - { "color" : "red" } - -will match any document with a field named "color" with value "red". An empty document ``{}`` can be used to match all documents. - -This first example uses an empty query specifier to find all documents in the database "mydb" and collection "mycoll". - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - int - main (int argc, char *argv[]) - { - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t *query; - char *str; - - mongoc_init (); - - client = - mongoc_client_new ("mongodb://localhost:27017/?appname=find-example"); - collection = mongoc_client_get_collection (client, "mydb", "mycoll"); - query = bson_new (); - cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - printf ("%s\n", str); - bson_free (str); - } - - bson_destroy (query); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return 0; - } - -Compile the code and run it: - -.. code-block:: none - - $ gcc -o find find.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./find - { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" } - -On Windows: - -.. code-block:: none - - C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find.c - C:\> find - { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" } - -To look for a specific document, add a specifier to ``query``. This example adds a call to ``BSON_APPEND_UTF8()`` to look for all documents matching ``{"hello" : "world"}``. - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - int - main (int argc, char *argv[]) - { - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t *query; - char *str; - - mongoc_init (); - - client = mongoc_client_new ( - "mongodb://localhost:27017/?appname=find-specific-example"); - collection = mongoc_client_get_collection (client, "mydb", "mycoll"); - query = bson_new (); - BSON_APPEND_UTF8 (query, "hello", "world"); - - cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - printf ("%s\n", str); - bson_free (str); - } - - bson_destroy (query); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return 0; - } - -.. code-block:: none - - $ gcc -o find-specific find-specific.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./find-specific - { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" } - -.. code-block:: none - - C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find-specific.c - C:\> find-specific - { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" } - -Updating a Document -^^^^^^^^^^^^^^^^^^^ - -This code snippet gives an example of using :doc:`mongoc_collection_update_one() <mongoc_collection_update_one>` to update the fields of a document. - -Using the "mydb" database, the following example inserts an example document into the "mycoll" collection. Then, using its ``_id`` field, the document is updated with different values and a new field. - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - int - main (int argc, char *argv[]) - { - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - bson_oid_t oid; - bson_t *doc = NULL; - bson_t *update = NULL; - bson_t *query = NULL; - - mongoc_init (); - - client = - mongoc_client_new ("mongodb://localhost:27017/?appname=update-example"); - collection = mongoc_client_get_collection (client, "mydb", "mycoll"); - - bson_oid_init (&oid, NULL); - doc = BCON_NEW ("_id", BCON_OID (&oid), "key", BCON_UTF8 ("old_value")); - - if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) { - fprintf (stderr, "%s\n", error.message); - goto fail; - } - - query = BCON_NEW ("_id", BCON_OID (&oid)); - update = BCON_NEW ("$set", - "{", - "key", - BCON_UTF8 ("new_value"), - "updated", - BCON_BOOL (true), - "}"); - - if (!mongoc_collection_update_one ( - collection, query, update, NULL, NULL, &error)) { - fprintf (stderr, "%s\n", error.message); - goto fail; - } - - fail: - if (doc) - bson_destroy (doc); - if (query) - bson_destroy (query); - if (update) - bson_destroy (update); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return 0; - } - -Compile the code and run it: - -.. code-block:: none - - $ gcc -o update update.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./update - -On Windows: - -.. code-block:: none - - C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 update.c - C:\> update - { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" } - -To verify that the update succeeded, connect with the MongoDB shell. - -.. code-block:: none - - $ mongo - MongoDB shell version: 3.0.6 - connecting to: test - > use mydb - switched to db mydb - > db.mycoll.find({"updated" : true}) - { "_id" : ObjectId("55ef549236fe322f9490e17b"), "updated" : true, "key" : "new_value" } - > - -Deleting a Document -^^^^^^^^^^^^^^^^^^^ - -This example illustrates the use of :symbol:`mongoc_collection_delete_one()` to delete a document. - -The following code inserts a sample document into the database "mydb" and collection "mycoll". Then, it deletes all documents matching ``{"hello" : "world"}``. - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - int - main (int argc, char *argv[]) - { - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - bson_oid_t oid; - bson_t *doc; - - mongoc_init (); - - client = - mongoc_client_new ("mongodb://localhost:27017/?appname=delete-example"); - collection = mongoc_client_get_collection (client, "test", "test"); - - doc = bson_new (); - bson_oid_init (&oid, NULL); - BSON_APPEND_OID (doc, "_id", &oid); - BSON_APPEND_UTF8 (doc, "hello", "world"); - - if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) { - fprintf (stderr, "Insert failed: %s\n", error.message); - } - - bson_destroy (doc); - - doc = bson_new (); - BSON_APPEND_OID (doc, "_id", &oid); - - if (!mongoc_collection_delete_one ( - collection, doc, NULL, NULL, &error)) { - fprintf (stderr, "Delete failed: %s\n", error.message); - } - - bson_destroy (doc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return 0; - } - -Compile the code and run it: - -.. code-block:: none - - $ gcc -o delete delete.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./delete - -On Windows: - -.. code-block:: none - - C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 delete.c - C:\> delete - -Use the MongoDB shell to prove that the documents have been removed successfully. - -.. code-block:: none - - $ mongo - MongoDB shell version: 3.0.6 - connecting to: test - > use mydb - switched to db mydb - > db.mycoll.count({"hello" : "world"}) - 0 - > - -Counting Documents -^^^^^^^^^^^^^^^^^^ - -Counting the number of documents in a MongoDB collection is similar to performing a :ref:`find operation <tutorial_find>`. This example counts the number of documents matching ``{"hello" : "world"}`` in the database "mydb" and collection "mycoll". - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - int - main (int argc, char *argv[]) - { - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - bson_t *doc; - int64_t count; - - mongoc_init (); - - client = - mongoc_client_new ("mongodb://localhost:27017/?appname=count-example"); - collection = mongoc_client_get_collection (client, "mydb", "mycoll"); - doc = bson_new_from_json ( - (const uint8_t *) "{\"hello\" : \"world\"}", -1, &error); - - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); - - if (count < 0) { - fprintf (stderr, "%s\n", error.message); - } else { - printf ("%" PRId64 "\n", count); - } - - bson_destroy (doc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return 0; - } - -Compile the code and run it: - -.. code-block:: none - - $ gcc -o count count.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./count - 1 - -On Windows: - -.. code-block:: none - - C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 count.c - C:\> count - 1 - -.. _tutorial_executing_commands: - -Executing Commands ------------------- - -The driver provides helper functions for executing MongoDB commands on client, database and collection structures. These functions return :doc:`cursors <mongoc_cursor_t>`; the ``_simple`` variants return booleans indicating success or failure. - -This example executes the `collStats <http://docs.mongodb.org/manual/reference/command/collStats/>`_ command against the collection "mycoll" in database "mydb". - -.. code-block:: c - - #include <bson/bson.h> - #include <mongoc/mongoc.h> - #include <stdio.h> - - int - main (int argc, char *argv[]) - { - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - bson_t *command; - bson_t reply; - char *str; - - mongoc_init (); - - client = mongoc_client_new ( - "mongodb://localhost:27017/?appname=executing-example"); - collection = mongoc_client_get_collection (client, "mydb", "mycoll"); - - command = BCON_NEW ("collStats", BCON_UTF8 ("mycoll")); - if (mongoc_collection_command_simple ( - collection, command, NULL, &reply, &error)) { - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - } else { - fprintf (stderr, "Failed to run command: %s\n", error.message); - } - - bson_destroy (command); - bson_destroy (&reply); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return 0; - } - -Compile the code and run it: - -.. code-block:: none - - $ gcc -o executing executing.c $(pkg-config --cflags --libs libmongoc-1.0) - $ ./executing - { "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192, - "lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1, - "indexDetails" : { }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 } - -On Windows: - -.. code-block:: none - - C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 executing.c - C:\> executing - { "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192, - "lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1, - "indexDetails" : { }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 } - -Threading ---------- - -The MongoDB C Driver is thread-unaware in the vast majority of its operations. This means it is up to the programmer to guarantee thread-safety. - -However, :symbol:`mongoc_client_pool_t` is thread-safe and is used to fetch a ``mongoc_client_t`` in a thread-safe manner. After retrieving a client from the pool, the client structure should be considered owned by the calling thread. When the thread is finished, the client should be placed back into the pool. - -.. literalinclude:: ../examples/example-pool.c - :language: c - :caption: example-pool.c - -Next Steps ----------- - -To find information on advanced topics, browse the rest of the :doc:`C driver guide <index>` or the `official MongoDB documentation <https://docs.mongodb.org>`_. - -For help with common issues, consult the :doc:`Troubleshooting <basic-troubleshooting>` page. To report a bug or request a new feature, follow :ref:`these instructions <basic-troubleshooting_file_bug>`. - diff --git a/lib/mongoc/libmongoc/doc/using_client_side_encryption.rst b/lib/mongoc/libmongoc/doc/using_client_side_encryption.rst deleted file mode 100644 index 51afc40888864f965ee846ba02e33d40bcdb3d1a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/using_client_side_encryption.rst +++ /dev/null @@ -1,6 +0,0 @@ -:man-page: using_client_side_encryption - -Using Client-Side Field Level Encryption -======================================== - -More information coming soon. Sit tight. \ No newline at end of file diff --git a/lib/mongoc/libmongoc/doc/visual-studio-guide.rst b/lib/mongoc/libmongoc/doc/visual-studio-guide.rst deleted file mode 100644 index d94b8b5e72ab2e9e7917df61a32eaf5358690939..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/doc/visual-studio-guide.rst +++ /dev/null @@ -1,88 +0,0 @@ -Using libmongoc in a Microsoft Visual Studio project -==================================================== - -:ref:`Download and install libmongoc on your system <build-on-windows>`, then open Visual Studio, select "File |rarrow| New |rarrow| Project...", and create a new Win32 Console Application. - -.. image:: - static/msvc-create-project.png - -Remember to switch the platform from 32-bit to 64-bit: - -.. image:: - static/msvc-switch-architecture.png - -Right-click on your console application in the Solution Explorer and select "Properties". Choose to edit properties for "All Configurations", expand the "C/C++" options and choose "General". Add to the "Additional Include Directories" these paths: - -.. code-block:: text - - C:\mongo-c-driver\include\libbson-1.0 - C:\mongo-c-driver\include\libmongoc-1.0 - -.. image:: - static/msvc-add-include-directories.png - -(If you chose a different ``CMAKE_INSTALL_PREFIX`` :ref:`when you ran CMake <build-on-windows>`, your include paths will be different.) - -Also in the Properties dialog, expand the "Linker" options and choose "Input", and add to the "Additional Dependencies" these libraries: - -.. code-block:: text - - C:\mongo-c-driver\lib\bson-1.0.lib - C:\mongo-c-driver\lib\mongoc-1.0.lib - -.. image:: - static/msvc-add-dependencies.png - -Adding these libraries as dependencies provides linker symbols to build your application, but to actually run it, libbson's and libmongoc's DLLs must be in your executable path. Select "Debugging" in the Properties dialog, and set the "Environment" option to: - -.. code-block:: text - - PATH=c:/mongo-c-driver/bin - -.. image:: - static/msvc-set-path.png - -Finally, include "mongoc/mongoc.h" in your project's "stdafx.h": - -.. code-block:: c - - #include <mongoc/mongoc.h> - -Static linking --------------- - -Following the instructions above, you have dynamically linked your application to the libbson and libmongoc DLLs. This is usually the right choice. If you want to link statically instead, update your "Additional Dependencies" list by removing ``bson-1.0.lib`` and ``mongoc-1.0.lib`` and replacing them with these libraries: - -.. code-block:: text - - C:\mongo-c-driver\lib\bson-static-1.0.lib - C:\mongo-c-driver\lib\mongoc-static-1.0.lib - ws2_32.lib - Secur32.lib - Crypt32.lib - BCrypt.lib - -.. image:: - static/msvc-add-dependencies-static.png - -(To explain the purpose of each library: ``bson-static-1.0.lib`` and ``mongoc-static-1.0.lib`` are static archives of the driver code. The socket library ``ws2_32`` is required by libbson, which uses the socket routine ``gethostname`` to help guarantee ObjectId uniqueness. The ``BCrypt`` library is used by libmongoc for SSL connections to MongoDB, and ``Secur32`` and ``Crypt32`` are required for enterprise authentication methods like Kerberos.) - -Finally, define two preprocessor symbols before including ``mongoc/mongoc.h`` in your ``stdafx.h``: - -.. code-block:: c - - #define BSON_STATIC - #define MONGOC_STATIC - #include <mongoc/mongoc.h> - -Making these changes to your project is only required for static linking; for most people, the dynamic-linking instructions above are preferred. - -Next Steps ----------- - -Now you can build and debug applications in Visual Studio that use libbson and libmongoc. Proceed to :ref:`making-a-connection` in the tutorial to learn how connect to MongoDB and perform operations. - -.. turn "rarrow" above into right-arrow with no spaces around it - -.. |rarrow| unicode:: U+2192 - :trim: diff --git a/lib/mongoc/libmongoc/examples/.gitignore b/lib/mongoc/libmongoc/examples/.gitignore deleted file mode 100644 index aa8e87261fd6b3e505e246b88aa569c54561a4ef..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -cmake_install.cmake -hello_mongoc -build diff --git a/lib/mongoc/libmongoc/examples/CMakeLists.txt b/lib/mongoc/libmongoc/examples/CMakeLists.txt deleted file mode 100644 index 02f9e7574103e99c04cc8f57b3d19d70d9815c6b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -file (GLOB_RECURSE src_libmongoc_examples_DIST_cs - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.c -) -file (GLOB_RECURSE src_libmongoc_examples_DIST_shs - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.sh -) - -set_dist_list (src_libmongoc_examples_DIST - CMakeLists.txt - cmake/find_package/CMakeLists.txt - cmake/find_package_static/CMakeLists.txt - ${src_libmongoc_examples_DIST_cs} - ${src_libmongoc_examples_DIST_shs} -) diff --git a/lib/mongoc/libmongoc/examples/aggregation/aggregation1.c b/lib/mongoc/libmongoc/examples/aggregation/aggregation1.c deleted file mode 100644 index ad686293b70c1ffff30c0a302e6ee9ea8e3a26e1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/aggregation/aggregation1.c +++ /dev/null @@ -1,95 +0,0 @@ -#include <mongoc/mongoc.h> -#include <stdio.h> - -static void -print_pipeline (mongoc_collection_t *collection) -{ - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - bson_t *pipeline; - char *str; - - pipeline = BCON_NEW ("pipeline", - "[", - "{", - "$group", - "{", - "_id", - "$state", - "total_pop", - "{", - "$sum", - "$pop", - "}", - "}", - "}", - "{", - "$match", - "{", - "total_pop", - "{", - "$gte", - BCON_INT32 (10000000), - "}", - "}", - "}", - "]"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - printf ("%s\n", str); - bson_free (str); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "Cursor Failure: %s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - bson_destroy (pipeline); -} - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - const char *uri_string = - "mongodb://localhost:27017/?appname=aggregation-example"; - mongoc_uri_t *uri; - bson_error_t error; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "test", "zipcodes"); - - print_pipeline (collection); - - mongoc_uri_destroy (uri); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/basic_aggregation/basic-aggregation.c b/lib/mongoc/libmongoc/examples/basic_aggregation/basic-aggregation.c deleted file mode 100644 index 0e2cad07a2b86f2306b4b26469c5cc27d5f1cedd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/basic_aggregation/basic-aggregation.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2016 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 <mongoc/mongoc.h> -#include <stdio.h> - - -#include "constants.c" - -#include "../doc-common-insert.c" -#include "distinct.c" -#include "map-reduce-basic.c" -#include "map-reduce-advanced.c" - - -int -main (int argc, char *argv[]) -{ - mongoc_database_t *database = NULL; - mongoc_client_t *client = NULL; - mongoc_collection_t *collection = NULL; - mongoc_uri_t *uri = NULL; - bson_error_t error; - char *host_and_port = NULL; - int exit_code = EXIT_FAILURE; - - if (argc != 2) { - fprintf (stderr, "usage: %s CONNECTION-STRING\n", argv[0]); - fprintf (stderr, - "the connection string can be of the following forms:\n"); - fprintf (stderr, "localhost\t\t\t\tlocal machine\n"); - fprintf (stderr, "localhost:27018\t\t\t\tlocal machine on port 27018\n"); - fprintf (stderr, - "mongodb://user:pass@localhost:27017\t" - "local machine on port 27017, and authenticate with username " - "user and password pass\n"); - return exit_code; - } - - mongoc_init (); - - if (strncmp (argv[1], "mongodb://", 10) == 0) { - host_and_port = bson_strdup (argv[1]); - } else { - host_and_port = bson_strdup_printf ("mongodb://%s", argv[1]); - } - - uri = mongoc_uri_new_with_error (host_and_port, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - host_and_port, - error.message); - goto cleanup; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - goto cleanup; - } - - mongoc_client_set_error_api (client, 2); - database = mongoc_client_get_database (client, "test"); - collection = mongoc_database_get_collection (database, COLLECTION_NAME); - - printf ("Inserting data\n"); - if (!insert_data (collection)) { - goto cleanup; - } - - printf ("distinct\n"); - if (!distinct (database)) { - goto cleanup; - } - - printf ("map reduce\n"); - if (!map_reduce_basic (database)) { - goto cleanup; - } - - printf ("more complicated map reduce\n"); - if (!map_reduce_advanced (database)) { - goto cleanup; - } - - exit_code = EXIT_SUCCESS; - -cleanup: - if (collection) { - mongoc_collection_destroy (collection); - } - - if (database) { - mongoc_database_destroy (database); - } - - if (client) { - mongoc_client_destroy (client); - } - - if (uri) { - mongoc_uri_destroy (uri); - } - - if (host_and_port) { - bson_free (host_and_port); - } - - mongoc_cleanup (); - return exit_code; -} diff --git a/lib/mongoc/libmongoc/examples/basic_aggregation/constants.c b/lib/mongoc/libmongoc/examples/basic_aggregation/constants.c deleted file mode 100644 index cd94fa838fe61023ba14a89a199e6e687cd8f06a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/basic_aggregation/constants.c +++ /dev/null @@ -1,22 +0,0 @@ -const char *const COLLECTION_NAME = "things"; - -/* Our map function just emits a single (key, 1) pair for each tag - in the array: */ -const char *const MAPPER = "function () {" - "this.tags.forEach(function(z) {" - "emit(z, 1);" - "});" - "}"; - -/* The reduce function sums over all of the emitted values for a - given key: */ -const char *const REDUCER = "function (key, values) {" - "var total = 0;" - "for (var i = 0; i < values.length; i++) {" - "total += values[i];" - "}" - "return total;" - "}"; -/* Note We can't just return values.length as the reduce function - might be called iteratively on the results of other reduce - steps. */ diff --git a/lib/mongoc/libmongoc/examples/basic_aggregation/distinct.c b/lib/mongoc/libmongoc/examples/basic_aggregation/distinct.c deleted file mode 100644 index 663a7733cb5852bc2d51c3485d36830c28073a83..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/basic_aggregation/distinct.c +++ /dev/null @@ -1,51 +0,0 @@ -bool -distinct (mongoc_database_t *database) -{ - bson_t *command; - bson_t reply; - bson_error_t error; - bool res; - bson_iter_t iter; - bson_iter_t array_iter; - double val; - - command = BCON_NEW ("distinct", - BCON_UTF8 (COLLECTION_NAME), - "key", - BCON_UTF8 ("x"), - "query", - "{", - "x", - "{", - "$gt", - BCON_DOUBLE (1.0), - "}", - "}"); - res = - mongoc_database_command_simple (database, command, NULL, &reply, &error); - if (!res) { - fprintf (stderr, "Error with distinct: %s\n", error.message); - goto cleanup; - } - - /* Do something with reply (in this case iterate through the values) */ - if (!(bson_iter_init_find (&iter, &reply, "values") && - BSON_ITER_HOLDS_ARRAY (&iter) && - bson_iter_recurse (&iter, &array_iter))) { - fprintf (stderr, "Couldn't extract \"values\" field from response\n"); - goto cleanup; - } - - while (bson_iter_next (&array_iter)) { - if (BSON_ITER_HOLDS_DOUBLE (&array_iter)) { - val = bson_iter_double (&array_iter); - printf ("Next double: %f\n", val); - } - } - -cleanup: - /* cleanup */ - bson_destroy (command); - bson_destroy (&reply); - return res; -} diff --git a/lib/mongoc/libmongoc/examples/basic_aggregation/map-reduce-advanced.c b/lib/mongoc/libmongoc/examples/basic_aggregation/map-reduce-advanced.c deleted file mode 100644 index 145fb7a4d3caddd2ee93ae6fb9ef34b1bc6a331f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/basic_aggregation/map-reduce-advanced.c +++ /dev/null @@ -1,47 +0,0 @@ -bool -map_reduce_advanced (mongoc_database_t *database) -{ - bson_t *command; - bson_error_t error; - bool res = true; - mongoc_cursor_t *cursor; - mongoc_read_prefs_t *read_pref; - const bson_t *doc; - - /* Construct the mapReduce command */ - /* Other arguments can also be specified here, like "query" or "limit" - and so on */ - - /* Read the results inline from a secondary replica */ - command = BCON_NEW ("mapReduce", - BCON_UTF8 (COLLECTION_NAME), - "map", - BCON_CODE (MAPPER), - "reduce", - BCON_CODE (REDUCER), - "out", - "{", - "inline", - "1", - "}"); - - read_pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - cursor = mongoc_database_command ( - database, MONGOC_QUERY_NONE, 0, 0, 0, command, NULL, read_pref); - - /* Do something with the results */ - while (mongoc_cursor_next (cursor, &doc)) { - print_res (doc); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "ERROR: %s\n", error.message); - res = false; - } - - mongoc_cursor_destroy (cursor); - mongoc_read_prefs_destroy (read_pref); - bson_destroy (command); - - return res; -} diff --git a/lib/mongoc/libmongoc/examples/basic_aggregation/map-reduce-basic.c b/lib/mongoc/libmongoc/examples/basic_aggregation/map-reduce-basic.c deleted file mode 100644 index 78a655b5bc2f57bff8ebb0d1a8d93ffb67c62d47..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/basic_aggregation/map-reduce-basic.c +++ /dev/null @@ -1,71 +0,0 @@ -bool -map_reduce_basic (mongoc_database_t *database) -{ - bson_t reply; - bson_t *command; - bool res; - bson_error_t error; - mongoc_cursor_t *cursor; - const bson_t *doc; - - bool query_done = false; - - const char *out_collection_name = "outCollection"; - mongoc_collection_t *out_collection; - - /* Empty find query */ - bson_t find_query = BSON_INITIALIZER; - - /* Construct the mapReduce command */ - - /* Other arguments can also be specified here, like "query" or - "limit" and so on */ - command = BCON_NEW ("mapReduce", - BCON_UTF8 (COLLECTION_NAME), - "map", - BCON_CODE (MAPPER), - "reduce", - BCON_CODE (REDUCER), - "out", - BCON_UTF8 (out_collection_name)); - res = - mongoc_database_command_simple (database, command, NULL, &reply, &error); - - if (!res) { - fprintf (stderr, "MapReduce failed: %s\n", error.message); - goto cleanup; - } - - /* Do something with the reply (it doesn't contain the mapReduce results) */ - print_res (&reply); - - /* Now we'll query outCollection to see what the results are */ - out_collection = - mongoc_database_get_collection (database, out_collection_name); - cursor = mongoc_collection_find_with_opts ( - out_collection, &find_query, NULL, NULL); - query_done = true; - - /* Do something with the results */ - while (mongoc_cursor_next (cursor, &doc)) { - print_res (doc); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "ERROR: %s\n", error.message); - res = false; - goto cleanup; - } - -cleanup: - /* cleanup */ - if (query_done) { - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (out_collection); - } - - bson_destroy (&reply); - bson_destroy (command); - - return res; -} diff --git a/lib/mongoc/libmongoc/examples/bulk/bulk-collation.c b/lib/mongoc/libmongoc/examples/bulk/bulk-collation.c deleted file mode 100644 index 2900f019641cd0db492e7a150f1a1dbd2447f039..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/bulk/bulk-collation.c +++ /dev/null @@ -1,97 +0,0 @@ -#include <mongoc/mongoc.h> -#include <stdio.h> - -static void -bulk_collation (mongoc_collection_t *collection) -{ - mongoc_bulk_operation_t *bulk; - bson_t *opts; - bson_t *doc; - bson_t *selector; - bson_t *update; - bson_error_t error; - bson_t reply; - char *str; - uint32_t ret; - - /* insert {_id: "one"} and {_id: "One"} */ - bulk = mongoc_collection_create_bulk_operation_with_opts ( - collection, NULL); - doc = BCON_NEW ("_id", BCON_UTF8 ("one")); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - doc = BCON_NEW ("_id", BCON_UTF8 ("One")); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - /* "One" normally sorts before "one"; make "one" come first */ - opts = BCON_NEW ("collation", - "{", - "locale", - BCON_UTF8 ("en_US"), - "caseFirst", - BCON_UTF8 ("lower"), - "}"); - - /* set x=1 on the document with _id "One", which now sorts after "one" */ - update = BCON_NEW ("$set", "{", "x", BCON_INT64 (1), "}"); - selector = BCON_NEW ("_id", "{", "$gt", BCON_UTF8 ("one"), "}"); - mongoc_bulk_operation_update_one_with_opts ( - bulk, selector, update, opts, &error); - - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - if (!ret) { - printf ("Error: %s\n", error.message); - } - - bson_destroy (&reply); - bson_destroy (update); - bson_destroy (selector); - bson_destroy (opts); - mongoc_bulk_operation_destroy (bulk); -} - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - const char *uri_string = "mongodb://localhost/?appname=bulk-collation"; - mongoc_uri_t *uri; - bson_error_t error; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "db", "collection"); - bulk_collation (collection); - - mongoc_uri_destroy (uri); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/bulk/bulk1.c b/lib/mongoc/libmongoc/examples/bulk/bulk1.c deleted file mode 100644 index 9b0659bbaefad7854fa610d97d3c3a538a827bd5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/bulk/bulk1.c +++ /dev/null @@ -1,76 +0,0 @@ -#include <assert.h> -#include <mongoc/mongoc.h> -#include <stdio.h> - -static void -bulk1 (mongoc_collection_t *collection) -{ - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t *doc; - bson_t reply; - char *str; - bool ret; - int i; - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - for (i = 0; i < 10000; i++) { - doc = BCON_NEW ("i", BCON_INT32 (i)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - } - - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - if (!ret) { - fprintf (stderr, "Error: %s\n", error.message); - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); -} - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - const char *uri_string = "mongodb://localhost/?appname=bulk1-example"; - mongoc_uri_t *uri; - bson_error_t error; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "test", "test"); - - bulk1 (collection); - - mongoc_uri_destroy (uri); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/bulk/bulk2.c b/lib/mongoc/libmongoc/examples/bulk/bulk2.c deleted file mode 100644 index e4f27486d9b414902c662c2aa81d58640705ba36..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/bulk/bulk2.c +++ /dev/null @@ -1,107 +0,0 @@ -#include <assert.h> -#include <mongoc/mongoc.h> -#include <stdio.h> - -static void -bulk2 (mongoc_collection_t *collection) -{ - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t *query; - bson_t *doc; - bson_t *opts; - bson_t reply; - char *str; - bool ret; - int i; - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - /* Remove everything */ - query = bson_new (); - mongoc_bulk_operation_remove (bulk, query); - bson_destroy (query); - - /* Add a few documents */ - for (i = 1; i < 4; i++) { - doc = BCON_NEW ("_id", BCON_INT32 (i)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - } - - /* {_id: 1} => {$set: {foo: "bar"}} */ - query = BCON_NEW ("_id", BCON_INT32 (1)); - doc = BCON_NEW ("$set", "{", "foo", BCON_UTF8 ("bar"), "}"); - mongoc_bulk_operation_update_many_with_opts (bulk, query, doc, NULL, &error); - bson_destroy (query); - bson_destroy (doc); - - /* {_id: 4} => {'$inc': {'j': 1}} (upsert) */ - opts = BCON_NEW ("upsert", BCON_BOOL (true)); - query = BCON_NEW ("_id", BCON_INT32 (4)); - doc = BCON_NEW ("$inc", "{", "j", BCON_INT32 (1), "}"); - mongoc_bulk_operation_update_many_with_opts (bulk, query, doc, opts, &error); - bson_destroy (query); - bson_destroy (doc); - bson_destroy (opts); - - /* replace {j:1} with {j:2} */ - query = BCON_NEW ("j", BCON_INT32 (1)); - doc = BCON_NEW ("j", BCON_INT32 (2)); - mongoc_bulk_operation_replace_one_with_opts (bulk, query, doc, NULL, &error); - bson_destroy (query); - bson_destroy (doc); - - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - if (!ret) { - printf ("Error: %s\n", error.message); - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); -} - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - const char *uri_string = "mongodb://localhost/?appname=bulk2-example"; - mongoc_uri_t *uri; - bson_error_t error; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "test", "test"); - - bulk2 (collection); - - mongoc_uri_destroy (uri); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/bulk/bulk3.c b/lib/mongoc/libmongoc/examples/bulk/bulk3.c deleted file mode 100644 index b86215a0c4758ceca92fc9c0e396455365b0ced5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/bulk/bulk3.c +++ /dev/null @@ -1,97 +0,0 @@ -#include <assert.h> -#include <mongoc/mongoc.h> -#include <stdio.h> - -static void -bulk3 (mongoc_collection_t *collection) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t *query; - bson_t *doc; - bson_t reply; - char *str; - bool ret; - - /* false indicates unordered */ - BSON_APPEND_BOOL (&opts, "ordered", false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - bson_destroy (&opts); - - /* Add a document */ - doc = BCON_NEW ("_id", BCON_INT32 (1)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - /* remove {_id: 2} */ - query = BCON_NEW ("_id", BCON_INT32 (2)); - mongoc_bulk_operation_remove_one (bulk, query); - bson_destroy (query); - - /* insert {_id: 3} */ - doc = BCON_NEW ("_id", BCON_INT32 (3)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - /* replace {_id:4} {'i': 1} */ - query = BCON_NEW ("_id", BCON_INT32 (4)); - doc = BCON_NEW ("i", BCON_INT32 (1)); - mongoc_bulk_operation_replace_one (bulk, query, doc, false); - bson_destroy (query); - bson_destroy (doc); - - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - if (!ret) { - printf ("Error: %s\n", error.message); - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); -} - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - const char *uri_string = "mongodb://localhost/?appname=bulk3-example"; - mongoc_uri_t *uri; - bson_error_t error; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "test", "test"); - - bulk3 (collection); - - mongoc_uri_destroy (uri); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/bulk/bulk4.c b/lib/mongoc/libmongoc/examples/bulk/bulk4.c deleted file mode 100644 index d0fad80b525d92be903101e4c0d42ac77548ee73..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/bulk/bulk4.c +++ /dev/null @@ -1,87 +0,0 @@ -#include <assert.h> -#include <mongoc/mongoc.h> -#include <stdio.h> - -static void -bulk4 (mongoc_collection_t *collection) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_write_concern_t *wc; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t *doc; - bson_t reply; - char *str; - bool ret; - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 4); - mongoc_write_concern_set_wtimeout_int64 (wc, 100); /* milliseconds */ - mongoc_write_concern_append (wc, &opts); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - - /* Two inserts */ - doc = BCON_NEW ("_id", BCON_INT32 (10)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - doc = BCON_NEW ("_id", BCON_INT32 (11)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - if (!ret) { - printf ("Error: %s\n", error.message); - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_write_concern_destroy (wc); - bson_destroy (&opts); -} - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - const char *uri_string = "mongodb://localhost/?appname=bulk4-example"; - mongoc_uri_t *uri; - bson_error_t error; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "test", "test"); - - bulk4 (collection); - - mongoc_uri_destroy (uri); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/bulk/bulk5.c b/lib/mongoc/libmongoc/examples/bulk/bulk5.c deleted file mode 100644 index 0ed501041013157922de43b21b8d52c5f6ffd41a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/bulk/bulk5.c +++ /dev/null @@ -1,135 +0,0 @@ -#include <assert.h> -#include <mongoc/mongoc.h> -#include <stdio.h> - -static void -bulk5_fail (mongoc_collection_t *collection) -{ - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t *doc; - bson_t reply; - char *str; - bool ret; - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - /* Two inserts */ - doc = BCON_NEW ("_id", BCON_INT32 (31)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - doc = BCON_NEW ("_id", BCON_INT32 (32)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - /* The above documents do not comply to the schema validation rules - * we created previously, so this will result in an error */ - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - if (!ret) { - printf ("Error: %s\n", error.message); - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); -} - -static void -bulk5_success (mongoc_collection_t *collection) -{ - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t *doc; - bson_t reply; - char *str; - bool ret; - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - /* Allow this document to bypass document validation. - * NOTE: When authentication is enabled, the authenticated user must have - * either the "dbadmin" or "restore" roles to bypass document validation */ - mongoc_bulk_operation_set_bypass_document_validation (bulk, true); - - /* Two inserts */ - doc = BCON_NEW ("_id", BCON_INT32 (31)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - doc = BCON_NEW ("_id", BCON_INT32 (32)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - if (!ret) { - printf ("Error: %s\n", error.message); - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); -} - -int -main (int argc, char *argv[]) -{ - bson_t *options; - bson_error_t error; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_database_t *database; - const char *uri_string = "mongodb://localhost/?appname=bulk5-example"; - mongoc_uri_t *uri; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - database = mongoc_client_get_database (client, "testasdf"); - - /* Create schema validator */ - options = BCON_NEW ( - "validator", "{", "number", "{", "$gte", BCON_INT32 (5), "}", "}"); - collection = - mongoc_database_create_collection (database, "collname", options, &error); - - if (collection) { - bulk5_fail (collection); - bulk5_success (collection); - mongoc_collection_destroy (collection); - } else { - fprintf (stderr, "Couldn't create collection: '%s'\n", error.message); - } - - bson_free (options); - mongoc_uri_destroy (uri); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/bulk/bulk6.c b/lib/mongoc/libmongoc/examples/bulk/bulk6.c deleted file mode 100644 index c09c92196a320d8e281e856c2c184d322bb3950a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/bulk/bulk6.c +++ /dev/null @@ -1,85 +0,0 @@ -#include <mongoc/mongoc.h> -#include <stdio.h> - -static void -bulk6 (mongoc_collection_t *collection) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_write_concern_t *wc; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t *doc; - bson_t *selector; - bson_t reply; - char *str; - bool ret; - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_append (wc, &opts); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - - doc = BCON_NEW ("_id", BCON_INT32 (10)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - - selector = BCON_NEW ("_id", BCON_INT32 (11)); - mongoc_bulk_operation_remove_one (bulk, selector); - bson_destroy (selector); - - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - if (!ret) { - printf ("Error: %s\n", error.message); - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_write_concern_destroy (wc); - bson_destroy (&opts); -} - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - const char *uri_string = "mongodb://localhost/?appname=bulk6-example"; - mongoc_uri_t *uri; - bson_error_t error; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "test", "test"); - - bulk6 (collection); - - mongoc_uri_destroy (uri); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/cmake/find_package/CMakeLists.txt b/lib/mongoc/libmongoc/examples/cmake/find_package/CMakeLists.txt deleted file mode 100644 index 8e062ae582d676ab5ac353cad563c234a21310a4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/cmake/find_package/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2017 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. - -# Demonstrates how to use the CMake 'find_package' mechanism to locate -# and build against libmongoc. - -cmake_minimum_required (VERSION 3.0) - -if (APPLE) - cmake_policy (SET CMP0042 OLD) -endif () - -project (hello_mongoc LANGUAGES C) - -# NOTE: For this to work, the CMAKE_PREFIX_PATH variable must be set to point to -# the directory that was used as the argument to CMAKE_INSTALL_PREFIX when -# building libmongoc. -# -- sphinx-include-start -- -# Specify the minimum version you require. -find_package (mongoc-1.0 1.7 REQUIRED) - -# The "hello_mongoc.c" sample program is shared among four tests. -add_executable (hello_mongoc ../../hello_mongoc.c) -target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_shared) diff --git a/lib/mongoc/libmongoc/examples/cmake/find_package_static/CMakeLists.txt b/lib/mongoc/libmongoc/examples/cmake/find_package_static/CMakeLists.txt deleted file mode 100644 index f7e3e0907cac8d2a0c38a663e69aabb7657628c9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/cmake/find_package_static/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2017 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. - -# Demonstrates how to use the CMake 'find_package' mechanism to locate -# and build against libmongoc. - -cmake_minimum_required (VERSION 3.0) - -if (APPLE) - cmake_policy (SET CMP0042 OLD) -endif () - -project (hello_mongoc LANGUAGES C) - -# NOTE: For this to work, the CMAKE_PREFIX_PATH variable must be set to point to -# the directory that was used as the argument to CMAKE_INSTALL_PREFIX when -# building libmongoc. -# -- sphinx-include-start -- -# Specify the minimum version you require. -find_package (mongoc-1.0 1.7 REQUIRED) - -# The "hello_mongoc.c" sample program is shared among four tests. -add_executable (hello_mongoc ../../hello_mongoc.c) -target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_static) diff --git a/lib/mongoc/libmongoc/examples/common_operations/common-operations.c b/lib/mongoc/libmongoc/examples/common_operations/common-operations.c deleted file mode 100644 index 319b0ec5596dcc680f5f25592520083a8542c70a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/common_operations/common-operations.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2016 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 <mongoc/mongoc.h> -#include <stdio.h> - - -const char *COLLECTION_NAME = "things"; - -#include "../doc-common-insert.c" -#include "explain.c" - - -int -main (int argc, char *argv[]) -{ - mongoc_database_t *database = NULL; - mongoc_client_t *client = NULL; - mongoc_collection_t *collection = NULL; - mongoc_uri_t *uri = NULL; - bson_error_t error; - char *host_and_port; - int res = 0; - - if (argc < 2 || argc > 3) { - fprintf (stderr, - "usage: %s MONGOD-1-CONNECTION-STRING " - "[MONGOD-2-HOST-NAME:MONGOD-2-PORT]\n", - argv[0]); - fprintf (stderr, - "MONGOD-1-CONNECTION-STRING can be " - "of the following forms:\n"); - fprintf (stderr, "localhost\t\t\t\tlocal machine\n"); - fprintf (stderr, "localhost:27018\t\t\t\tlocal machine on port 27018\n"); - fprintf (stderr, - "mongodb://user:pass@localhost:27017\t" - "local machine on port 27017, and authenticate with username " - "user and password pass\n"); - return EXIT_FAILURE; - } - - mongoc_init (); - - if (strncmp (argv[1], "mongodb://", 10) == 0) { - host_and_port = bson_strdup (argv[1]); - } else { - host_and_port = bson_strdup_printf ("mongodb://%s", argv[1]); - } - - uri = mongoc_uri_new_with_error (host_and_port, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - host_and_port, - error.message); - res = EXIT_FAILURE; - goto cleanup; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - res = EXIT_FAILURE; - goto cleanup; - } - - mongoc_client_set_error_api (client, 2); - database = mongoc_client_get_database (client, "test"); - collection = mongoc_database_get_collection (database, COLLECTION_NAME); - - printf ("Inserting data\n"); - if (!insert_data (collection)) { - res = EXIT_FAILURE; - goto cleanup; - } - - printf ("explain\n"); - if (!explain (collection)) { - res = EXIT_FAILURE; - goto cleanup; - } - -cleanup: - if (collection) { - mongoc_collection_destroy (collection); - } - - if (database) { - mongoc_database_destroy (database); - } - - if (client) { - mongoc_client_destroy (client); - } - - if (uri) { - mongoc_uri_destroy (uri); - } - - bson_free (host_and_port); - mongoc_cleanup (); - return res; -} diff --git a/lib/mongoc/libmongoc/examples/common_operations/explain.c b/lib/mongoc/libmongoc/examples/common_operations/explain.c deleted file mode 100644 index 7ef77ae905c4da0b27224985293521bccfaac39b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/common_operations/explain.c +++ /dev/null @@ -1,33 +0,0 @@ -bool -explain (mongoc_collection_t *collection) -{ - bson_t *command; - bson_t reply; - bson_error_t error; - bool res; - - command = BCON_NEW ("explain", - "{", - "find", - BCON_UTF8 (COLLECTION_NAME), - "filter", - "{", - "x", - BCON_INT32 (1), - "}", - "}"); - res = mongoc_collection_command_simple ( - collection, command, NULL, &reply, &error); - if (!res) { - fprintf (stderr, "Error with explain: %s\n", error.message); - goto cleanup; - } - - /* Do something with the reply */ - print_res (&reply); - -cleanup: - bson_destroy (&reply); - bson_destroy (command); - return res; -} diff --git a/lib/mongoc/libmongoc/examples/compile-with-pkg-config-static.sh b/lib/mongoc/libmongoc/examples/compile-with-pkg-config-static.sh deleted file mode 100644 index acc7fbdb9f5492986e7f215c863365d813a15992..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/compile-with-pkg-config-static.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# -- sphinx-include-start -- -gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-static-1.0) diff --git a/lib/mongoc/libmongoc/examples/compile-with-pkg-config.sh b/lib/mongoc/libmongoc/examples/compile-with-pkg-config.sh deleted file mode 100755 index 91e0a7ebccf54b39e1947ef8d53f792525c8a9f1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/compile-with-pkg-config.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# -- sphinx-include-start -- -gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-1.0) diff --git a/lib/mongoc/libmongoc/examples/doc-common-insert.c b/lib/mongoc/libmongoc/examples/doc-common-insert.c deleted file mode 100644 index b8dd2860992bfa1b75d384fe821c9df747623e18..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/doc-common-insert.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Don't try to compile this file on its own. It's meant to be #included - by example code */ - -/* Insert some sample data */ -bool -insert_data (mongoc_collection_t *collection) -{ - mongoc_bulk_operation_t *bulk; - enum N { ndocs = 4 }; - bson_t *docs[ndocs]; - bson_error_t error; - int i = 0; - bool ret; - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - docs[0] = BCON_NEW ("x", BCON_DOUBLE (1.0), "tags", "[", "dog", "cat", "]"); - docs[1] = BCON_NEW ("x", BCON_DOUBLE (2.0), "tags", "[", "cat", "]"); - docs[2] = BCON_NEW ( - "x", BCON_DOUBLE (2.0), "tags", "[", "mouse", "cat", "dog", "]"); - docs[3] = BCON_NEW ("x", BCON_DOUBLE (3.0), "tags", "[", "]"); - - for (i = 0; i < ndocs; i++) { - mongoc_bulk_operation_insert (bulk, docs[i]); - bson_destroy (docs[i]); - docs[i] = NULL; - } - - ret = mongoc_bulk_operation_execute (bulk, NULL, &error); - - if (!ret) { - fprintf (stderr, "Error inserting data: %s\n", error.message); - } - - mongoc_bulk_operation_destroy (bulk); - return ret; -} - -/* A helper which we'll use a lot later on */ -void -print_res (const bson_t *reply) -{ - char *str; - BSON_ASSERT (reply); - str = bson_as_canonical_extended_json (reply, NULL); - printf ("%s\n", str); - bson_free (str); -} diff --git a/lib/mongoc/libmongoc/examples/example-client.c b/lib/mongoc/libmongoc/examples/example-client.c deleted file mode 100644 index b5379ef8a318467c927dec5d60f4c86f5c208ed2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-client.c +++ /dev/null @@ -1,82 +0,0 @@ -/* gcc example-client.c -o example-client $(pkg-config --cflags --libs - * libmongoc-1.0) */ - -/* ./example-client [CONNECTION_STRING [COLLECTION_NAME]] */ - -#include <mongoc/mongoc.h> -#include <stdio.h> -#include <stdlib.h> - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - const char *collection_name = "test"; - bson_t query; - char *str; - const char *uri_string = "mongodb://127.0.0.1/?appname=client-example"; - mongoc_uri_t *uri; - - mongoc_init (); - if (argc > 1) { - uri_string = argv[1]; - } - - if (argc > 2) { - collection_name = argv[2]; - } - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - - bson_init (&query); - -#if 0 - bson_append_utf8 (&query, "hello", -1, "world", -1); -#endif - - collection = mongoc_client_get_collection (client, "test", collection_name); - cursor = mongoc_collection_find_with_opts ( - collection, - &query, - NULL, /* additional options */ - NULL); /* read prefs, NULL for default */ - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - fprintf (stdout, "%s\n", str); - bson_free (str); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "Cursor Failure: %s\n", error.message); - return EXIT_FAILURE; - } - - bson_destroy (&query); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/example-collection-watch.c b/lib/mongoc/libmongoc/examples/example-collection-watch.c deleted file mode 100644 index b1cb015236da9527bff54d323bffc2b715628d34..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-collection-watch.c +++ /dev/null @@ -1,79 +0,0 @@ -#include <mongoc/mongoc.h> - -int -main () -{ - bson_t empty = BSON_INITIALIZER; - const bson_t *doc; - bson_t *to_insert = BCON_NEW ("x", BCON_INT32 (1)); - const bson_t *err_doc; - bson_error_t error; - const char *uri_string; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t opts = BSON_INITIALIZER; - bool r; - - mongoc_init (); - - uri_string = "mongodb://" - "localhost:27017,localhost:27018,localhost:" - "27019/db?replicaSet=rs0"; - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - coll = mongoc_client_get_collection (client, "db", "coll"); - stream = mongoc_collection_watch (coll, &empty, NULL); - - mongoc_write_concern_set_wmajority (wc, 10000); - mongoc_write_concern_append (wc, &opts); - r = mongoc_collection_insert_one (coll, to_insert, &opts, NULL, &error); - if (!r) { - fprintf (stderr, "Error: %s\n", error.message); - return EXIT_FAILURE; - } - - while (mongoc_change_stream_next (stream, &doc)) { - char *as_json = bson_as_relaxed_extended_json (doc, NULL); - fprintf (stderr, "Got document: %s\n", as_json); - bson_free (as_json); - } - - if (mongoc_change_stream_error_document (stream, &error, &err_doc)) { - if (!bson_empty (err_doc)) { - fprintf (stderr, - "Server Error: %s\n", - bson_as_relaxed_extended_json (err_doc, NULL)); - } else { - fprintf (stderr, "Client Error: %s\n", error.message); - } - return EXIT_FAILURE; - } - - bson_destroy (to_insert); - mongoc_write_concern_destroy (wc); - bson_destroy (&opts); - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/example-command-monitoring.c b/lib/mongoc/libmongoc/examples/example-command-monitoring.c deleted file mode 100644 index fe154dce8b1c444628ac598cade8d179401fd603..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-command-monitoring.c +++ /dev/null @@ -1,136 +0,0 @@ -/* gcc example-command-monitoring.c -o example-command-monitoring \ - * $(pkg-config --cflags --libs libmongoc-1.0) */ - -/* ./example-command-monitoring [CONNECTION_STRING] */ - -#include <mongoc/mongoc.h> -#include <stdio.h> - - -typedef struct { - int started; - int succeeded; - int failed; -} stats_t; - - -void -command_started (const mongoc_apm_command_started_t *event) -{ - char *s; - - s = bson_as_relaxed_extended_json ( - mongoc_apm_command_started_get_command (event), NULL); - printf ("Command %s started on %s:\n%s\n\n", - mongoc_apm_command_started_get_command_name (event), - mongoc_apm_command_started_get_host (event)->host, - s); - - ((stats_t *) mongoc_apm_command_started_get_context (event))->started++; - - bson_free (s); -} - - -void -command_succeeded (const mongoc_apm_command_succeeded_t *event) -{ - char *s; - - s = bson_as_relaxed_extended_json ( - mongoc_apm_command_succeeded_get_reply (event), NULL); - printf ("Command %s succeeded:\n%s\n\n", - mongoc_apm_command_succeeded_get_command_name (event), - s); - - ((stats_t *) mongoc_apm_command_succeeded_get_context (event))->succeeded++; - - bson_free (s); -} - - -void -command_failed (const mongoc_apm_command_failed_t *event) -{ - bson_error_t error; - - mongoc_apm_command_failed_get_error (event, &error); - printf ("Command %s failed:\n\"%s\"\n\n", - mongoc_apm_command_failed_get_command_name (event), - error.message); - - ((stats_t *) mongoc_apm_command_failed_get_context (event))->failed++; -} - - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_apm_callbacks_t *callbacks; - stats_t stats = {0}; - mongoc_collection_t *collection; - bson_error_t error; - const char *uri_string = - "mongodb://127.0.0.1/?appname=cmd-monitoring-example"; - mongoc_uri_t *uri; - const char *collection_name = "test"; - bson_t *docs[2]; - - mongoc_init (); - - if (argc > 1) { - uri_string = argv[1]; - } - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, command_started); - mongoc_apm_set_command_succeeded_cb (callbacks, command_succeeded); - mongoc_apm_set_command_failed_cb (callbacks, command_failed); - mongoc_client_set_apm_callbacks ( - client, callbacks, (void *) &stats /* context pointer */); - - collection = mongoc_client_get_collection (client, "test", collection_name); - mongoc_collection_drop (collection, NULL); - - docs[0] = BCON_NEW ("_id", BCON_INT32 (0)); - docs[1] = BCON_NEW ("_id", BCON_INT32 (1)); - mongoc_collection_insert_many ( - collection, (const bson_t **) docs, 2, NULL, NULL, NULL); - - /* duplicate key error on the second insert */ - mongoc_collection_insert_one (collection, docs[0], NULL, NULL, NULL); - - mongoc_collection_destroy (collection); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - printf ("started: %d\nsucceeded: %d\nfailed: %d\n", - stats.started, - stats.succeeded, - stats.failed); - - bson_destroy (docs[0]); - bson_destroy (docs[1]); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/example-command-with-opts.c b/lib/mongoc/libmongoc/examples/example-command-with-opts.c deleted file mode 100644 index fbbc3481f07a964911cefee0fc2aa70d544d19d5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-command-with-opts.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - -Demonstrates how to prepare options for mongoc_client_read_command_with_opts and -mongoc_client_write_command_with_opts. First it calls "cloneCollectionAsCapped" -command with "writeConcern" option, then "distinct" command with "collation" and -"readConcern" options, - -Start a MongoDB 3.4 replica set with --enableMajorityReadConcern and insert two -documents: - -$ mongo -MongoDB Enterprise replset:PRIMARY> db.my_collection.insert({x: 1, y: "One"}) -WriteResult({ "nInserted" : 1 }) -MongoDB Enterprise replset:PRIMARY> db.my_collection.insert({x: 2, y: "Two"}) -WriteResult({ "nInserted" : 1 }) - -Build and run the example: - -gcc example-command-with-opts.c -o example-command-with-opts $(pkg-config ---cflags --libs libmongoc-1.0) -./example-command-with-opts [CONNECTION_STRING] -cloneCollectionAsCapped: { "ok" : 1 } -distinct: { "values" : [ 1, 2 ], "ok" : 1 } - -*/ - -#include <mongoc/mongoc.h> -#include <stdio.h> -#include <stdlib.h> - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - const char *uri_string = "mongodb://127.0.0.1/?appname=client-example"; - mongoc_uri_t *uri; - bson_t *cmd; - bson_t *opts; - mongoc_write_concern_t *write_concern; - mongoc_read_prefs_t *read_prefs; - mongoc_read_concern_t *read_concern; - bson_t reply; - bson_error_t error; - char *json; - - mongoc_init (); - - if (argc > 1) { - uri_string = argv[1]; - } - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - - cmd = BCON_NEW ("cloneCollectionAsCapped", - BCON_UTF8 ("my_collection"), - "toCollection", - BCON_UTF8 ("my_capped_collection"), - "size", - BCON_INT64 (1024 * 1024)); - - /* include write concern "majority" in command options */ - write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_wmajority (write_concern, 10000 /* wtimeoutMS */); - opts = bson_new (); - mongoc_write_concern_append (write_concern, opts); - - if (mongoc_client_write_command_with_opts ( - client, "test", cmd, opts, &reply, &error)) { - json = bson_as_canonical_extended_json (&reply, NULL); - printf ("cloneCollectionAsCapped: %s\n", json); - bson_free (json); - } else { - fprintf (stderr, "cloneCollectionAsCapped: %s\n", error.message); - } - - bson_free (cmd); - bson_free (opts); - - /* distinct values of "x" in "my_collection" where "y" sorts after "one" */ - cmd = BCON_NEW ("distinct", - BCON_UTF8 ("my_collection"), - "key", - BCON_UTF8 ("x"), - "query", - "{", - "y", - "{", - "$gt", - BCON_UTF8 ("one"), - "}", - "}"); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - /* "One" normally sorts before "one"; make "One" sort after "one" */ - opts = BCON_NEW ("collation", - "{", - "locale", - BCON_UTF8 ("en_US"), - "caseFirst", - BCON_UTF8 ("lower"), - "}"); - - /* add a read concern to "opts" */ - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, - MONGOC_READ_CONCERN_LEVEL_MAJORITY); - - mongoc_read_concern_append (read_concern, opts); - - if (mongoc_client_read_command_with_opts ( - client, "test", cmd, read_prefs, opts, &reply, &error)) { - json = bson_as_canonical_extended_json (&reply, NULL); - printf ("distinct: %s\n", json); - bson_free (json); - } else { - fprintf (stderr, "distinct: %s\n", error.message); - } - - bson_destroy (cmd); - bson_destroy (opts); - bson_destroy (&reply); - mongoc_read_prefs_destroy (read_prefs); - mongoc_read_concern_destroy (read_concern); - mongoc_write_concern_destroy (write_concern); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/example-create-indexes.c b/lib/mongoc/libmongoc/examples/example-create-indexes.c deleted file mode 100644 index 82853eb358afeff45a0a4cecdc0748c26a0497c4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-create-indexes.c +++ /dev/null @@ -1,92 +0,0 @@ -/* gcc example-create-indexes.c -o example-create-indexes $(pkg-config --cflags - * --libs libmongoc-1.0) */ - -/* ./example-create-indexes [CONNECTION_STRING [COLLECTION_NAME]] */ - -#include <mongoc/mongoc.h> -#include <stdio.h> -#include <stdlib.h> - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - const char *uri_string = - "mongodb://127.0.0.1/?appname=create-indexes-example"; - mongoc_uri_t *uri; - mongoc_database_t *db; - const char *collection_name = "test"; - bson_t keys; - char *index_name; - bson_t *create_indexes; - bson_t reply; - char *reply_str; - bson_error_t error; - bool r; - - mongoc_init (); - - if (argc > 1) { - uri_string = argv[1]; - } - - if (argc > 2) { - collection_name = argv[2]; - } - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - db = mongoc_client_get_database (client, "test"); - - /* ascending index on field "x" */ - bson_init (&keys); - BSON_APPEND_INT32 (&keys, "x", 1); - index_name = mongoc_collection_keys_to_index_string (&keys); - create_indexes = BCON_NEW ("createIndexes", - BCON_UTF8 (collection_name), - "indexes", - "[", - "{", - "key", - BCON_DOCUMENT (&keys), - "name", - BCON_UTF8 (index_name), - "}", - "]"); - - r = mongoc_database_write_command_with_opts ( - db, create_indexes, NULL /* opts */, &reply, &error); - - reply_str = bson_as_json (&reply, NULL); - printf ("%s\n", reply_str); - - if (!r) { - fprintf (stderr, "Error in createIndexes: %s\n", error.message); - } - - bson_free (index_name); - bson_free (reply_str); - bson_destroy (&reply); - bson_destroy (create_indexes); - mongoc_database_destroy (db); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return r ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/lib/mongoc/libmongoc/examples/example-gridfs-bucket.c b/lib/mongoc/libmongoc/examples/example-gridfs-bucket.c deleted file mode 100644 index 23622e8f21cfdcc0be9e467d76573137c1cc2210..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-gridfs-bucket.c +++ /dev/null @@ -1,94 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#include <mongoc/mongoc.h> - -int -main (int argc, char *argv[]) -{ - const char *uri_string = - "mongodb://localhost:27017/?appname=new-gridfs-example"; - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_stream_t *file_stream; - mongoc_gridfs_bucket_t *bucket; - mongoc_cursor_t *cursor; - bson_t filter; - bool res; - bson_value_t file_id; - bson_error_t error; - const bson_t *doc; - char *str; - mongoc_init (); - - if (argc != 3) { - fprintf (stderr, "usage: %s SOURCE_FILE_PATH FILE_COPY_PATH\n", argv[0]); - return EXIT_FAILURE; - } - - /* 1. Make a bucket. */ - client = mongoc_client_new (uri_string); - db = mongoc_client_get_database (client, "test"); - bucket = mongoc_gridfs_bucket_new (db, NULL, NULL, &error); - if (!bucket) { - printf ("Error creating gridfs bucket: %s\n", error.message); - return EXIT_FAILURE; - } - - /* 2. Insert a file. */ - file_stream = mongoc_stream_file_new_for_path (argv[1], O_RDONLY, 0); - res = mongoc_gridfs_bucket_upload_from_stream ( - bucket, "my-file", file_stream, NULL, &file_id, &error); - if (!res) { - printf ("Error uploading file: %s\n", error.message); - return EXIT_FAILURE; - } - - mongoc_stream_close (file_stream); - mongoc_stream_destroy (file_stream); - - /* 3. Download the file in GridFS to a local file. */ - file_stream = mongoc_stream_file_new_for_path (argv[2], O_CREAT | O_RDWR, 0); - if (!file_stream) { - perror ("Error opening file stream"); - return EXIT_FAILURE; - } - - res = mongoc_gridfs_bucket_download_to_stream ( - bucket, &file_id, file_stream, &error); - if (!res) { - printf ("Error downloading file to stream: %s\n", error.message); - return EXIT_FAILURE; - } - mongoc_stream_close (file_stream); - mongoc_stream_destroy (file_stream); - - /* 4. List what files are available in GridFS. */ - bson_init (&filter); - cursor = mongoc_gridfs_bucket_find (bucket, &filter, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_canonical_extended_json (doc, NULL); - printf ("%s\n", str); - bson_free (str); - } - - /* 5. Delete the file that we added. */ - res = mongoc_gridfs_bucket_delete_by_id (bucket, &file_id, &error); - if (!res) { - printf ("Error deleting the file: %s\n", error.message); - return EXIT_FAILURE; - } - - /* 6. Cleanup. */ - mongoc_stream_close (file_stream); - mongoc_stream_destroy (file_stream); - mongoc_cursor_destroy (cursor); - bson_destroy (&filter); - mongoc_gridfs_bucket_destroy (bucket); - mongoc_database_destroy (db); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return EXIT_SUCCESS; -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/examples/example-gridfs.c b/lib/mongoc/libmongoc/examples/example-gridfs.c deleted file mode 100644 index 4e7b43afd212e4f47ad07662cc2d47644840c7b7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-gridfs.c +++ /dev/null @@ -1,154 +0,0 @@ -#include <assert.h> -#include <mongoc/mongoc.h> -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> - -int -main (int argc, char *argv[]) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_gridfs_file_list_t *list; - mongoc_gridfs_file_opt_t opt = {0}; - mongoc_client_t *client; - const char *uri_string = "mongodb://127.0.0.1:27017/?appname=gridfs-example"; - mongoc_uri_t *uri; - mongoc_stream_t *stream; - bson_t filter; - bson_t opts; - bson_t child; - bson_error_t error; - ssize_t r; - char buf[4096]; - mongoc_iovec_t iov; - const char *filename; - const char *command; - bson_value_t id; - - if (argc < 2) { - fprintf (stderr, "usage - %s command ...\n", argv[0]); - return EXIT_FAILURE; - } - - mongoc_init (); - - iov.iov_base = (void *) buf; - iov.iov_len = sizeof buf; - - /* connect to localhost client */ - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - assert (client); - mongoc_client_set_error_api (client, 2); - - /* grab a gridfs handle in test prefixed by fs */ - gridfs = mongoc_client_get_gridfs (client, "test", "fs", &error); - assert (gridfs); - - command = argv[1]; - filename = argv[2]; - - if (strcmp (command, "read") == 0) { - if (argc != 3) { - fprintf (stderr, "usage - %s read filename\n", argv[0]); - return EXIT_FAILURE; - } - file = mongoc_gridfs_find_one_by_filename (gridfs, filename, &error); - assert (file); - - stream = mongoc_stream_gridfs_new (file); - assert (stream); - - for (;;) { - r = mongoc_stream_readv (stream, &iov, 1, -1, 0); - - assert (r >= 0); - - if (r == 0) { - break; - } - - if (fwrite (iov.iov_base, 1, r, stdout) != r) { - MONGOC_ERROR ("Failed to write to stdout. Exiting.\n"); - exit (1); - } - } - - mongoc_stream_destroy (stream); - mongoc_gridfs_file_destroy (file); - } else if (strcmp (command, "list") == 0) { - bson_init (&filter); - - bson_init (&opts); - bson_append_document_begin (&opts, "sort", -1, &child); - BSON_APPEND_INT32 (&child, "filename", 1); - bson_append_document_end (&opts, &child); - - list = mongoc_gridfs_find_with_opts (gridfs, &filter, &opts); - - bson_destroy (&filter); - bson_destroy (&opts); - - while ((file = mongoc_gridfs_file_list_next (list))) { - const char *name = mongoc_gridfs_file_get_filename (file); - printf ("%s\n", name ? name : "?"); - - mongoc_gridfs_file_destroy (file); - } - - mongoc_gridfs_file_list_destroy (list); - } else if (strcmp (command, "write") == 0) { - if (argc != 4) { - fprintf (stderr, "usage - %s write filename input_file\n", argv[0]); - return EXIT_FAILURE; - } - - stream = mongoc_stream_file_new_for_path (argv[3], O_RDONLY, 0); - assert (stream); - - opt.filename = filename; - - /* the driver generates a file_id for you */ - file = mongoc_gridfs_create_file_from_stream (gridfs, stream, &opt); - assert (file); - - id.value_type = BSON_TYPE_INT32; - id.value.v_int32 = 1; - - /* optional: the following method specifies a file_id of any - BSON type */ - if (!mongoc_gridfs_file_set_id (file, &id, &error)) { - fprintf (stderr, "%s\n", error.message); - return EXIT_FAILURE; - } - - if (!mongoc_gridfs_file_save (file)) { - mongoc_gridfs_file_error (file, &error); - fprintf (stderr, "Could not save: %s\n", error.message); - return EXIT_FAILURE; - } - - mongoc_gridfs_file_destroy (file); - } else { - fprintf (stderr, "Unknown command"); - return EXIT_FAILURE; - } - - mongoc_gridfs_destroy (gridfs); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/example-pool.c b/lib/mongoc/libmongoc/examples/example-pool.c deleted file mode 100644 index 8b80b01dfca87912435612e8081e43312af2444d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-pool.c +++ /dev/null @@ -1,102 +0,0 @@ -/* gcc example-pool.c -o example-pool $(pkg-config --cflags --libs - * libmongoc-1.0) */ - -/* ./example-pool [CONNECTION_STRING] */ - -#include <mongoc/mongoc.h> -#include <pthread.h> -#include <stdio.h> - -static pthread_mutex_t mutex; -static bool in_shutdown = false; - -static void * -worker (void *data) -{ - mongoc_client_pool_t *pool = data; - mongoc_client_t *client; - bson_t ping = BSON_INITIALIZER; - bson_error_t error; - bool r; - - BSON_APPEND_INT32 (&ping, "ping", 1); - - while (true) { - client = mongoc_client_pool_pop (pool); - /* Do something with client. If you are writing an HTTP server, you - * probably only want to hold onto the client for the portion of the - * request performing database queries. - */ - r = mongoc_client_command_simple ( - client, "admin", &ping, NULL, NULL, &error); - - if (!r) { - fprintf (stderr, "%s\n", error.message); - } - - mongoc_client_pool_push (pool, client); - - pthread_mutex_lock (&mutex); - if (in_shutdown || !r) { - pthread_mutex_unlock (&mutex); - break; - } - - pthread_mutex_unlock (&mutex); - } - - bson_destroy (&ping); - return NULL; -} - -int -main (int argc, char *argv[]) -{ - const char *uri_string = "mongodb://127.0.0.1/?appname=pool-example"; - mongoc_uri_t *uri; - bson_error_t error; - mongoc_client_pool_t *pool; - pthread_t threads[10]; - unsigned i; - void *ret; - - pthread_mutex_init (&mutex, NULL); - mongoc_init (); - - if (argc > 1) { - uri_string = argv[1]; - } - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - pool = mongoc_client_pool_new (uri); - mongoc_client_pool_set_error_api (pool, 2); - - for (i = 0; i < 10; i++) { - pthread_create (&threads[i], NULL, worker, pool); - } - - sleep (10); - pthread_mutex_lock (&mutex); - in_shutdown = true; - pthread_mutex_unlock (&mutex); - - for (i = 0; i < 10; i++) { - pthread_join (threads[i], &ret); - } - - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/example-resume.c b/lib/mongoc/libmongoc/examples/example-resume.c deleted file mode 100644 index ea65f02922905e541e895f9779cab3756b0aa35d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-resume.c +++ /dev/null @@ -1,161 +0,0 @@ -#include <mongoc/mongoc.h> - -/* An example implementation of custom resume logic in a change stream. -* example-resume starts a client-wide change stream and persists the resume -* token in a file "resume-token.json". On restart, if "resume-token.json" -* exists, the change stream starts watching after the persisted resume token. -* -* This behavior allows a user to exit example-resume, and restart it later -* without missing any change events. -*/ -#include <unistd.h> - -static const char *RESUME_TOKEN_PATH = "resume-token.json"; - -static bool -_save_resume_token (const bson_t *doc) -{ - FILE *file_stream; - bson_iter_t iter; - bson_t resume_token_doc; - char *as_json = NULL; - size_t as_json_len; - ssize_t r, n_written; - const bson_value_t *resume_token; - - if (!bson_iter_init_find (&iter, doc, "_id")) { - fprintf (stderr, "reply does not contain operationTime."); - return false; - } - resume_token = bson_iter_value (&iter); - /* store the resume token in a document, { resumeAfter: <resume token> } - * which we can later append easily. */ - file_stream = fopen (RESUME_TOKEN_PATH, "w+"); - if (!file_stream) { - fprintf (stderr, "failed to open %s for writing\n", RESUME_TOKEN_PATH); - return false; - } - bson_init (&resume_token_doc); - BSON_APPEND_VALUE (&resume_token_doc, "resumeAfter", resume_token); - as_json = bson_as_canonical_extended_json (&resume_token_doc, &as_json_len); - bson_destroy (&resume_token_doc); - n_written = 0; - while (n_written < as_json_len) { - r = fwrite ((void *) (as_json + n_written), - sizeof (char), - as_json_len - n_written, - file_stream); - if (r == -1) { - fprintf (stderr, "failed to write to %s\n", RESUME_TOKEN_PATH); - bson_free (as_json); - fclose (file_stream); - return false; - } - n_written += r; - } - - bson_free (as_json); - fclose (file_stream); - return true; -} - -bool -_load_resume_token (bson_t *opts) -{ - bson_error_t error; - bson_json_reader_t *reader; - bson_t doc; - - /* if the file does not exist, skip. */ - if (-1 == access (RESUME_TOKEN_PATH, R_OK)) { - return true; - } - reader = bson_json_reader_new_from_file (RESUME_TOKEN_PATH, &error); - if (!reader) { - fprintf (stderr, - "failed to open %s for reading: %s\n", - RESUME_TOKEN_PATH, - error.message); - return false; - } - - bson_init (&doc); - if (-1 == bson_json_reader_read (reader, &doc, &error)) { - fprintf (stderr, "failed to read doc from %s\n", RESUME_TOKEN_PATH); - bson_destroy (&doc); - bson_json_reader_destroy (reader); - return false; - } - - printf ("found cached resume token in %s, resuming change stream.\n", - RESUME_TOKEN_PATH); - - bson_concat (opts, &doc); - bson_destroy (&doc); - bson_json_reader_destroy (reader); - return true; -} - -int -main () -{ - int exit_code = EXIT_FAILURE; - const char *uri_string; - mongoc_uri_t *uri = NULL; - bson_error_t error; - mongoc_client_t *client = NULL; - bson_t pipeline = BSON_INITIALIZER; - bson_t opts = BSON_INITIALIZER; - mongoc_change_stream_t *stream = NULL; - const bson_t *doc; - - const int max_time = 30; /* max amount of time, in seconds, that - mongoc_change_stream_next can block. */ - - mongoc_init (); - uri_string = "mongodb://localhost:27017/db?replicaSet=rs0"; - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - goto cleanup; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - goto cleanup; - } - - if (!_load_resume_token (&opts)) { - goto cleanup; - } - BSON_APPEND_INT64 (&opts, "maxAwaitTimeMS", max_time * 1000); - - printf ("listening for changes on the client (max %d seconds).\n", max_time); - stream = mongoc_client_watch (client, &pipeline, &opts); - - while (mongoc_change_stream_next (stream, &doc)) { - char *as_json; - - as_json = bson_as_canonical_extended_json (doc, NULL); - printf ("change received: %s\n", as_json); - bson_free (as_json); - if (!_save_resume_token (doc)) { - goto cleanup; - } - } - - exit_code = EXIT_SUCCESS; - -cleanup: - mongoc_uri_destroy (uri); - bson_destroy (&pipeline); - bson_destroy (&opts); - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); - mongoc_cleanup (); - return exit_code; -} diff --git a/lib/mongoc/libmongoc/examples/example-scram.c b/lib/mongoc/libmongoc/examples/example-scram.c deleted file mode 100644 index 49a496e11958e12b81c47cd7f9e1714333e436b6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-scram.c +++ /dev/null @@ -1,118 +0,0 @@ -/* gcc example.c -o example $(pkg-config --cflags --libs libmongoc-1.0) */ - -/* ./example-scram */ - -#include <mongoc/mongoc.h> -#include <stdio.h> -#include <stdlib.h> - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client = NULL; - mongoc_database_t *database = NULL; - mongoc_collection_t *collection = NULL; - mongoc_cursor_t *cursor = NULL; - bson_error_t error; - const char *uri_string = "mongodb://127.0.0.1/"; - mongoc_uri_t *uri = NULL; - const char *authuristr; - bson_t roles; - bson_t query; - const bson_t *doc; - int exit_code = EXIT_FAILURE; - - if (argc != 2) { - printf ("%s - [implicit|scram]\n", argv[0]); - return exit_code; - } - - if (strcmp (argv[1], "implicit") == 0) { - authuristr = "mongodb://user,=:pass@127.0.0.1/test?appname=scram-example"; - } else if (strcmp (argv[1], "scram") == 0) { - authuristr = "mongodb://user,=:pass@127.0.0.1/" - "test?appname=scram-example&authMechanism=SCRAM-SHA-1"; - } else { - printf ("%s - [implicit|scram]\n", argv[0]); - return exit_code; - } - - mongoc_init (); - - bson_init (&roles); - bson_init (&query); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - goto CLEANUP; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - goto CLEANUP; - } - - mongoc_client_set_error_api (client, 2); - - database = mongoc_client_get_database (client, "test"); - - BCON_APPEND (&roles, "0", "{", "role", "root", "db", "admin", "}"); - - mongoc_database_add_user (database, "user,=", "pass", &roles, NULL, &error); - - mongoc_database_destroy (database); - - mongoc_client_destroy (client); - - client = mongoc_client_new (authuristr); - - if (!client) { - fprintf (stderr, "failed to parse SCRAM uri\n"); - goto CLEANUP; - } - - mongoc_client_set_error_api (client, 2); - - collection = mongoc_client_get_collection (client, "test", "test"); - - cursor = mongoc_collection_find_with_opts (collection, &query, NULL, NULL); - - mongoc_cursor_next (cursor, &doc); - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "Auth error: %s\n", error.message); - goto CLEANUP; - } - - exit_code = EXIT_SUCCESS; - -CLEANUP: - - bson_destroy (&roles); - bson_destroy (&query); - - if (collection) { - mongoc_collection_destroy (collection); - } - - if (uri) { - mongoc_uri_destroy (uri); - } - - if (client) { - mongoc_client_destroy (client); - } - - if (cursor) { - mongoc_cursor_destroy (cursor); - } - - mongoc_cleanup (); - - return exit_code; -} diff --git a/lib/mongoc/libmongoc/examples/example-sdam-monitoring.c b/lib/mongoc/libmongoc/examples/example-sdam-monitoring.c deleted file mode 100644 index 879e16385679c28e255dd729b8605576a88d7668..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-sdam-monitoring.c +++ /dev/null @@ -1,293 +0,0 @@ -/* gcc example-sdam-monitoring.c -o example-sdam-monitoring \ - * $(pkg-config --cflags --libs libmongoc-1.0) */ - -/* ./example-sdam-monitoring [CONNECTION_STRING] */ - -#include <mongoc/mongoc.h> -#include <stdio.h> - - -typedef struct { - int server_changed_events; - int server_opening_events; - int server_closed_events; - int topology_changed_events; - int topology_opening_events; - int topology_closed_events; - int heartbeat_started_events; - int heartbeat_succeeded_events; - int heartbeat_failed_events; -} stats_t; - - -static void -server_changed (const mongoc_apm_server_changed_t *event) -{ - stats_t *context; - const mongoc_server_description_t *prev_sd, *new_sd; - - context = (stats_t *) mongoc_apm_server_changed_get_context (event); - context->server_changed_events++; - - prev_sd = mongoc_apm_server_changed_get_previous_description (event); - new_sd = mongoc_apm_server_changed_get_new_description (event); - - printf ("server changed: %s %s -> %s\n", - mongoc_apm_server_changed_get_host (event)->host_and_port, - mongoc_server_description_type (prev_sd), - mongoc_server_description_type (new_sd)); -} - - -static void -server_opening (const mongoc_apm_server_opening_t *event) -{ - stats_t *context; - - context = (stats_t *) mongoc_apm_server_opening_get_context (event); - context->server_opening_events++; - - printf ("server opening: %s\n", - mongoc_apm_server_opening_get_host (event)->host_and_port); -} - - -static void -server_closed (const mongoc_apm_server_closed_t *event) -{ - stats_t *context; - - context = (stats_t *) mongoc_apm_server_closed_get_context (event); - context->server_closed_events++; - - printf ("server closed: %s\n", - mongoc_apm_server_closed_get_host (event)->host_and_port); -} - - -static void -topology_changed (const mongoc_apm_topology_changed_t *event) -{ - stats_t *context; - const mongoc_topology_description_t *prev_td; - const mongoc_topology_description_t *new_td; - mongoc_server_description_t **prev_sds; - size_t n_prev_sds; - mongoc_server_description_t **new_sds; - size_t n_new_sds; - size_t i; - mongoc_read_prefs_t *prefs; - - context = (stats_t *) mongoc_apm_topology_changed_get_context (event); - context->topology_changed_events++; - - prev_td = mongoc_apm_topology_changed_get_previous_description (event); - prev_sds = mongoc_topology_description_get_servers (prev_td, &n_prev_sds); - new_td = mongoc_apm_topology_changed_get_new_description (event); - new_sds = mongoc_topology_description_get_servers (new_td, &n_new_sds); - - printf ("topology changed: %s -> %s\n", - mongoc_topology_description_type (prev_td), - mongoc_topology_description_type (new_td)); - - if (n_prev_sds) { - printf (" previous servers:\n"); - for (i = 0; i < n_prev_sds; i++) { - printf (" %s %s\n", - mongoc_server_description_type (prev_sds[i]), - mongoc_server_description_host (prev_sds[i])->host_and_port); - } - } - - if (n_new_sds) { - printf (" new servers:\n"); - for (i = 0; i < n_new_sds; i++) { - printf (" %s %s\n", - mongoc_server_description_type (new_sds[i]), - mongoc_server_description_host (new_sds[i])->host_and_port); - } - } - - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - /* it is safe, and unfortunately necessary, to cast away const here */ - if (mongoc_topology_description_has_readable_server ( - (mongoc_topology_description_t *) new_td, prefs)) { - printf (" secondary AVAILABLE\n"); - } else { - printf (" secondary UNAVAILABLE\n"); - } - - if (mongoc_topology_description_has_writable_server ( - (mongoc_topology_description_t *) new_td)) { - printf (" primary AVAILABLE\n"); - } else { - printf (" primary UNAVAILABLE\n"); - } - - mongoc_read_prefs_destroy (prefs); - mongoc_server_descriptions_destroy_all (prev_sds, n_prev_sds); - mongoc_server_descriptions_destroy_all (new_sds, n_new_sds); -} - - -static void -topology_opening (const mongoc_apm_topology_opening_t *event) -{ - stats_t *context; - - context = (stats_t *) mongoc_apm_topology_opening_get_context (event); - context->topology_opening_events++; - - printf ("topology opening\n"); -} - - -static void -topology_closed (const mongoc_apm_topology_closed_t *event) -{ - stats_t *context; - - context = (stats_t *) mongoc_apm_topology_closed_get_context (event); - context->topology_closed_events++; - - printf ("topology closed\n"); -} - - -static void -server_heartbeat_started (const mongoc_apm_server_heartbeat_started_t *event) -{ - stats_t *context; - - context = - (stats_t *) mongoc_apm_server_heartbeat_started_get_context (event); - context->heartbeat_started_events++; - - printf ("%s heartbeat started\n", - mongoc_apm_server_heartbeat_started_get_host (event)->host_and_port); -} - - -static void -server_heartbeat_succeeded ( - const mongoc_apm_server_heartbeat_succeeded_t *event) -{ - stats_t *context; - char *reply; - - context = - (stats_t *) mongoc_apm_server_heartbeat_succeeded_get_context (event); - context->heartbeat_succeeded_events++; - - reply = bson_as_canonical_extended_json ( - mongoc_apm_server_heartbeat_succeeded_get_reply (event), NULL); - - printf ( - "%s heartbeat succeeded: %s\n", - mongoc_apm_server_heartbeat_succeeded_get_host (event)->host_and_port, - reply); - - bson_free (reply); -} - - -static void -server_heartbeat_failed (const mongoc_apm_server_heartbeat_failed_t *event) -{ - stats_t *context; - bson_error_t error; - - context = (stats_t *) mongoc_apm_server_heartbeat_failed_get_context (event); - context->heartbeat_failed_events++; - mongoc_apm_server_heartbeat_failed_get_error (event, &error); - - printf ("%s heartbeat failed: %s\n", - mongoc_apm_server_heartbeat_failed_get_host (event)->host_and_port, - error.message); -} - - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - mongoc_apm_callbacks_t *cbs; - stats_t stats = {0}; - const char *uri_string = - "mongodb://127.0.0.1/?appname=sdam-monitoring-example"; - mongoc_uri_t *uri; - bson_t cmd = BSON_INITIALIZER; - bson_t reply; - bson_error_t error; - - mongoc_init (); - - if (argc > 1) { - uri_string = argv[1]; - } - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - cbs = mongoc_apm_callbacks_new (); - mongoc_apm_set_server_changed_cb (cbs, server_changed); - mongoc_apm_set_server_opening_cb (cbs, server_opening); - mongoc_apm_set_server_closed_cb (cbs, server_closed); - mongoc_apm_set_topology_changed_cb (cbs, topology_changed); - mongoc_apm_set_topology_opening_cb (cbs, topology_opening); - mongoc_apm_set_topology_closed_cb (cbs, topology_closed); - mongoc_apm_set_server_heartbeat_started_cb (cbs, server_heartbeat_started); - mongoc_apm_set_server_heartbeat_succeeded_cb (cbs, - server_heartbeat_succeeded); - mongoc_apm_set_server_heartbeat_failed_cb (cbs, server_heartbeat_failed); - mongoc_client_set_apm_callbacks ( - client, cbs, (void *) &stats /* context pointer */); - - /* the driver connects on demand to perform first operation */ - BSON_APPEND_INT32 (&cmd, "buildinfo", 1); - mongoc_client_command_simple (client, "admin", &cmd, NULL, &reply, &error); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - printf ("Events:\n" - " server changed: %d\n" - " server opening: %d\n" - " server closed: %d\n" - " topology changed: %d\n" - " topology opening: %d\n" - " topology closed: %d\n" - " heartbeat started: %d\n" - " heartbeat succeeded: %d\n" - " heartbeat failed: %d\n", - stats.server_changed_events, - stats.server_opening_events, - stats.server_closed_events, - stats.topology_changed_events, - stats.topology_opening_events, - stats.topology_closed_events, - stats.heartbeat_started_events, - stats.heartbeat_succeeded_events, - stats.heartbeat_failed_events); - - bson_destroy (&cmd); - bson_destroy (&reply); - mongoc_apm_callbacks_destroy (cbs); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/example-session.c b/lib/mongoc/libmongoc/examples/example-session.c deleted file mode 100644 index 163e0087386cbc51cf6fd5eb25625ecc9d4b444d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-session.c +++ /dev/null @@ -1,145 +0,0 @@ -/* gcc example-session.c -o example-session \ - * $(pkg-config --cflags --libs libmongoc-1.0) */ - -/* ./example-session [CONNECTION_STRING] */ - -#include <stdio.h> -#include <mongoc/mongoc.h> - - -int -main (int argc, char *argv[]) -{ - int exit_code = EXIT_FAILURE; - - mongoc_client_t *client = NULL; - const char *uri_string = "mongodb://127.0.0.1/?appname=session-example"; - mongoc_uri_t *uri = NULL; - mongoc_client_session_t *client_session = NULL; - mongoc_collection_t *collection = NULL; - bson_error_t error; - bson_t *selector = NULL; - bson_t *update = NULL; - bson_t *update_opts = NULL; - bson_t *find_opts = NULL; - mongoc_read_prefs_t *secondary = NULL; - mongoc_cursor_t *cursor = NULL; - const bson_t *doc; - char *str; - bool r; - - mongoc_init (); - - if (argc > 1) { - uri_string = argv[1]; - } - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - goto done; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - goto done; - } - - mongoc_client_set_error_api (client, 2); - - /* pass NULL for options - by default the session is causally consistent */ - client_session = mongoc_client_start_session (client, NULL, &error); - if (!client_session) { - fprintf (stderr, "Failed to start session: %s\n", error.message); - goto done; - } - - collection = mongoc_client_get_collection (client, "test", "collection"); - selector = BCON_NEW ("_id", BCON_INT32 (1)); - update = BCON_NEW ("$inc", "{", "x", BCON_INT32 (1), "}"); - update_opts = bson_new (); - if (!mongoc_client_session_append (client_session, update_opts, &error)) { - fprintf (stderr, "Could not add session to opts: %s\n", error.message); - goto done; - } - - r = mongoc_collection_update_one ( - collection, selector, update, update_opts, NULL /* reply */, &error); - - if (!r) { - fprintf (stderr, "Update failed: %s\n", error.message); - goto done; - } - - bson_destroy (selector); - selector = BCON_NEW ("_id", BCON_INT32 (1)); - secondary = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - find_opts = BCON_NEW ("maxTimeMS", BCON_INT32 (2000)); - if (!mongoc_client_session_append (client_session, find_opts, &error)) { - fprintf (stderr, "Could not add session to opts: %s\n", error.message); - goto done; - }; - - /* read from secondary. since we're in a causally consistent session, the - * data is guaranteed to reflect the update we did on the primary. the query - * blocks waiting for the secondary to catch up, if necessary, or times out - * and fails after 2000 ms. - */ - cursor = mongoc_collection_find_with_opts ( - collection, selector, find_opts, secondary); - - while (mongoc_cursor_next (cursor, &doc)) { - str = bson_as_json (doc, NULL); - fprintf (stdout, "%s\n", str); - bson_free (str); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "Cursor Failure: %s\n", error.message); - goto done; - } - - exit_code = EXIT_SUCCESS; - -done: - if (find_opts) { - bson_destroy (find_opts); - } - if (update) { - bson_destroy (update); - } - if (selector) { - bson_destroy (selector); - } - if (update_opts) { - bson_destroy (update_opts); - } - if (secondary) { - mongoc_read_prefs_destroy (secondary); - } - /* destroy cursor, collection, session before the client they came from */ - if (cursor) { - mongoc_cursor_destroy (cursor); - } - if (collection) { - mongoc_collection_destroy (collection); - } - if (client_session) { - mongoc_client_session_destroy (client_session); - } - if (uri) { - mongoc_uri_destroy (uri); - } - if (client) { - mongoc_client_destroy (client); - } - - mongoc_cleanup (); - - return exit_code; -} diff --git a/lib/mongoc/libmongoc/examples/example-start-at-optime.c b/lib/mongoc/libmongoc/examples/example-start-at-optime.c deleted file mode 100644 index 9330b1cb45d93e75f0e53b81d2b4b21f4de37ab4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-start-at-optime.c +++ /dev/null @@ -1,103 +0,0 @@ -/* An example of starting a change stream with startAtOperationTime. */ -#include <mongoc/mongoc.h> - -int -main () -{ - int exit_code = EXIT_FAILURE; - const char *uri_string; - mongoc_uri_t *uri = NULL; - bson_error_t error; - mongoc_client_t *client = NULL; - mongoc_collection_t *coll = NULL; - bson_t pipeline = BSON_INITIALIZER; - bson_t opts = BSON_INITIALIZER; - mongoc_change_stream_t *stream = NULL; - bson_iter_t iter; - const bson_t *doc; - bson_value_t cached_operation_time = {0}; - int i; - bool r; - - mongoc_init (); - uri_string = "mongodb://localhost:27017/db?replicaSet=rs0"; - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - goto cleanup; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - goto cleanup; - } - - /* insert five documents. */ - coll = mongoc_client_get_collection (client, "db", "coll"); - for (i = 0; i < 5; i++) { - bson_t reply; - bson_t *insert_cmd = BCON_NEW ("insert", - "coll", - "documents", - "[", - "{", - "x", - BCON_INT64 (i), - "}", - "]"); - - r = mongoc_collection_write_command_with_opts ( - coll, insert_cmd, NULL, &reply, &error); - bson_destroy (insert_cmd); - if (!r) { - bson_destroy (&reply); - fprintf (stderr, "failed to insert: %s\n", error.message); - goto cleanup; - } - if (i == 0) { - /* cache the operation time in the first reply. */ - if (bson_iter_init_find (&iter, &reply, "operationTime")) { - bson_value_copy (bson_iter_value (&iter), &cached_operation_time); - } else { - fprintf (stderr, "reply does not contain operationTime."); - bson_destroy (&reply); - goto cleanup; - } - } - bson_destroy (&reply); - } - - /* start a change stream at the first returned operationTime. */ - BSON_APPEND_VALUE (&opts, "startAtOperationTime", &cached_operation_time); - stream = mongoc_collection_watch (coll, &pipeline, &opts); - - /* since the change stream started at the operation time of the first - * insert, the five inserts are returned. */ - printf ("listening for changes on db.coll:\n"); - while (mongoc_change_stream_next (stream, &doc)) { - char *as_json; - - as_json = bson_as_canonical_extended_json (doc, NULL); - printf ("change received: %s\n", as_json); - bson_free (as_json); - } - - exit_code = EXIT_SUCCESS; - -cleanup: - mongoc_uri_destroy (uri); - bson_destroy (&pipeline); - bson_destroy (&opts); - if (cached_operation_time.value_type) { - bson_value_destroy (&cached_operation_time); - } - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mongoc_cleanup (); - return exit_code; -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/examples/example-transaction.c b/lib/mongoc/libmongoc/examples/example-transaction.c deleted file mode 100644 index 3977b4840d6c191fcbeb1870ee6061833a360d6f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-transaction.c +++ /dev/null @@ -1,180 +0,0 @@ -/* gcc example-transaction.c -o example-transaction \ - * $(pkg-config --cflags --libs libmongoc-1.0) */ - -/* ./example-transaction [CONNECTION_STRING] */ - -#include <stdio.h> -#include <mongoc/mongoc.h> - - -int -main (int argc, char *argv[]) -{ - int exit_code = EXIT_FAILURE; - - mongoc_client_t *client = NULL; - mongoc_database_t *database = NULL; - mongoc_collection_t *collection = NULL; - mongoc_client_session_t *session = NULL; - mongoc_session_opt_t *session_opts = NULL; - mongoc_transaction_opt_t *default_txn_opts = NULL; - mongoc_transaction_opt_t *txn_opts = NULL; - mongoc_read_concern_t *read_concern = NULL; - mongoc_write_concern_t *write_concern = NULL; - const char *uri_string = "mongodb://127.0.0.1/?appname=transaction-example"; - mongoc_uri_t *uri; - bson_error_t error; - bson_t *doc = NULL; - bson_t *insert_opts = NULL; - int32_t i; - int64_t start; - bson_t reply = BSON_INITIALIZER; - char *reply_json; - bool r; - - mongoc_init (); - - if (argc > 1) { - uri_string = argv[1]; - } - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - MONGOC_ERROR ("failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - goto done; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - goto done; - } - - mongoc_client_set_error_api (client, 2); - database = mongoc_client_get_database (client, "example-transaction"); - - /* inserting into a nonexistent collection normally creates it, but a - * collection can't be created in a transaction; create it now */ - collection = - mongoc_database_create_collection (database, "collection", NULL, &error); - - if (!collection) { - /* code 48 is NamespaceExists, see error_codes.err in mongodb source */ - if (error.code == 48) { - collection = mongoc_database_get_collection (database, "collection"); - } else { - MONGOC_ERROR ("Failed to create collection: %s", error.message); - goto done; - } - } - - /* a transaction's read preferences, read concern, and write concern can be - * set on the client, on the default transaction options, or when starting - * the transaction. for the sake of this example, set read concern on the - * default transaction options. */ - default_txn_opts = mongoc_transaction_opts_new (); - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, "snapshot"); - mongoc_transaction_opts_set_read_concern (default_txn_opts, read_concern); - session_opts = mongoc_session_opts_new (); - mongoc_session_opts_set_default_transaction_opts (session_opts, - default_txn_opts); - - session = mongoc_client_start_session (client, session_opts, &error); - if (!session) { - MONGOC_ERROR ("Failed to start session: %s", error.message); - goto done; - } - - /* in this example, set write concern when starting the transaction */ - txn_opts = mongoc_transaction_opts_new (); - write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_wmajority (write_concern, 1000 /* wtimeout */); - mongoc_transaction_opts_set_write_concern (txn_opts, write_concern); - - insert_opts = bson_new (); - if (!mongoc_client_session_append (session, insert_opts, &error)) { - MONGOC_ERROR ("Could not add session to opts: %s", error.message); - goto done; - } - -retry_transaction: - r = mongoc_client_session_start_transaction (session, txn_opts, &error); - if (!r) { - MONGOC_ERROR ("Failed to start transaction: %s", error.message); - goto done; - } - - /* insert two documents - on error, retry the whole transaction */ - for (i = 0; i < 2; i++) { - doc = BCON_NEW ("_id", BCON_INT32 (i)); - bson_destroy (&reply); - r = mongoc_collection_insert_one ( - collection, doc, insert_opts, &reply, &error); - - bson_destroy (doc); - - if (!r) { - MONGOC_ERROR ("Insert failed: %s", error.message); - mongoc_client_session_abort_transaction (session, NULL); - - /* a network error, primary failover, or other temporary error in a - * transaction includes {"errorLabels": ["TransientTransactionError"]}, - * meaning that trying the entire transaction again may succeed - */ - if (mongoc_error_has_label (&reply, "TransientTransactionError")) { - goto retry_transaction; - } - - goto done; - } - - reply_json = bson_as_json (&reply, NULL); - printf ("%s\n", reply_json); - bson_free (reply_json); - } - - /* in case of transient errors, retry for 5 seconds to commit transaction */ - start = bson_get_monotonic_time (); - while (bson_get_monotonic_time () - start < 5 * 1000 * 1000) { - bson_destroy (&reply); - r = mongoc_client_session_commit_transaction (session, &reply, &error); - if (r) { - /* success */ - break; - } else { - MONGOC_ERROR ("Warning: commit failed: %s", error.message); - if (mongoc_error_has_label (&reply, "TransientTransactionError")) { - goto retry_transaction; - } else if (mongoc_error_has_label (&reply, - "UnknownTransactionCommitResult")) { - /* try again to commit */ - continue; - } - - /* unrecoverable error trying to commit */ - break; - } - } - - exit_code = EXIT_SUCCESS; - -done: - bson_destroy (&reply); - bson_destroy (insert_opts); - mongoc_write_concern_destroy (write_concern); - mongoc_read_concern_destroy (read_concern); - mongoc_transaction_opts_destroy (txn_opts); - mongoc_transaction_opts_destroy (default_txn_opts); - mongoc_client_session_destroy (session); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return exit_code; -} diff --git a/lib/mongoc/libmongoc/examples/example-update.c b/lib/mongoc/libmongoc/examples/example-update.c deleted file mode 100644 index b24773e76a9571f28ebcd86cd0524bc3cc15078f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-update.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "mongoc/mongoc.h" - -int -main (int argc, char **argv) -{ - bson_t *to_insert = BCON_NEW ("_id", BCON_INT32 (1)); - bson_t *selector = BCON_NEW ("_id", "{", "$gt", BCON_INT32 (0), "}"); - bson_t *update = BCON_NEW ("$set", "{", "x", BCON_INT32 (1), "}"); - const bson_t *next_doc; - char *to_str; - bson_error_t error = {0}; - mongoc_cursor_t *cursor; - mongoc_client_t *client; - mongoc_collection_t *coll; - const char *uri_string = "mongodb://localhost:27017/?appname=example-update"; - mongoc_uri_t *uri = mongoc_uri_new_with_error (uri_string, &error); - - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - coll = mongoc_client_get_collection (client, "db", "example_coll"); - - mongoc_client_set_error_api (client, 2); - /* insert a document */ - if (!mongoc_collection_insert_one (coll, to_insert, NULL, NULL, &error)) { - fprintf (stderr, "insert failed: %s\n", error.message); - return EXIT_FAILURE; - } - - if (!mongoc_collection_update_one ( - coll, selector, update, NULL, NULL, &error)) { - fprintf (stderr, "update failed: %s\n", error.message); - return EXIT_FAILURE; - } - - to_str = bson_as_relaxed_extended_json (to_insert, NULL); - printf ("inserted: %s\n", to_str); - bson_free (to_str); - - cursor = mongoc_collection_find_with_opts (coll, selector, NULL, NULL); - BSON_ASSERT (mongoc_cursor_next (cursor, &next_doc)); - printf ("after update, collection has the following document:\n"); - - to_str = bson_as_relaxed_extended_json (next_doc, NULL); - printf ("%s\n", to_str); - bson_free (to_str); - - BSON_ASSERT (mongoc_collection_drop (coll, NULL)); - - bson_destroy (to_insert); - bson_destroy (update); - bson_destroy (selector); - mongoc_collection_destroy (coll); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/example-with-transaction-cb.c b/lib/mongoc/libmongoc/examples/example-with-transaction-cb.c deleted file mode 100644 index 10aa8afccd5af2e772c6b1018ac8d290f3fd40fd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/example-with-transaction-cb.c +++ /dev/null @@ -1,185 +0,0 @@ -/* gcc example-with-transaction-cb.c -o example-with-transaction-cb $(pkg-config - * --cflags --libs libmongoc-1.0) */ - -/* ./example-with-transaction-cb [CONNECTION_STRING] */ - -#include <mongoc/mongoc.h> -#include <stdio.h> -#include <stdlib.h> - -/* - * We pass this context object to mongoc_client_session_with_transaction() along - * with our callback function. The context object will be passed to our callback - * function when it runs, so we can access it. - */ -typedef struct { - mongoc_collection_t *collection; - bson_t *insert_opts; -} ctx_t; - -/* - * We pass this method as the callback to - * mongoc_client_session_with_transaction(). The insert that this method - * performs will happen inside of a new transaction. - */ -bool -create_and_insert_doc (mongoc_client_session_t *session, - void *ctx, - bson_t **reply, /* out param for our server reply */ - bson_error_t *error) -{ - /* - * mongoc_collection_insert_one requires an uninitialized, stack-allocated - * bson_t to receive the update result - */ - bson_t local_reply; - bson_t *doc = NULL; - ctx_t *data = NULL; - bool retval; - - /* - * Create a new bson document - { id: 1 } - */ - doc = BCON_NEW ("_id", BCON_INT32 (1)); - - printf ( - "Running the user-defined callback in a newly created transaction...\n"); - data = (ctx_t *) ctx; - retval = mongoc_collection_insert_one ( - data->collection, doc, data->insert_opts, &local_reply, error); - - /* - * To return to the mongoc_client_session_with_transaction() method, set - * *reply to a new copy of our local_reply before destroying it. - */ - *reply = bson_copy (&local_reply); - bson_destroy (&local_reply); - - bson_destroy (doc); - return retval; -} - -int -main (int argc, char *argv[]) -{ - int exit_code = EXIT_FAILURE; - - mongoc_uri_t *uri = NULL; - const char *uri_string = "mongodb://127.0.0.1/?appname=with-txn-cb-example"; - mongoc_client_t *client = NULL; - mongoc_database_t *database = NULL; - mongoc_collection_t *collection = NULL; - mongoc_client_session_t *session = NULL; - bson_t *insert_opts = NULL; - bson_t reply; - ctx_t ctx; - char *str; - bson_error_t error; - - /* - * Required to initialize libmongoc's internals - */ - mongoc_init (); - - /* - * Optionally get MongoDB URI from command line - */ - if (argc > 1) { - uri_string = argv[1]; - } - - /* - * Safely create a MongoDB URI object from the given string - */ - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - MONGOC_ERROR ("failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - goto done; - } - - /* - * Create a new client instance - */ - client = mongoc_client_new_from_uri (uri); - if (!client) { - goto done; - } - - mongoc_client_set_error_api (client, 2); - - /* - * Get a handle on the database "example-with-txn-cb" - */ - database = mongoc_client_get_database (client, "example-with-txn-cb"); - - /* - * Inserting into a nonexistent collection normally creates it, but a - * collection can't be created in a transaction; create it now - */ - collection = - mongoc_database_create_collection (database, "collection", NULL, &error); - if (!collection) { - /* code 48 is NamespaceExists, see error_codes.err in mongodb source */ - if (error.code == 48) { - collection = mongoc_database_get_collection (database, "collection"); - } else { - MONGOC_ERROR ("Failed to create collection: %s", error.message); - goto done; - } - } - - /* - * Pass NULL for options - by default the session is causally consistent - */ - session = mongoc_client_start_session (client, NULL, &error); - if (!session) { - MONGOC_ERROR ("Failed to start session: %s", error.message); - goto done; - } - - /* - * Append a logical session id to command options - */ - insert_opts = bson_new (); - if (!mongoc_client_session_append (session, insert_opts, &error)) { - MONGOC_ERROR ("Could not add session to opts: %s", error.message); - goto done; - } - - ctx.collection = collection; - ctx.insert_opts = insert_opts; - - /* - * This method will start a new transaction on session, run our callback - * function, i.e., &create_and_insert_doc, passing &ctx as an argument and - * commit the transaction. - */ - if (!mongoc_client_session_with_transaction ( - session, &create_and_insert_doc, NULL, &ctx, &reply, &error)) { - MONGOC_ERROR ("Insert failed: %s", error.message); - goto done; - } - - str = bson_as_json (&reply, NULL); - printf ("%s\n", str); - - exit_code = EXIT_SUCCESS; - -done: - bson_free (str); - bson_destroy (&reply); - bson_destroy (insert_opts); - mongoc_client_session_destroy (session); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - - mongoc_cleanup (); - - return exit_code; -} - diff --git a/lib/mongoc/libmongoc/examples/find-and-modify.c b/lib/mongoc/libmongoc/examples/find-and-modify.c deleted file mode 100644 index f8b916d41e3fdf32da4ccc508f1e24a775f4e482..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/find-and-modify.c +++ /dev/null @@ -1,86 +0,0 @@ -#include <mongoc/mongoc.h> -#include <stdio.h> - - -int -main (int argc, char *argv[]) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - const char *uri_string = - "mongodb://127.0.0.1:27017/?appname=find-and-modify-example"; - mongoc_uri_t *uri; - bson_error_t error; - bson_t *query; - bson_t *update; - bson_t reply; - char *str; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "test", "test"); - - /* - * Build our query, {"cmpxchg": 1} - */ - query = BCON_NEW ("cmpxchg", BCON_INT32 (1)); - - /* - * Build our update. {"$set": {"cmpxchg": 2}} - */ - update = BCON_NEW ("$set", "{", "cmpxchg", BCON_INT32 (2), "}"); - - /* - * Submit the findAndModify. - */ - if (!mongoc_collection_find_and_modify (collection, - query, - NULL, - update, - NULL, - false, - false, - true, - &reply, - &error)) { - fprintf (stderr, "find_and_modify() failure: %s\n", error.message); - return EXIT_FAILURE; - } - - /* - * Print the result as JSON. - */ - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - - /* - * Cleanup. - */ - bson_destroy (query); - bson_destroy (update); - bson_destroy (&reply); - mongoc_collection_destroy (collection); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/find_and_modify_with_opts/fam.c b/lib/mongoc/libmongoc/examples/find_and_modify_with_opts/fam.c deleted file mode 100644 index 711a05d2b7088bb50ee7f8e2a9bcdfbcfc00ea89..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/find_and_modify_with_opts/fam.c +++ /dev/null @@ -1,382 +0,0 @@ - -#include <mongoc/mongoc.h> - -/* EXAMPLE_FAM_BYPASS_BEGIN */ -void -fam_bypass (mongoc_collection_t *collection) -{ - mongoc_find_and_modify_opts_t *opts; - bson_t reply; - bson_t *update; - bson_error_t error; - bson_t query = BSON_INITIALIZER; - bool success; - - - /* Find Zlatan Ibrahimovic, the striker */ - BSON_APPEND_UTF8 (&query, "firstname", "Zlatan"); - BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic"); - BSON_APPEND_UTF8 (&query, "profession", "Football player"); - - /* Bump his age */ - update = BCON_NEW ("$inc", "{", "age", BCON_INT32 (1), "}"); - - opts = mongoc_find_and_modify_opts_new (); - mongoc_find_and_modify_opts_set_update (opts, update); - /* He can still play, even though he is pretty old. */ - mongoc_find_and_modify_opts_set_bypass_document_validation (opts, true); - - success = mongoc_collection_find_and_modify_with_opts ( - collection, &query, opts, &reply, &error); - - if (success) { - char *str; - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - } else { - fprintf ( - stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__); - } - - bson_destroy (&reply); - bson_destroy (update); - bson_destroy (&query); - mongoc_find_and_modify_opts_destroy (opts); -} -/* EXAMPLE_FAM_BYPASS_END */ - -/* EXAMPLE_FAM_FLAGS_BEGIN */ -void -fam_flags (mongoc_collection_t *collection) -{ - mongoc_find_and_modify_opts_t *opts; - bson_t reply; - bson_error_t error; - bson_t query = BSON_INITIALIZER; - bson_t *update; - bool success; - - - /* Find Zlatan Ibrahimovic, the striker */ - BSON_APPEND_UTF8 (&query, "firstname", "Zlatan"); - BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic"); - BSON_APPEND_UTF8 (&query, "profession", "Football player"); - BSON_APPEND_INT32 (&query, "age", 34); - BSON_APPEND_INT32 ( - &query, "goals", (16 + 35 + 23 + 57 + 16 + 14 + 28 + 84) + (1 + 6 + 62)); - - /* Add his football position */ - update = BCON_NEW ("$set", "{", "position", BCON_UTF8 ("striker"), "}"); - - opts = mongoc_find_and_modify_opts_new (); - - mongoc_find_and_modify_opts_set_update (opts, update); - - /* Create the document if it didn't exist, and return the updated document */ - mongoc_find_and_modify_opts_set_flags ( - opts, MONGOC_FIND_AND_MODIFY_UPSERT | MONGOC_FIND_AND_MODIFY_RETURN_NEW); - - success = mongoc_collection_find_and_modify_with_opts ( - collection, &query, opts, &reply, &error); - - if (success) { - char *str; - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - } else { - fprintf ( - stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__); - } - - bson_destroy (&reply); - bson_destroy (update); - bson_destroy (&query); - mongoc_find_and_modify_opts_destroy (opts); -} -/* EXAMPLE_FAM_FLAGS_END */ - -/* EXAMPLE_FAM_UPDATE_BEGIN */ -void -fam_update (mongoc_collection_t *collection) -{ - mongoc_find_and_modify_opts_t *opts; - bson_t *update; - bson_t reply; - bson_error_t error; - bson_t query = BSON_INITIALIZER; - bool success; - - - /* Find Zlatan Ibrahimovic */ - BSON_APPEND_UTF8 (&query, "firstname", "Zlatan"); - BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic"); - - /* Make him a book author */ - update = BCON_NEW ("$set", "{", "author", BCON_BOOL (true), "}"); - - opts = mongoc_find_and_modify_opts_new (); - /* Note that the document returned is the _previous_ version of the document - * To fetch the modified new version, use - * mongoc_find_and_modify_opts_set_flags (opts, - * MONGOC_FIND_AND_MODIFY_RETURN_NEW); - */ - mongoc_find_and_modify_opts_set_update (opts, update); - - success = mongoc_collection_find_and_modify_with_opts ( - collection, &query, opts, &reply, &error); - - if (success) { - char *str; - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - } else { - fprintf ( - stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__); - } - - bson_destroy (&reply); - bson_destroy (update); - bson_destroy (&query); - mongoc_find_and_modify_opts_destroy (opts); -} -/* EXAMPLE_FAM_UPDATE_END */ - -/* EXAMPLE_FAM_FIELDS_BEGIN */ -void -fam_fields (mongoc_collection_t *collection) -{ - mongoc_find_and_modify_opts_t *opts; - bson_t fields = BSON_INITIALIZER; - bson_t *update; - bson_t reply; - bson_error_t error; - bson_t query = BSON_INITIALIZER; - bool success; - - - /* Find Zlatan Ibrahimovic */ - BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic"); - BSON_APPEND_UTF8 (&query, "firstname", "Zlatan"); - - /* Return his goal tally */ - BSON_APPEND_INT32 (&fields, "goals", 1); - - /* Bump his goal tally */ - update = BCON_NEW ("$inc", "{", "goals", BCON_INT32 (1), "}"); - - opts = mongoc_find_and_modify_opts_new (); - mongoc_find_and_modify_opts_set_update (opts, update); - mongoc_find_and_modify_opts_set_fields (opts, &fields); - /* Return the new tally */ - mongoc_find_and_modify_opts_set_flags (opts, - MONGOC_FIND_AND_MODIFY_RETURN_NEW); - - success = mongoc_collection_find_and_modify_with_opts ( - collection, &query, opts, &reply, &error); - - if (success) { - char *str; - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - } else { - fprintf ( - stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__); - } - - bson_destroy (&reply); - bson_destroy (update); - bson_destroy (&fields); - bson_destroy (&query); - mongoc_find_and_modify_opts_destroy (opts); -} -/* EXAMPLE_FAM_FIELDS_END */ - -/* EXAMPLE_FAM_OPTS_BEGIN */ -void -fam_opts (mongoc_collection_t *collection) -{ - mongoc_find_and_modify_opts_t *opts; - bson_t reply; - bson_t *update; - bson_error_t error; - bson_t query = BSON_INITIALIZER; - mongoc_write_concern_t *wc; - bson_t extra = BSON_INITIALIZER; - bool success; - - - /* Find Zlatan Ibrahimovic, the striker */ - BSON_APPEND_UTF8 (&query, "firstname", "Zlatan"); - BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic"); - BSON_APPEND_UTF8 (&query, "profession", "Football player"); - - /* Bump his age */ - update = BCON_NEW ("$inc", "{", "age", BCON_INT32 (1), "}"); - - opts = mongoc_find_and_modify_opts_new (); - mongoc_find_and_modify_opts_set_update (opts, update); - - /* Abort if the operation takes too long. */ - mongoc_find_and_modify_opts_set_max_time_ms (opts, 100); - - /* Set write concern w: 2 */ - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_write_concern_append (wc, &extra); - - /* Some future findAndModify option the driver doesn't support conveniently - */ - BSON_APPEND_INT32 (&extra, "futureOption", 42); - mongoc_find_and_modify_opts_append (opts, &extra); - - success = mongoc_collection_find_and_modify_with_opts ( - collection, &query, opts, &reply, &error); - - if (success) { - char *str; - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - } else { - fprintf ( - stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__); - } - - bson_destroy (&reply); - bson_destroy (&extra); - bson_destroy (update); - bson_destroy (&query); - mongoc_write_concern_destroy (wc); - mongoc_find_and_modify_opts_destroy (opts); -} -/* EXAMPLE_FAM_OPTS_END */ - -/* EXAMPLE_FAM_SORT_BEGIN */ -void -fam_sort (mongoc_collection_t *collection) -{ - mongoc_find_and_modify_opts_t *opts; - bson_t *update; - bson_t sort = BSON_INITIALIZER; - bson_t reply; - bson_error_t error; - bson_t query = BSON_INITIALIZER; - bool success; - - - /* Find all users with the lastname Ibrahimovic */ - BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic"); - - /* Sort by age (descending) */ - BSON_APPEND_INT32 (&sort, "age", -1); - - /* Bump his goal tally */ - update = BCON_NEW ("$set", "{", "oldest", BCON_BOOL (true), "}"); - - opts = mongoc_find_and_modify_opts_new (); - mongoc_find_and_modify_opts_set_update (opts, update); - mongoc_find_and_modify_opts_set_sort (opts, &sort); - - success = mongoc_collection_find_and_modify_with_opts ( - collection, &query, opts, &reply, &error); - - if (success) { - char *str; - - str = bson_as_canonical_extended_json (&reply, NULL); - printf ("%s\n", str); - bson_free (str); - } else { - fprintf ( - stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__); - } - - bson_destroy (&reply); - bson_destroy (update); - bson_destroy (&sort); - bson_destroy (&query); - mongoc_find_and_modify_opts_destroy (opts); -} -/* EXAMPLE_FAM_SORT_END */ - -/* EXAMPLE_FAM_MAIN_BEGIN */ -int -main (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - const char *uri_string = - "mongodb://localhost:27017/admin?appname=find-and-modify-opts-example"; - mongoc_uri_t *uri; - bson_error_t error; - bson_t *options; - - mongoc_init (); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - database = mongoc_client_get_database (client, "databaseName"); - - options = BCON_NEW ("validator", - "{", - "age", - "{", - "$lte", - BCON_INT32 (34), - "}", - "}", - "validationAction", - BCON_UTF8 ("error"), - "validationLevel", - BCON_UTF8 ("moderate")); - - collection = mongoc_database_create_collection ( - database, "collectionName", options, &error); - if (!collection) { - fprintf ( - stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__); - return EXIT_FAILURE; - } - - fam_flags (collection); - fam_bypass (collection); - fam_update (collection); - fam_fields (collection); - fam_opts (collection); - fam_sort (collection); - - mongoc_collection_drop (collection, NULL); - bson_destroy (options); - mongoc_uri_destroy (uri); - mongoc_database_destroy (database); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mongoc_cleanup (); - return EXIT_SUCCESS; -} -/* EXAMPLE_FAM_MAIN_END */ diff --git a/lib/mongoc/libmongoc/examples/hello_mongoc.c b/lib/mongoc/libmongoc/examples/hello_mongoc.c deleted file mode 100644 index d6ede67cacae1b07b4cf44144a7e325b6d646c24..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/hello_mongoc.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/* -- sphinx-include-start -- */ -#include <mongoc/mongoc.h> - -int -main (int argc, char *argv[]) -{ - const char *uri_string = "mongodb://localhost:27017"; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_database_t *database; - mongoc_collection_t *collection; - bson_t *command, reply, *insert; - bson_error_t error; - char *str; - bool retval; - - /* - * Required to initialize libmongoc's internals - */ - mongoc_init (); - - /* - * Optionally get MongoDB URI from command line - */ - if (argc > 1) { - uri_string = argv[1]; - } - - /* - * Safely create a MongoDB URI object from the given string - */ - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - /* - * Create a new client instance - */ - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - /* - * Register the application name so we can track it in the profile logs - * on the server. This can also be done from the URI (see other examples). - */ - mongoc_client_set_appname (client, "connect-example"); - - /* - * Get a handle on the database "db_name" and collection "coll_name" - */ - database = mongoc_client_get_database (client, "db_name"); - collection = mongoc_client_get_collection (client, "db_name", "coll_name"); - - /* - * Do work. This example pings the database, prints the result as JSON and - * performs an insert - */ - command = BCON_NEW ("ping", BCON_INT32 (1)); - - retval = mongoc_client_command_simple ( - client, "admin", command, NULL, &reply, &error); - - if (!retval) { - fprintf (stderr, "%s\n", error.message); - return EXIT_FAILURE; - } - - str = bson_as_json (&reply, NULL); - printf ("%s\n", str); - - insert = BCON_NEW ("hello", BCON_UTF8 ("world")); - - if (!mongoc_collection_insert_one (collection, insert, NULL, NULL, &error)) { - fprintf (stderr, "%s\n", error.message); - } - - bson_destroy (insert); - bson_destroy (&reply); - bson_destroy (command); - bson_free (str); - - /* - * Release our handles and clean up libmongoc - */ - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - mongoc_cleanup (); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/mongoc-dump.c b/lib/mongoc/libmongoc/examples/mongoc-dump.c deleted file mode 100644 index dd53f59d844d104dc2cafaac71a43e11231d3624..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/mongoc-dump.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2014 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 <bson/bson.h> -#include <fcntl.h> -#include <mongoc/mongoc.h> - - -static bool -mongoc_dump_mkdir_p (const char *path, int mode) -{ - int r; - -#ifdef _WIN32 - r = _mkdir (path); -#else - r = mkdir (path, mode); -#endif - - return (r == 0 || errno == EEXIST); -} - - -static int -mongoc_dump_collection (mongoc_client_t *client, - const char *database, - const char *collection) -{ - mongoc_collection_t *col; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - bson_t query = BSON_INITIALIZER; - FILE *stream; - char *path; - int ret = EXIT_SUCCESS; - - path = bson_strdup_printf ("dump/%s/%s.bson", database, collection); -#ifdef _WIN32 - _unlink (path); -#else - unlink (path); -#endif - - stream = fopen (path, "w"); - if (!stream) { - fprintf (stderr, "Failed to open \"%s\", aborting.\n", path); - exit (EXIT_FAILURE); - } - - col = mongoc_client_get_collection (client, database, collection); - cursor = mongoc_collection_find_with_opts (col, &query, NULL, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - if (BSON_UNLIKELY (doc->len != - fwrite (bson_get_data (doc), 1, doc->len, stream))) { - fprintf (stderr, "Failed to write %u bytes to %s\n", doc->len, path); - ret = EXIT_FAILURE; - goto cleanup; - } - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "ERROR: %s\n", error.message); - ret = EXIT_FAILURE; - } - -cleanup: - bson_free (path); - fclose (stream); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (col); - - return ret; -} - - -static int -mongoc_dump_database (mongoc_client_t *client, - const char *database, - const char *collection) -{ - mongoc_database_t *db; - bson_error_t error; - char *path; - char **str; - int ret = EXIT_SUCCESS; - int i; - - BSON_ASSERT (database); - - path = bson_strdup_printf ("dump/%s", database); - if (!mongoc_dump_mkdir_p (path, 0750)) { - fprintf (stderr, "failed to create directory \"%s\"", path); - bson_free (path); - return EXIT_FAILURE; - } - - bson_free (path); - - if (collection) { - return mongoc_dump_collection (client, database, collection); - } - - db = mongoc_client_get_database (client, database); - str = mongoc_database_get_collection_names_with_opts (db, NULL, &error); - for (i = 0; str[i]; i++) { - if (EXIT_SUCCESS != mongoc_dump_collection (client, database, str[i])) { - ret = EXIT_FAILURE; - goto cleanup; - } - } - -cleanup: - mongoc_database_destroy (db); - bson_strfreev (str); - - return ret; -} - - -static int -mongoc_dump (mongoc_client_t *client, - const char *database, - const char *collection) -{ - bson_error_t error; - char **str; - int i; - - if (!mongoc_dump_mkdir_p ("dump", 0750)) { - perror ("Failed to create directory \"dump\""); - return EXIT_FAILURE; - } - - if (database) { - return mongoc_dump_database (client, database, collection); - } - - if (!(str = mongoc_client_get_database_names_with_opts ( - client, NULL, &error))) { - fprintf (stderr, "Failed to fetch database names: %s\n", error.message); - return EXIT_FAILURE; - } - - for (i = 0; str[i]; i++) { - if (EXIT_SUCCESS != mongoc_dump_database (client, str[i], NULL)) { - bson_strfreev (str); - return EXIT_FAILURE; - } - } - - bson_strfreev (str); - - return EXIT_SUCCESS; -} - - -static void -usage (FILE *stream) -{ - fprintf (stream, - "Usage: mongoc-dump [OPTIONS]\n" - "\n" - "Options:\n" - "\n" - " -h HOST Optional hostname to connect to [127.0.0.1].\n" - " -p PORT Optional port to connect to [27017].\n" - " -d DBNAME Optional database name to dump.\n" - " -c COLNAME Optional collection name to dump.\n" - " --ssl Use SSL when connecting to server.\n" - "\n"); -} - - -int -main (int argc, char *argv[]) -{ - mongoc_client_t *client; - const char *collection = NULL; - const char *database = NULL; - const char *host = "127.0.0.1"; - uint16_t port = 27017; - bool ssl = false; - char *uri_string; - mongoc_uri_t *uri; - bson_error_t error; - int ret; - int i; - - mongoc_init (); - - for (i = 1; i < argc; i++) { - if (0 == strcmp (argv[i], "-c") && ((i + 1) < argc)) { - collection = argv[++i]; - } else if (0 == strcmp (argv[i], "-d") && ((i + 1) < argc)) { - database = argv[++i]; - } else if (0 == strcmp (argv[i], "--help")) { - usage (stdout); - return EXIT_SUCCESS; - } else if (0 == strcmp (argv[i], "-h") && ((i + 1) < argc)) { - host = argv[++i]; - } else if (0 == strcmp (argv[i], "--ssl")) { - ssl = true; - } else if (0 == strcmp (argv[i], "-p") && ((i + 1) < argc)) { - port = atoi (argv[++i]); - if (!port) { - fprintf (stderr, "Invalid port \"%s\"", argv[i]); - return EXIT_FAILURE; - } - } else { - fprintf (stderr, "Unknown argument \"%s\"\n", argv[i]); - return EXIT_FAILURE; - } - } - - uri_string = - bson_strdup_printf ("mongodb://%s:%hu/%s?appname=dump-example&ssl=%s", - host, - port, - database ? database : "", - ssl ? "true" : "false"); - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - uri_string, - error.message); - return EXIT_FAILURE; - } - - if (!(client = mongoc_client_new_from_uri (uri))) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - - ret = mongoc_dump (client, database, collection); - - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - return ret; -} diff --git a/lib/mongoc/libmongoc/examples/mongoc-ping.c b/lib/mongoc/libmongoc/examples/mongoc-ping.c deleted file mode 100644 index 9901d54ac2427ef96de9bd6e8d64f7e31e23fed4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/mongoc-ping.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2013-2014 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 <mongoc/mongoc.h> -#include <stdio.h> - - -int -main (int argc, char *argv[]) -{ - mongoc_database_t *database; - mongoc_client_t *client; - bson_t reply; - uint16_t port; - bson_error_t error; - bson_t ping; - char *host_and_port; - mongoc_uri_t *uri; - char *str; - bool r; - - if (argc < 2 || argc > 3) { - fprintf (stderr, "usage: %s HOSTNAME [PORT]\n", argv[0]); - return EXIT_FAILURE; - } - - mongoc_init (); - - port = (argc == 3) ? atoi (argv[2]) : 27017; - - if (!strncmp (argv[1], "mongodb://", 10) || - !strncmp (argv[1], "mongodb+srv://", 14)) { - host_and_port = bson_strdup (argv[1]); - } else { - host_and_port = bson_strdup_printf ("mongodb://%s:%hu", argv[1], port); - } - - uri = mongoc_uri_new_with_error (host_and_port, &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - host_and_port, - error.message); - return EXIT_FAILURE; - } - bson_free (host_and_port); - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - - bson_init (&ping); - bson_append_int32 (&ping, "ping", 4, 1); - database = mongoc_client_get_database (client, "test"); - r = mongoc_database_command_with_opts ( - database, &ping, NULL, NULL, &reply, &error); - - if (r) { - str = bson_as_canonical_extended_json (&reply, NULL); - fprintf (stdout, "%s\n", str); - bson_free (str); - } else { - fprintf (stderr, "Ping failure: %s\n", error.message); - } - - bson_destroy (&ping); - bson_destroy (&reply); - mongoc_database_destroy (database); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - return r ? 0 : 3; -} diff --git a/lib/mongoc/libmongoc/examples/mongoc-tail.c b/lib/mongoc/libmongoc/examples/mongoc-tail.c deleted file mode 100644 index aa1d1828133da460eab932e6a424cc558d204c89..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/mongoc-tail.c +++ /dev/null @@ -1,129 +0,0 @@ -#include <bson/bson.h> -#include <mongoc/mongoc.h> -#include <stdio.h> -#include <stdlib.h> - -#ifdef _WIN32 -#define sleep(_n) Sleep ((_n) *1000) -#endif - - -static void -print_bson (const bson_t *b) -{ - char *str; - - str = bson_as_canonical_extended_json (b, NULL); - fprintf (stdout, "%s\n", str); - bson_free (str); -} - - -static mongoc_cursor_t * -query_collection (mongoc_collection_t *collection, uint32_t last_time) -{ - mongoc_cursor_t *cursor; - bson_t query; - bson_t gt; - bson_t opts; - - BSON_ASSERT (collection); - - bson_init (&query); - BSON_APPEND_DOCUMENT_BEGIN (&query, "ts", >); - BSON_APPEND_TIMESTAMP (>, "$gt", last_time, 0); - bson_append_document_end (&query, >); - - bson_init (&opts); - BSON_APPEND_BOOL (&opts, "tailable", true); - BSON_APPEND_BOOL (&opts, "awaitData", true); - - cursor = mongoc_collection_find_with_opts (collection, &query, &opts, NULL); - - bson_destroy (&query); - bson_destroy (&opts); - - return cursor; -} - - -static void -tail_collection (mongoc_collection_t *collection) -{ - mongoc_cursor_t *cursor; - uint32_t last_time; - const bson_t *doc; - bson_error_t error; - bson_iter_t iter; - - BSON_ASSERT (collection); - - last_time = (uint32_t) time (NULL); - - while (true) { - cursor = query_collection (collection, last_time); - while (!mongoc_cursor_error (cursor, &error) && - mongoc_cursor_more (cursor)) { - if (mongoc_cursor_next (cursor, &doc)) { - if (bson_iter_init_find (&iter, doc, "ts") && - BSON_ITER_HOLDS_TIMESTAMP (&iter)) { - bson_iter_timestamp (&iter, &last_time, NULL); - } - print_bson (doc); - } - } - if (mongoc_cursor_error (cursor, &error)) { - if (error.domain == MONGOC_ERROR_SERVER) { - fprintf (stderr, "%s\n", error.message); - exit (1); - } - } - - mongoc_cursor_destroy (cursor); - sleep (1); - } -} - - -int -main (int argc, char *argv[]) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_uri_t *uri; - bson_error_t error; - - if (argc != 2) { - fprintf (stderr, "usage: %s MONGO_URI\n", argv[0]); - return EXIT_FAILURE; - } - - mongoc_init (); - - uri = mongoc_uri_new_with_error (argv[1], &error); - if (!uri) { - fprintf (stderr, - "failed to parse URI: %s\n" - "error message: %s\n", - argv[1], - error.message); - return EXIT_FAILURE; - } - - client = mongoc_client_new_from_uri (uri); - if (!client) { - return EXIT_FAILURE; - } - - mongoc_client_set_error_api (client, 2); - - collection = mongoc_client_get_collection (client, "local", "oplog.rs"); - - tail_collection (collection); - - mongoc_collection_destroy (collection); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - - return EXIT_SUCCESS; -} diff --git a/lib/mongoc/libmongoc/examples/parse_handshake_cfg.py b/lib/mongoc/libmongoc/examples/parse_handshake_cfg.py deleted file mode 100644 index f8ca6d62d2ae5ae8f91b3c71b8e79a7142ba49f7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/examples/parse_handshake_cfg.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys - -# Should be in EXACT same order as from src/mongoc/mongoc-handshake-private.h. -# The values are implicit (so we assume 1st entry is 1 << 0, -# second entry is 1 << 1 and so on). -MD_FLAGS = [ - "MONGOC_MD_FLAG_ENABLE_CRYPTO", - "MONGOC_MD_FLAG_ENABLE_CRYPTO_CNG", - "MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO", - "MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO", - "MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE", - "MONGOC_MD_FLAG_ENABLE_SASL", - "MONGOC_MD_FLAG_ENABLE_SSL", - "MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL", - "MONGOC_MD_FLAG_ENABLE_SSL_SECURE_CHANNEL", - "MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT", - "MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES", - "MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE", - "MONGOC_MD_FLAG_HAVE_WEAK_SYMBOLS", - "MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS", - "MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL", - "MONGOC_MD_FLAG_ENABLE_SASL_CYRUS", - "MONGOC_MD_FLAG_ENABLE_SASL_SSPI", - "MONGOC_MD_FLAG_HAVE_SOCKLEN", - "MONGOC_MD_FLAG_ENABLE_COMPRESSION", - "MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY", - "MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB", - "MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI", - "MONGOC_MD_FLAG_ENABLE_RES_NSEARCH", - "MONGOC_MD_FLAG_ENABLE_RES_NDESTROY", - "MONGOC_MD_FLAG_ENABLE_RES_NCLOSE", - "MONGOC_MD_FLAG_ENABLE_RES_SEARCH", - "MONGOC_MD_FLAG_ENABLE_DNSAPI", - "MONGOC_MD_FLAG_ENABLE_RDTSCP", - "MONGOC_MD_FLAG_HAVE_SCHED_GETCPU", - "MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS", - "MONGOC_MD_FLAG_TRACE", - "MONGOC_MD_FLAG_ENABLE_ICU", - "MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION" -] - -def main(): - flag_to_number = {s: 2 ** i for i,s in enumerate(MD_FLAGS)} - - if len(sys.argv) < 2: - print "Usage: python {0} config-bitfield".format(sys.argv[0]) - print "Example: python parse_handshake_cfg.py 0x3e65" - return - - config_bitfield_string = sys.argv[1] - config_bitfield_num = int(config_bitfield_string, 0) - print "Decimal value: {}".format(config_bitfield_num) - - for flag, num in flag_to_number.iteritems(): - v = "true" if config_bitfield_num & num else "false" - print "{:<50}: {}".format(flag, v) - -if __name__ == "__main__": - main() diff --git a/lib/mongoc/libmongoc/src/CMakeLists.txt b/lib/mongoc/libmongoc/src/CMakeLists.txt deleted file mode 100644 index 9fcc323a444a9c9f49b4604ab7393af9e19e8f6f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -add_subdirectory (mongoc) - -set_local_dist (src_libmongoc_src_DIST_local - CMakeLists.txt - libmongoc-1.0.pc.in - libmongoc-ssl-1.0.pc.in - libmongoc-static-1.0.pc.in - mongoc-config.cmake -) - -set (src_libmongoc_src_DIST - ${src_libmongoc_src_DIST_local} - ${src_libmongoc_src_mongoc_DIST} - PARENT_SCOPE -) - diff --git a/lib/mongoc/libmongoc/src/libmongoc-1.0.pc.in b/lib/mongoc/libmongoc/src/libmongoc-1.0.pc.in deleted file mode 100644 index 1b489d86ce7569430301a4ba38fc57b0e5a049fc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/libmongoc-1.0.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=${prefix} -libdir=@libdir@ -includedir=${exec_prefix}/include - -Name: libmongoc -Description: The libmongoc MongoDB client library. -Version: @VERSION@ -Requires: libbson-1.0 -Libs: -L${libdir} -lmongoc-1.0 -Cflags: -I${includedir}/libmongoc-@MONGOC_API_VERSION@ diff --git a/lib/mongoc/libmongoc/src/libmongoc-ssl-1.0.pc.in b/lib/mongoc/libmongoc/src/libmongoc-ssl-1.0.pc.in deleted file mode 100644 index a1887ab94cb63dcf3bc31d4a95f5f1c331b9635b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/libmongoc-ssl-1.0.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=${prefix} -libdir=@libdir@ -includedir=${exec_prefix}/include - -Name: libmongoc-@MONGOC_API_VERSION@ -Description: SSL support for the libmongoc-@MONGOC_API_VERSION@ library. -Version: @VERSION@ -Requires: libmongoc-1.0 -Libs: -Cflags: diff --git a/lib/mongoc/libmongoc/src/libmongoc-static-1.0.pc.in b/lib/mongoc/libmongoc/src/libmongoc-static-1.0.pc.in deleted file mode 100644 index d59ee64478e842e1f9dc239ff7879061a7075da2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/libmongoc-static-1.0.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=${prefix} -libdir=@libdir@ -includedir=${exec_prefix}/include - -Name: libmongoc -Description: The libmongoc MongoDB client library. -Version: @VERSION@ -Requires: libbson-static-1.0 -Libs: -L${libdir} -lmongoc-static-1.0 @MONGOC_LIBRARIES@ -Cflags: -I${includedir}/libmongoc-@MONGOC_API_VERSION@ -DMONGOC_STATIC diff --git a/lib/mongoc/libmongoc/src/mongoc-config.cmake b/lib/mongoc/libmongoc/src/mongoc-config.cmake deleted file mode 100644 index 7fe7cf42dd7801cceb708a9902af2287666034d7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc-config.cmake +++ /dev/null @@ -1,3 +0,0 @@ -include(CMakeFindDependencyMacro) -find_dependency(bson-1.0 @MONGOC_MAJOR_VERSION@.@MONGOC_MINOR_VERSION@.@MONGOC_MICRO_VERSION@) -include("${CMAKE_CURRENT_LIST_DIR}/mongoc-targets.cmake") diff --git a/lib/mongoc/libmongoc/src/mongoc/.gitignore b/lib/mongoc/libmongoc/src/mongoc/.gitignore deleted file mode 100644 index 1b730d78be071de06c0d74de9a594731b5de622f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -mongoc-config.h -mongoc-version.h diff --git a/lib/mongoc/libmongoc/src/mongoc/CMakeLists.txt b/lib/mongoc/libmongoc/src/mongoc/CMakeLists.txt deleted file mode 100644 index 01b958c44ca9b64d9b51fd3966a65e8844c1e47e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/CMakeLists.txt +++ /dev/null @@ -1,272 +0,0 @@ -set (src_libmongoc_src_mongoc_DIST_defs - op-delete.def - op-get-more.def - op-header.def - op-insert.def - op-kill-cursors.def - op-msg.def - op-query.def - op-reply.def - op-reply-header.def - op-update.def - op-compressed.def - mongoc-counters.defs -) - -set (src_libmongoc_src_mongoc_DIST_hs - mongoc-apm.h - mongoc-bulk-operation.h - mongoc-change-stream.h - mongoc-client.h - mongoc-client-pool.h - mongoc-client-side-encryption.h - mongoc-collection.h - mongoc-cursor.h - mongoc-database.h - mongoc-error.h - mongoc-find-and-modify.h - mongoc-flags.h - mongoc-gridfs-bucket.h - mongoc-gridfs-file.h - mongoc-gridfs-file-list.h - mongoc-gridfs-file-page.h - mongoc-gridfs.h - mongoc.h - mongoc-handshake.h - mongoc-host-list.h - mongoc-index.h - mongoc-init.h - mongoc-iovec.h - mongoc-log.h - mongoc-macros.h - mongoc-matcher.h - mongoc-opcode.h - mongoc-prelude.h - mongoc-rand.h - mongoc-read-concern.h - mongoc-read-prefs.h - mongoc-server-description.h - mongoc-client-session.h - mongoc-socket.h - mongoc-ssl.h - mongoc-stream-buffered.h - mongoc-stream-file.h - mongoc-stream-gridfs.h - mongoc-stream.h - mongoc-stream-socket.h - mongoc-stream-tls.h - mongoc-stream-tls-libressl.h - mongoc-stream-tls-openssl.h - mongoc-stream-tls-secure-channel.h - mongoc-stream-tls-secure-transport.h - mongoc-topology-description.h - mongoc-uri.h - mongoc-version-functions.h - mongoc-version.h.in - mongoc-write-concern.h - utlist.h - forwarding/mongoc.h -) -extra_dist_generated ( - mongoc-version.h -) - -set (src_libmongoc_src_mongoc_DIST_noinst_hs - mongoc-aggregate-private.h - mongoc-apm-private.h - mongoc-array-private.h - mongoc-async-cmd-private.h - mongoc-async-private.h - mongoc-buffer-private.h - mongoc-bulk-operation-private.h - mongoc-change-stream-private.h - mongoc-client-pool-private.h - mongoc-client-private.h - mongoc-client-side-encryption-private.h - mongoc-cluster-cyrus-private.h - mongoc-cluster-private.h - mongoc-cluster-sasl-private.h - mongoc-cluster-sspi-private.h - mongoc-cluster-sspi-private.h - mongoc-cmd-private.h - mongoc-collection-private.h - mongoc-compression-private.h - mongoc-config.h.in - mongoc-counters-private.h - mongoc-crypto-cng-private.h - mongoc-crypto-common-crypto-private.h - mongoc-crypto-openssl-private.h - mongoc-crypto-private.h - mongoc-cursor-private.h - mongoc-cyrus-private.h - mongoc-database-private.h - mongoc-errno-private.h - mongoc-error-private.h - mongoc-find-and-modify-private.h - mongoc-gridfs-bucket-file-private.h - mongoc-gridfs-bucket-private.h - mongoc-gridfs-file-list-private.h - mongoc-gridfs-file-page-private.h - mongoc-gridfs-file-private.h - mongoc-gridfs-private.h - mongoc-handshake-compiler-private.h - mongoc-handshake-os-private.h - mongoc-handshake-private.h - mongoc-host-list-private.h - mongoc-libressl-private.h - mongoc-linux-distro-scanner-private.h - mongoc-list-private.h - mongoc-log-private.h - mongoc-matcher-op-private.h - mongoc-matcher-private.h - mongoc-memcmp-private.h - mongoc-openssl-private.h - mongoc-opts-private.h - mongoc-opts-helpers-private.h - mongoc-queue-private.h - mongoc-rand-private.h - mongoc-read-concern-private.h - mongoc-read-prefs-private.h - mongoc-rpc-private.h - mongoc-sasl-private.h - mongoc-client-session-private.h - mongoc-sspi-private.h - mongoc-scram-private.h - mongoc-secure-channel-private.h - mongoc-secure-transport-private.h - mongoc-server-description-private.h - mongoc-server-stream-private.h - mongoc-set-private.h - mongoc-socket-private.h - mongoc-ssl-private.h - mongoc-sspi-private.h - mongoc-stream-private.h - mongoc-stream-tls-libressl-private.h - mongoc-stream-tls-openssl-bio-private.h - mongoc-stream-tls-openssl-private.h - mongoc-stream-tls-private.h - mongoc-stream-tls-secure-channel-private.h - mongoc-stream-tls-secure-transport-private.h - mongoc-stream-gridfs-download-private.h - mongoc-stream-gridfs-upload-private.h - mongoc-thread-private.h - mongoc-topology-description-apm-private.h - mongoc-topology-description-private.h - mongoc-topology-private.h - mongoc-topology-scanner-private.h - mongoc-trace-private.h - mongoc-uri-private.h - mongoc-util-private.h - mongoc-write-command-private.h - mongoc-write-command-legacy-private.h - mongoc-write-concern-private.h -) - -set (src_libmongoc_src_mongoc_DIST_cs - mongoc-aggregate.c - mongoc-apm.c - mongoc-array.c - mongoc-async.c - mongoc-async-cmd.c - mongoc-buffer.c - mongoc-bulk-operation.c - mongoc-change-stream.c - mongoc-client.c - mongoc-client-pool.c - mongoc-client-side-encryption.c - mongoc-cluster.c - mongoc-collection.c - mongoc-compression.c - mongoc-counters.c - mongoc-cursor.c - mongoc-cursor-legacy.c - mongoc-cursor-array.c - mongoc-cursor-find.c - mongoc-cursor-find-cmd.c - mongoc-cursor-find-opquery.c - mongoc-cursor-cmd.c - mongoc-cursor-change-stream.c - mongoc-cursor-cmd-deprecated.c - mongoc-database.c - mongoc-error.c - mongoc-find-and-modify.c - mongoc-host-list.c - mongoc-init.c - mongoc-gridfs.c - mongoc-gridfs-bucket.c - mongoc-gridfs-bucket-file.c - mongoc-gridfs-file.c - mongoc-gridfs-file-page.c - mongoc-gridfs-file-list.c - mongoc-handshake.c - mongoc-index.c - mongoc-linux-distro-scanner.c - mongoc-list.c - mongoc-log.c - mongoc-matcher-op.c - mongoc-matcher.c - mongoc-memcmp.c - mongoc-cmd.c - mongoc-opts.c - mongoc-opts-helpers.c - mongoc-queue.c - mongoc-read-concern.c - mongoc-read-prefs.c - mongoc-rpc.c - mongoc-server-description.c - mongoc-server-stream.c - mongoc-client-session.c - mongoc-set.c - mongoc-socket.c - mongoc-stream.c - mongoc-stream-buffered.c - mongoc-stream-file.c - mongoc-stream-gridfs.c - mongoc-stream-gridfs-download.c - mongoc-stream-gridfs-upload.c - mongoc-stream-socket.c - mongoc-topology.c - mongoc-topology-description.c - mongoc-topology-description-apm.c - mongoc-topology-scanner.c - mongoc-uri.c - mongoc-util.c - mongoc-version-functions.c - mongoc-write-command.c - mongoc-write-command-legacy.c - mongoc-write-concern.c - mongoc-crypto.c - mongoc-scram.c - mongoc-crypto-openssl.c - mongoc-rand-openssl.c - mongoc-crypto-common-crypto.c - mongoc-rand-common-crypto.c - mongoc-crypto-cng.c - mongoc-rand-cng.c - mongoc-stream-tls.c - mongoc-ssl.c - mongoc-libressl.c - mongoc-stream-tls-libressl.c - mongoc-openssl.c - mongoc-stream-tls-openssl.c - mongoc-stream-tls-openssl-bio.c - mongoc-secure-transport.c - mongoc-stream-tls-secure-transport.c - mongoc-secure-channel.c - mongoc-stream-tls-secure-channel.c - mongoc-cluster-sasl.c - mongoc-sasl.c - mongoc-cluster-cyrus.c - mongoc-cyrus.c - mongoc-cluster-sspi.c - mongoc-sspi.c -) - -set_dist_list (src_libmongoc_src_mongoc_DIST - CMakeLists.txt - modules/module.modulemap.in - ${src_libmongoc_src_mongoc_DIST_cs} - ${src_libmongoc_src_mongoc_DIST_hs} - ${src_libmongoc_src_mongoc_DIST_noinst_hs} - ${src_libmongoc_src_mongoc_DIST_defs} -) diff --git a/lib/mongoc/libmongoc/src/mongoc/forwarding/mongoc.h b/lib/mongoc/libmongoc/src/mongoc/forwarding/mongoc.h deleted file mode 100644 index 458369f130d4653c32e1a6f09a7d347aa23b1759..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/forwarding/mongoc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2018-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. - */ - -/* Including mongoc.h is superseded. Use mongoc/mongoc.h instead. */ -#include "mongoc/mongoc.h" \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-aggregate-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-aggregate-private.h deleted file mode 100644 index 41a1f02c9dc5d82d4728468fe272ab1ad8621e41..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-aggregate-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2019 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_AGGREGATE_PRIVATE_H -#define MONGOC_AGGREGATE_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-flags.h" -#include "mongoc/mongoc-read-concern.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-write-concern.h" - - -BSON_BEGIN_DECLS - - -mongoc_cursor_t * -_mongoc_aggregate (mongoc_client_t *client, - const char *ns, - mongoc_query_flags_t flags, - const bson_t *pipeline, - const bson_t *opts, - const mongoc_read_prefs_t *user_rp, - const mongoc_read_prefs_t *default_rp, - const mongoc_read_concern_t *default_rc, - const mongoc_write_concern_t *default_wc); - -bool -_has_write_key (bson_iter_t *iter); - -BSON_END_DECLS - - -#endif /* MONGOC_AGGREGATE_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-aggregate.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-aggregate.c deleted file mode 100644 index 8fd88ccf19e1c1e3d1c07751db2c1e6ca8001fcb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-aggregate.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2019 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 "mongoc/mongoc-aggregate-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-server-stream-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" - - -/*-------------------------------------------------------------------------- - * - * _has_write_key -- - * - * Returns true if the aggregation pipeline's last stage is "$out" - * or "$merge"; otherwise returns false. - * - * Side effects: - * Advances @iter to the last element. - * - *-------------------------------------------------------------------------- - */ - -bool -_has_write_key (bson_iter_t *iter) -{ - bson_iter_t stage; - bson_iter_t next; - - memcpy (&next, iter, sizeof (bson_iter_t)); - if (!bson_iter_next (&next)) { - /* default to false when iter is emtpy */ - return false; - } - - while (bson_iter_next (iter)) { - if (!bson_iter_next (&next) && BSON_ITER_HOLDS_DOCUMENT (iter)) { - bson_iter_recurse (iter, &stage); - if (bson_iter_find (&stage, "$out")) { - return true; - } - - bson_iter_recurse (iter, &stage); - if (bson_iter_find (&stage, "$merge")) { - return true; - } - } - } - - return false; -} - - -/*-------------------------------------------------------------------------- - * - * _make_agg_cmd -- - * - * Constructs an aggregate command. If @ns does not include a collection - * name, 1 will be used in its place for the value of "aggregate" in the - * command document. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @command is always initialized. - * @error is set if there is a failure. - * - *-------------------------------------------------------------------------- - */ - -static bool -_make_agg_cmd (const char *ns, - const bson_t *pipeline, - mongoc_aggregate_opts_t *opts, - bson_t *command, - bson_error_t *err) -{ - const char *dot; - bson_iter_t iter; - bson_t child; - bool has_write_key; - bson_iter_t has_write_key_iter; - - bson_init (command); - - dot = strstr (ns, "."); - - if (dot) { - /* Note: we're not validating that the collection name's length is one or - * more characters, as functions such as mongoc_client_get_collection also - * do not validate. */ - BSON_APPEND_UTF8 (command, "aggregate", dot + 1); - } else { - BSON_APPEND_INT32 (command, "aggregate", 1); - } - - /* - * The following will allow @pipeline to be either an array of - * items for the pipeline, or {"pipeline": [...]}. - */ - if (bson_iter_init_find (&iter, pipeline, "pipeline") && - BSON_ITER_HOLDS_ARRAY (&iter)) { - bson_iter_recurse (&iter, &has_write_key_iter); - if (!bson_append_iter (command, "pipeline", 8, &iter)) { - bson_set_error (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Failed to append \"pipeline\" to create command."); - return false; - } - } else { - BSON_APPEND_ARRAY (command, "pipeline", pipeline); - bson_iter_init (&has_write_key_iter, pipeline); - } - - has_write_key = _has_write_key (&has_write_key_iter); - bson_append_document_begin (command, "cursor", 6, &child); - /* Ignore batchSize=0 for aggregates with $out or $merge */ - if (opts->batchSize_is_set && !(has_write_key && opts->batchSize == 0)) { - BSON_APPEND_INT32 (&child, "batchSize", opts->batchSize); - } - - bson_append_document_end (command, &child); - return true; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_aggregate -- - * - * Constructs a mongoc_cursor_t for an "aggregate" command. - * - * This function will always return a new mongoc_cursor_t that should - * be freed with mongoc_cursor_destroy(). - * - * The cursor may fail once iterated upon, so check - * mongoc_cursor_error() if mongoc_cursor_next() returns false. - * - * See http://docs.mongodb.org/manual/aggregation/ for more - * information on how to build aggregation pipelines. - * - * Parameters: - * @ns: Namespace (or database name for database-level aggregation). - * @flags: Bitwise or of mongoc_query_flags_t or 0. - * @pipeline: A bson_t containing the pipeline request. @pipeline - * will be sent as an array type in the request. - * @opts: A bson_t containing aggregation options, such as - * bypassDocumentValidation (used with $out and $merge), maxTimeMS - * (declaring maximum server execution time) and explain (return - * information on the processing of the pipeline). - * @user_rp: Optional read preferences for the command. - * @default_rp: Default read preferences from the collection or database. - * @default_rc: Default read concern from the collection or database. - * @default_wc: Default write concern from the collection or database. - * - * Returns: - * A newly allocated mongoc_cursor_t that should be freed with - * mongoc_cursor_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_cursor_t * -_mongoc_aggregate (mongoc_client_t *client, - const char *ns, - mongoc_query_flags_t flags, - const bson_t *pipeline, - const bson_t *opts, - const mongoc_read_prefs_t *user_rp, - const mongoc_read_prefs_t *default_rp, - const mongoc_read_concern_t *default_rc, - const mongoc_write_concern_t *default_wc) - -{ - mongoc_server_stream_t *server_stream = NULL; - bool has_write_key; - bson_iter_t ar; - mongoc_cursor_t *cursor; - bson_iter_t iter; - bson_t command; - bson_t cursor_opts; - bool created_command; - bson_error_t create_cmd_err = {0}; - mongoc_aggregate_opts_t aggregate_opts; - bson_error_t opts_err = {0}; - bool parsed_opts; - - ENTRY; - - BSON_ASSERT (client); - BSON_ASSERT (ns); - BSON_ASSERT (pipeline); - - bson_init (&cursor_opts); - _mongoc_cursor_flags_to_opts (flags, &cursor_opts, NULL); - if (opts) { - bson_concat (&cursor_opts /* destination */, opts /* source */); - } - - parsed_opts = - _mongoc_aggregate_opts_parse (client, opts, &aggregate_opts, &opts_err); - - if (parsed_opts) { - created_command = _make_agg_cmd ( - ns, pipeline, &aggregate_opts, &command, &create_cmd_err); - } else { - created_command = false; - } - - cursor = _mongoc_cursor_cmd_new (client, - ns, - created_command ? &command : NULL, - &cursor_opts, - user_rp, - default_rp, - default_rc); - - if (created_command) { - bson_destroy (&command); - } - bson_destroy (&cursor_opts); - - if (!parsed_opts) { - memcpy (&cursor->error, &opts_err, sizeof (bson_error_t)); - GOTO (done); - } - - if (!created_command) { - /* copy error back to cursor. */ - memcpy (&cursor->error, &create_cmd_err, sizeof (bson_error_t)); - GOTO (done); - } - - if (mongoc_cursor_error (cursor, NULL)) { - GOTO (done); - } - - if (!_mongoc_read_prefs_validate (cursor->read_prefs, &cursor->error)) { - GOTO (done); - } - - /* pipeline could be like {pipeline: [{$out: 'test'}]} or [{$out: 'test'}] */ - if (bson_iter_init_find (&iter, pipeline, "pipeline") && - BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &ar)) { - has_write_key = _has_write_key (&ar); - } else { - if (!bson_iter_init (&iter, pipeline)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Pipeline is invalid BSON"); - GOTO (done); - } - has_write_key = _has_write_key (&iter); - } - - if (has_write_key && cursor->read_prefs->mode != MONGOC_READ_PRIMARY) { - mongoc_read_prefs_destroy (cursor->read_prefs); - cursor->read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - MONGOC_WARNING ("$out or $merge stage specified. Overriding read " - "preference to primary."); - } - - /* server id isn't enough. ensure we're connected & know wire version */ - server_stream = _mongoc_cursor_fetch_stream (cursor); - if (!server_stream) { - GOTO (done); - } - - if (aggregate_opts.write_concern_owned && has_write_key && - server_stream->sd->max_wire_version < WIRE_VERSION_CMD_WRITE_CONCERN) { - bson_set_error ( - &cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "\"aggregate\" with \"$out\" or \"$merge\" does not support " - "writeConcern with wire version %d, wire version %d is " - "required", - server_stream->sd->max_wire_version, - WIRE_VERSION_CMD_WRITE_CONCERN); - GOTO (done); - } - - /* Only inherit WriteConcern when aggregate has $out or $merge */ - if (!aggregate_opts.write_concern_owned && has_write_key) { - mongoc_write_concern_destroy (cursor->write_concern); - cursor->write_concern = mongoc_write_concern_copy (default_wc); - } - -done: - _mongoc_aggregate_opts_cleanup (&aggregate_opts); - mongoc_server_stream_cleanup (server_stream); /* null ok */ - - /* we always return the cursor, even if it fails; users can detect the - * failure on performing a cursor operation. see CDRIVER-880. */ - RETURN (cursor); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-apm-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-apm-private.h deleted file mode 100644 index 531bcac8209400f38b4fa3b0e8da97be5357e1b7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-apm-private.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_APM_PRIVATE_H -#define MONGOC_APM_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-apm.h" - -BSON_BEGIN_DECLS - -/* forward decl */ -struct _mongoc_cmd_t; - -struct _mongoc_apm_callbacks_t { - mongoc_apm_command_started_cb_t started; - mongoc_apm_command_succeeded_cb_t succeeded; - mongoc_apm_command_failed_cb_t failed; - mongoc_apm_server_changed_cb_t server_changed; - mongoc_apm_server_opening_cb_t server_opening; - mongoc_apm_server_closed_cb_t server_closed; - mongoc_apm_topology_changed_cb_t topology_changed; - mongoc_apm_topology_opening_cb_t topology_opening; - mongoc_apm_topology_closed_cb_t topology_closed; - mongoc_apm_server_heartbeat_started_cb_t server_heartbeat_started; - mongoc_apm_server_heartbeat_succeeded_cb_t server_heartbeat_succeeded; - mongoc_apm_server_heartbeat_failed_cb_t server_heartbeat_failed; -}; - -/* - * command monitoring events - */ - -struct _mongoc_apm_command_started_t { - bson_t *command; - bool command_owned; - const char *database_name; - const char *command_name; - int64_t request_id; - int64_t operation_id; - const mongoc_host_list_t *host; - uint32_t server_id; - void *context; -}; - -struct _mongoc_apm_command_succeeded_t { - int64_t duration; - const bson_t *reply; - const char *command_name; - int64_t request_id; - int64_t operation_id; - const mongoc_host_list_t *host; - uint32_t server_id; - void *context; -}; - -struct _mongoc_apm_command_failed_t { - int64_t duration; - const char *command_name; - const bson_error_t *error; - const bson_t *reply; - int64_t request_id; - int64_t operation_id; - const mongoc_host_list_t *host; - uint32_t server_id; - void *context; -}; - -/* - * SDAM monitoring events - */ - -struct _mongoc_apm_server_changed_t { - const mongoc_host_list_t *host; - bson_oid_t topology_id; - const mongoc_server_description_t *previous_description; - const mongoc_server_description_t *new_description; - void *context; -}; - -struct _mongoc_apm_server_opening_t { - const mongoc_host_list_t *host; - bson_oid_t topology_id; - void *context; -}; - -struct _mongoc_apm_server_closed_t { - const mongoc_host_list_t *host; - bson_oid_t topology_id; - void *context; -}; - -struct _mongoc_apm_topology_changed_t { - bson_oid_t topology_id; - const mongoc_topology_description_t *previous_description; - const mongoc_topology_description_t *new_description; - void *context; -}; - -struct _mongoc_apm_topology_opening_t { - bson_oid_t topology_id; - void *context; -}; - -struct _mongoc_apm_topology_closed_t { - bson_oid_t topology_id; - void *context; -}; - -struct _mongoc_apm_server_heartbeat_started_t { - const mongoc_host_list_t *host; - void *context; -}; - -struct _mongoc_apm_server_heartbeat_succeeded_t { - int64_t duration_usec; - const bson_t *reply; - const mongoc_host_list_t *host; - void *context; -}; - -struct _mongoc_apm_server_heartbeat_failed_t { - int64_t duration_usec; - const bson_error_t *error; - const mongoc_host_list_t *host; - void *context; -}; - -void -mongoc_apm_command_started_init (mongoc_apm_command_started_t *event, - const bson_t *command, - const char *database_name, - const char *command_name, - int64_t request_id, - int64_t operation_id, - const mongoc_host_list_t *host, - uint32_t server_id, - void *context); - -void -mongoc_apm_command_started_init_with_cmd (mongoc_apm_command_started_t *event, - struct _mongoc_cmd_t *cmd, - int64_t request_id, - void *context); - -void -mongoc_apm_command_started_cleanup (mongoc_apm_command_started_t *event); - -void -mongoc_apm_command_succeeded_init (mongoc_apm_command_succeeded_t *event, - int64_t duration, - const bson_t *reply, - const char *command_name, - int64_t request_id, - int64_t operation_id, - const mongoc_host_list_t *host, - uint32_t server_id, - void *context); - -void -mongoc_apm_command_succeeded_cleanup (mongoc_apm_command_succeeded_t *event); - -void -mongoc_apm_command_failed_init (mongoc_apm_command_failed_t *event, - int64_t duration, - const char *command_name, - const bson_error_t *error, - const bson_t *reply, - int64_t request_id, - int64_t operation_id, - const mongoc_host_list_t *host, - uint32_t server_id, - void *context); - -void -mongoc_apm_command_failed_cleanup (mongoc_apm_command_failed_t *event); - -BSON_END_DECLS - -#endif /* MONGOC_APM_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-apm.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-apm.c deleted file mode 100644 index 63641eb7318c4e832b942e3aaabf764c3b2d5aad..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-apm.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-apm-private.h" -#include "mongoc/mongoc-cmd-private.h" - -/* - * An Application Performance Management (APM) implementation, complying with - * MongoDB's Command Monitoring Spec: - * - * https://github.com/mongodb/specifications/tree/master/source/command-monitoring - */ - -static void -append_documents_from_cmd (const mongoc_cmd_t *cmd, - mongoc_apm_command_started_t *event) -{ - if (!cmd->payload || !cmd->payload_size) { - return; - } - - if (!event->command_owned) { - event->command = bson_copy (event->command); - event->command_owned = true; - } - - _mongoc_cmd_append_payload_as_array (cmd, event->command); -} - - -/* - * Private initializer / cleanup functions. - */ - -void -mongoc_apm_command_started_init (mongoc_apm_command_started_t *event, - const bson_t *command, - const char *database_name, - const char *command_name, - int64_t request_id, - int64_t operation_id, - const mongoc_host_list_t *host, - uint32_t server_id, - void *context) -{ - bson_iter_t iter; - uint32_t len; - const uint8_t *data; - - /* Command Monitoring Spec: - * - * In cases where queries or commands are embedded in a $query parameter - * when a read preference is provided, they MUST be unwrapped and the value - * of the $query attribute becomes the filter or the command in the started - * event. The read preference will subsequently be dropped as it is - * considered metadata and metadata is not currently provided in the command - * events. - */ - if (bson_has_field (command, "$readPreference")) { - if (bson_iter_init_find (&iter, command, "$query") && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - bson_iter_document (&iter, &len, &data); - event->command = bson_new_from_data (data, len); - event->command_owned = true; - } else { - /* Got $readPreference without $query, probably OP_MSG */ - event->command = (bson_t *) command; - event->command_owned = false; - } - } else { - /* discard "const", we promise not to modify "command" */ - event->command = (bson_t *) command; - event->command_owned = false; - } - - event->database_name = database_name; - event->command_name = command_name; - event->request_id = request_id; - event->operation_id = operation_id; - event->host = host; - event->server_id = server_id; - event->context = context; -} - - -void -mongoc_apm_command_started_init_with_cmd (mongoc_apm_command_started_t *event, - mongoc_cmd_t *cmd, - int64_t request_id, - void *context) -{ - mongoc_apm_command_started_init (event, - cmd->command, - cmd->db_name, - cmd->command_name, - request_id, - cmd->operation_id, - &cmd->server_stream->sd->host, - cmd->server_stream->sd->id, - context); - - /* OP_MSG document sequence for insert, update, or delete? */ - append_documents_from_cmd (cmd, event); -} - - -void -mongoc_apm_command_started_cleanup (mongoc_apm_command_started_t *event) -{ - if (event->command_owned) { - bson_destroy (event->command); - } -} - - -void -mongoc_apm_command_succeeded_init (mongoc_apm_command_succeeded_t *event, - int64_t duration, - const bson_t *reply, - const char *command_name, - int64_t request_id, - int64_t operation_id, - const mongoc_host_list_t *host, - uint32_t server_id, - void *context) -{ - BSON_ASSERT (reply); - - event->duration = duration; - event->reply = reply; - event->command_name = command_name; - event->request_id = request_id; - event->operation_id = operation_id; - event->host = host; - event->server_id = server_id; - event->context = context; -} - - -void -mongoc_apm_command_succeeded_cleanup (mongoc_apm_command_succeeded_t *event) -{ - /* no-op */ -} - - -void -mongoc_apm_command_failed_init (mongoc_apm_command_failed_t *event, - int64_t duration, - const char *command_name, - const bson_error_t *error, - const bson_t *reply, - int64_t request_id, - int64_t operation_id, - const mongoc_host_list_t *host, - uint32_t server_id, - void *context) -{ - BSON_ASSERT (reply); - - event->duration = duration; - event->command_name = command_name; - event->error = error; - event->reply = reply; - event->request_id = request_id; - event->operation_id = operation_id; - event->host = host; - event->server_id = server_id; - event->context = context; -} - - -void -mongoc_apm_command_failed_cleanup (mongoc_apm_command_failed_t *event) -{ - /* no-op */ -} - - -/* - * event field accessors - */ - -/* command-started event fields */ - -const bson_t * -mongoc_apm_command_started_get_command ( - const mongoc_apm_command_started_t *event) -{ - return event->command; -} - - -const char * -mongoc_apm_command_started_get_database_name ( - const mongoc_apm_command_started_t *event) -{ - return event->database_name; -} - - -const char * -mongoc_apm_command_started_get_command_name ( - const mongoc_apm_command_started_t *event) -{ - return event->command_name; -} - - -int64_t -mongoc_apm_command_started_get_request_id ( - const mongoc_apm_command_started_t *event) -{ - return event->request_id; -} - - -int64_t -mongoc_apm_command_started_get_operation_id ( - const mongoc_apm_command_started_t *event) -{ - return event->operation_id; -} - - -const mongoc_host_list_t * -mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event) -{ - return event->host; -} - - -uint32_t -mongoc_apm_command_started_get_server_id ( - const mongoc_apm_command_started_t *event) -{ - return event->server_id; -} - - -void * -mongoc_apm_command_started_get_context ( - const mongoc_apm_command_started_t *event) -{ - return event->context; -} - - -/* command-succeeded event fields */ - -int64_t -mongoc_apm_command_succeeded_get_duration ( - const mongoc_apm_command_succeeded_t *event) -{ - return event->duration; -} - - -const bson_t * -mongoc_apm_command_succeeded_get_reply ( - const mongoc_apm_command_succeeded_t *event) -{ - return event->reply; -} - - -const char * -mongoc_apm_command_succeeded_get_command_name ( - const mongoc_apm_command_succeeded_t *event) -{ - return event->command_name; -} - - -int64_t -mongoc_apm_command_succeeded_get_request_id ( - const mongoc_apm_command_succeeded_t *event) -{ - return event->request_id; -} - - -int64_t -mongoc_apm_command_succeeded_get_operation_id ( - const mongoc_apm_command_succeeded_t *event) -{ - return event->operation_id; -} - - -const mongoc_host_list_t * -mongoc_apm_command_succeeded_get_host ( - const mongoc_apm_command_succeeded_t *event) -{ - return event->host; -} - - -uint32_t -mongoc_apm_command_succeeded_get_server_id ( - const mongoc_apm_command_succeeded_t *event) -{ - return event->server_id; -} - - -void * -mongoc_apm_command_succeeded_get_context ( - const mongoc_apm_command_succeeded_t *event) -{ - return event->context; -} - - -/* command-failed event fields */ - -int64_t -mongoc_apm_command_failed_get_duration ( - const mongoc_apm_command_failed_t *event) -{ - return event->duration; -} - - -const char * -mongoc_apm_command_failed_get_command_name ( - const mongoc_apm_command_failed_t *event) -{ - return event->command_name; -} - - -void -mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event, - bson_error_t *error) -{ - memcpy (error, event->error, sizeof *event->error); -} - -const bson_t * -mongoc_apm_command_failed_get_reply (const mongoc_apm_command_failed_t *event) -{ - return event->reply; -} - -int64_t -mongoc_apm_command_failed_get_request_id ( - const mongoc_apm_command_failed_t *event) -{ - return event->request_id; -} - - -int64_t -mongoc_apm_command_failed_get_operation_id ( - const mongoc_apm_command_failed_t *event) -{ - return event->operation_id; -} - - -const mongoc_host_list_t * -mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event) -{ - return event->host; -} - - -uint32_t -mongoc_apm_command_failed_get_server_id ( - const mongoc_apm_command_failed_t *event) -{ - return event->server_id; -} - - -void * -mongoc_apm_command_failed_get_context (const mongoc_apm_command_failed_t *event) -{ - return event->context; -} - - -/* server-changed event fields */ - -const mongoc_host_list_t * -mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event) -{ - return event->host; -} - - -void -mongoc_apm_server_changed_get_topology_id ( - const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id) -{ - bson_oid_copy (&event->topology_id, topology_id); -} - - -const mongoc_server_description_t * -mongoc_apm_server_changed_get_previous_description ( - const mongoc_apm_server_changed_t *event) -{ - return event->previous_description; -} - - -const mongoc_server_description_t * -mongoc_apm_server_changed_get_new_description ( - const mongoc_apm_server_changed_t *event) -{ - return event->new_description; -} - - -void * -mongoc_apm_server_changed_get_context (const mongoc_apm_server_changed_t *event) -{ - return event->context; -} - - -/* server-opening event fields */ - -const mongoc_host_list_t * -mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event) -{ - return event->host; -} - - -void -mongoc_apm_server_opening_get_topology_id ( - const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id) -{ - bson_oid_copy (&event->topology_id, topology_id); -} - - -void * -mongoc_apm_server_opening_get_context (const mongoc_apm_server_opening_t *event) -{ - return event->context; -} - - -/* server-closed event fields */ - -const mongoc_host_list_t * -mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event) -{ - return event->host; -} - - -void -mongoc_apm_server_closed_get_topology_id ( - const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id) -{ - bson_oid_copy (&event->topology_id, topology_id); -} - - -void * -mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event) -{ - return event->context; -} - - -/* topology-changed event fields */ - -void -mongoc_apm_topology_changed_get_topology_id ( - const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id) -{ - bson_oid_copy (&event->topology_id, topology_id); -} - - -const mongoc_topology_description_t * -mongoc_apm_topology_changed_get_previous_description ( - const mongoc_apm_topology_changed_t *event) -{ - return event->previous_description; -} - - -const mongoc_topology_description_t * -mongoc_apm_topology_changed_get_new_description ( - const mongoc_apm_topology_changed_t *event) -{ - return event->new_description; -} - - -void * -mongoc_apm_topology_changed_get_context ( - const mongoc_apm_topology_changed_t *event) -{ - return event->context; -} - - -/* topology-opening event field */ - -void -mongoc_apm_topology_opening_get_topology_id ( - const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id) -{ - bson_oid_copy (&event->topology_id, topology_id); -} - - -void * -mongoc_apm_topology_opening_get_context ( - const mongoc_apm_topology_opening_t *event) -{ - return event->context; -} - - -/* topology-closed event field */ - -void -mongoc_apm_topology_closed_get_topology_id ( - const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id) -{ - bson_oid_copy (&event->topology_id, topology_id); -} - - -void * -mongoc_apm_topology_closed_get_context ( - const mongoc_apm_topology_closed_t *event) -{ - return event->context; -} - - -/* heartbeat-started event field */ - -const mongoc_host_list_t * -mongoc_apm_server_heartbeat_started_get_host ( - const mongoc_apm_server_heartbeat_started_t *event) -{ - return event->host; -} - - -void * -mongoc_apm_server_heartbeat_started_get_context ( - const mongoc_apm_server_heartbeat_started_t *event) -{ - return event->context; -} - - -/* heartbeat-succeeded event fields */ - -int64_t -mongoc_apm_server_heartbeat_succeeded_get_duration ( - const mongoc_apm_server_heartbeat_succeeded_t *event) -{ - return event->duration_usec; -} - - -const bson_t * -mongoc_apm_server_heartbeat_succeeded_get_reply ( - const mongoc_apm_server_heartbeat_succeeded_t *event) -{ - return event->reply; -} - - -const mongoc_host_list_t * -mongoc_apm_server_heartbeat_succeeded_get_host ( - const mongoc_apm_server_heartbeat_succeeded_t *event) -{ - return event->host; -} - - -void * -mongoc_apm_server_heartbeat_succeeded_get_context ( - const mongoc_apm_server_heartbeat_succeeded_t *event) -{ - return event->context; -} - - -/* heartbeat-failed event fields */ - -int64_t -mongoc_apm_server_heartbeat_failed_get_duration ( - const mongoc_apm_server_heartbeat_failed_t *event) -{ - return event->duration_usec; -} - - -void -mongoc_apm_server_heartbeat_failed_get_error ( - const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error) -{ - memcpy (error, event->error, sizeof *event->error); -} - - -const mongoc_host_list_t * -mongoc_apm_server_heartbeat_failed_get_host ( - const mongoc_apm_server_heartbeat_failed_t *event) -{ - return event->host; -} - - -void * -mongoc_apm_server_heartbeat_failed_get_context ( - const mongoc_apm_server_heartbeat_failed_t *event) -{ - return event->context; -} - - -/* - * registering callbacks - */ - -mongoc_apm_callbacks_t * -mongoc_apm_callbacks_new (void) -{ - size_t s = sizeof (mongoc_apm_callbacks_t); - - return (mongoc_apm_callbacks_t *) bson_malloc0 (s); -} - - -void -mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks) -{ - bson_free (callbacks); -} - - -void -mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_started_cb_t cb) -{ - callbacks->started = cb; -} - - -void -mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_succeeded_cb_t cb) -{ - callbacks->succeeded = cb; -} - - -void -mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_failed_cb_t cb) -{ - callbacks->failed = cb; -} - -void -mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_changed_cb_t cb) -{ - callbacks->server_changed = cb; -} - - -void -mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_opening_cb_t cb) -{ - callbacks->server_opening = cb; -} - - -void -mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_closed_cb_t cb) -{ - callbacks->server_closed = cb; -} - - -void -mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_changed_cb_t cb) -{ - callbacks->topology_changed = cb; -} - - -void -mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_opening_cb_t cb) -{ - callbacks->topology_opening = cb; -} - - -void -mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_closed_cb_t cb) -{ - callbacks->topology_closed = cb; -} - - -void -mongoc_apm_set_server_heartbeat_started_cb ( - mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_started_cb_t cb) -{ - callbacks->server_heartbeat_started = cb; -} - - -void -mongoc_apm_set_server_heartbeat_succeeded_cb ( - mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_succeeded_cb_t cb) -{ - callbacks->server_heartbeat_succeeded = cb; -} - - -void -mongoc_apm_set_server_heartbeat_failed_cb ( - mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_failed_cb_t cb) -{ - callbacks->server_heartbeat_failed = cb; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-apm.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-apm.h deleted file mode 100644 index c821dcd3f335f81a921dbe01e6bf1917c1263952..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-apm.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_APM_H -#define MONGOC_APM_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-host-list.h" -#include "mongoc/mongoc-server-description.h" -#include "mongoc/mongoc-topology-description.h" - -BSON_BEGIN_DECLS - -/* - * Application Performance Management (APM) interface, complies with two specs. - * MongoDB's Command Monitoring Spec: - * - * https://github.com/mongodb/specifications/tree/master/source/command-monitoring - * - * MongoDB's Spec for Monitoring Server Discovery and Monitoring (SDAM) events: - * - * https://github.com/mongodb/specifications/tree/master/source/server-discovery-and-monitoring - * - */ - -/* - * callbacks to receive APM events - */ - -typedef struct _mongoc_apm_callbacks_t mongoc_apm_callbacks_t; - - -/* - * command monitoring events - */ - -typedef struct _mongoc_apm_command_started_t mongoc_apm_command_started_t; -typedef struct _mongoc_apm_command_succeeded_t mongoc_apm_command_succeeded_t; -typedef struct _mongoc_apm_command_failed_t mongoc_apm_command_failed_t; - - -/* - * SDAM monitoring events - */ - -typedef struct _mongoc_apm_server_changed_t mongoc_apm_server_changed_t; -typedef struct _mongoc_apm_server_opening_t mongoc_apm_server_opening_t; -typedef struct _mongoc_apm_server_closed_t mongoc_apm_server_closed_t; -typedef struct _mongoc_apm_topology_changed_t mongoc_apm_topology_changed_t; -typedef struct _mongoc_apm_topology_opening_t mongoc_apm_topology_opening_t; -typedef struct _mongoc_apm_topology_closed_t mongoc_apm_topology_closed_t; -typedef struct _mongoc_apm_server_heartbeat_started_t - mongoc_apm_server_heartbeat_started_t; -typedef struct _mongoc_apm_server_heartbeat_succeeded_t - mongoc_apm_server_heartbeat_succeeded_t; -typedef struct _mongoc_apm_server_heartbeat_failed_t - mongoc_apm_server_heartbeat_failed_t; - -/* - * event field accessors - */ - -/* command-started event fields */ - -MONGOC_EXPORT (const bson_t *) -mongoc_apm_command_started_get_command ( - const mongoc_apm_command_started_t *event); -MONGOC_EXPORT (const char *) -mongoc_apm_command_started_get_database_name ( - const mongoc_apm_command_started_t *event); -MONGOC_EXPORT (const char *) -mongoc_apm_command_started_get_command_name ( - const mongoc_apm_command_started_t *event); -MONGOC_EXPORT (int64_t) -mongoc_apm_command_started_get_request_id ( - const mongoc_apm_command_started_t *event); -MONGOC_EXPORT (int64_t) -mongoc_apm_command_started_get_operation_id ( - const mongoc_apm_command_started_t *event); -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event); -MONGOC_EXPORT (uint32_t) -mongoc_apm_command_started_get_server_id ( - const mongoc_apm_command_started_t *event); -MONGOC_EXPORT (void *) -mongoc_apm_command_started_get_context ( - const mongoc_apm_command_started_t *event); - -/* command-succeeded event fields */ - -MONGOC_EXPORT (int64_t) -mongoc_apm_command_succeeded_get_duration ( - const mongoc_apm_command_succeeded_t *event); -MONGOC_EXPORT (const bson_t *) -mongoc_apm_command_succeeded_get_reply ( - const mongoc_apm_command_succeeded_t *event); -MONGOC_EXPORT (const char *) -mongoc_apm_command_succeeded_get_command_name ( - const mongoc_apm_command_succeeded_t *event); -MONGOC_EXPORT (int64_t) -mongoc_apm_command_succeeded_get_request_id ( - const mongoc_apm_command_succeeded_t *event); -MONGOC_EXPORT (int64_t) -mongoc_apm_command_succeeded_get_operation_id ( - const mongoc_apm_command_succeeded_t *event); -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_command_succeeded_get_host ( - const mongoc_apm_command_succeeded_t *event); -MONGOC_EXPORT (uint32_t) -mongoc_apm_command_succeeded_get_server_id ( - const mongoc_apm_command_succeeded_t *event); -MONGOC_EXPORT (void *) -mongoc_apm_command_succeeded_get_context ( - const mongoc_apm_command_succeeded_t *event); - -/* command-failed event fields */ - -MONGOC_EXPORT (int64_t) -mongoc_apm_command_failed_get_duration ( - const mongoc_apm_command_failed_t *event); -MONGOC_EXPORT (const char *) -mongoc_apm_command_failed_get_command_name ( - const mongoc_apm_command_failed_t *event); -/* retrieve the error by filling out the passed-in "error" struct */ -MONGOC_EXPORT (void) -mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event, - bson_error_t *error); -MONGOC_EXPORT (const bson_t *) -mongoc_apm_command_failed_get_reply (const mongoc_apm_command_failed_t *event); -MONGOC_EXPORT (int64_t) -mongoc_apm_command_failed_get_request_id ( - const mongoc_apm_command_failed_t *event); -MONGOC_EXPORT (int64_t) -mongoc_apm_command_failed_get_operation_id ( - const mongoc_apm_command_failed_t *event); -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event); -MONGOC_EXPORT (uint32_t) -mongoc_apm_command_failed_get_server_id ( - const mongoc_apm_command_failed_t *event); -MONGOC_EXPORT (void *) -mongoc_apm_command_failed_get_context ( - const mongoc_apm_command_failed_t *event); - -/* server-changed event fields */ - -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event); -MONGOC_EXPORT (void) -mongoc_apm_server_changed_get_topology_id ( - const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id); -MONGOC_EXPORT (const mongoc_server_description_t *) -mongoc_apm_server_changed_get_previous_description ( - const mongoc_apm_server_changed_t *event); -MONGOC_EXPORT (const mongoc_server_description_t *) -mongoc_apm_server_changed_get_new_description ( - const mongoc_apm_server_changed_t *event); -MONGOC_EXPORT (void *) -mongoc_apm_server_changed_get_context ( - const mongoc_apm_server_changed_t *event); - -/* server-opening event fields */ - -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event); -MONGOC_EXPORT (void) -mongoc_apm_server_opening_get_topology_id ( - const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id); -MONGOC_EXPORT (void *) -mongoc_apm_server_opening_get_context ( - const mongoc_apm_server_opening_t *event); - -/* server-closed event fields */ - -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event); -MONGOC_EXPORT (void) -mongoc_apm_server_closed_get_topology_id ( - const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id); -MONGOC_EXPORT (void *) -mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event); - -/* topology-changed event fields */ - -MONGOC_EXPORT (void) -mongoc_apm_topology_changed_get_topology_id ( - const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id); -MONGOC_EXPORT (const mongoc_topology_description_t *) -mongoc_apm_topology_changed_get_previous_description ( - const mongoc_apm_topology_changed_t *event); -MONGOC_EXPORT (const mongoc_topology_description_t *) -mongoc_apm_topology_changed_get_new_description ( - const mongoc_apm_topology_changed_t *event); -MONGOC_EXPORT (void *) -mongoc_apm_topology_changed_get_context ( - const mongoc_apm_topology_changed_t *event); - -/* topology-opening event field */ - -MONGOC_EXPORT (void) -mongoc_apm_topology_opening_get_topology_id ( - const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id); -MONGOC_EXPORT (void *) -mongoc_apm_topology_opening_get_context ( - const mongoc_apm_topology_opening_t *event); - -/* topology-closed event field */ - -MONGOC_EXPORT (void) -mongoc_apm_topology_closed_get_topology_id ( - const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id); -MONGOC_EXPORT (void *) -mongoc_apm_topology_closed_get_context ( - const mongoc_apm_topology_closed_t *event); - -/* heartbeat-started event field */ - -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_server_heartbeat_started_get_host ( - const mongoc_apm_server_heartbeat_started_t *event); -MONGOC_EXPORT (void *) -mongoc_apm_server_heartbeat_started_get_context ( - const mongoc_apm_server_heartbeat_started_t *event); - -/* heartbeat-succeeded event fields */ - -MONGOC_EXPORT (int64_t) -mongoc_apm_server_heartbeat_succeeded_get_duration ( - const mongoc_apm_server_heartbeat_succeeded_t *event); -MONGOC_EXPORT (const bson_t *) -mongoc_apm_server_heartbeat_succeeded_get_reply ( - const mongoc_apm_server_heartbeat_succeeded_t *event); -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_server_heartbeat_succeeded_get_host ( - const mongoc_apm_server_heartbeat_succeeded_t *event); -MONGOC_EXPORT (void *) -mongoc_apm_server_heartbeat_succeeded_get_context ( - const mongoc_apm_server_heartbeat_succeeded_t *event); - -/* heartbeat-failed event fields */ - -MONGOC_EXPORT (int64_t) -mongoc_apm_server_heartbeat_failed_get_duration ( - const mongoc_apm_server_heartbeat_failed_t *event); -MONGOC_EXPORT (void) -mongoc_apm_server_heartbeat_failed_get_error ( - const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error); -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_apm_server_heartbeat_failed_get_host ( - const mongoc_apm_server_heartbeat_failed_t *event); -MONGOC_EXPORT (void *) -mongoc_apm_server_heartbeat_failed_get_context ( - const mongoc_apm_server_heartbeat_failed_t *event); - - -/* - * callbacks - */ - -typedef void (*mongoc_apm_command_started_cb_t) ( - const mongoc_apm_command_started_t *event); -typedef void (*mongoc_apm_command_succeeded_cb_t) ( - const mongoc_apm_command_succeeded_t *event); -typedef void (*mongoc_apm_command_failed_cb_t) ( - const mongoc_apm_command_failed_t *event); -typedef void (*mongoc_apm_server_changed_cb_t) ( - const mongoc_apm_server_changed_t *event); -typedef void (*mongoc_apm_server_opening_cb_t) ( - const mongoc_apm_server_opening_t *event); -typedef void (*mongoc_apm_server_closed_cb_t) ( - const mongoc_apm_server_closed_t *event); -typedef void (*mongoc_apm_topology_changed_cb_t) ( - const mongoc_apm_topology_changed_t *event); -typedef void (*mongoc_apm_topology_opening_cb_t) ( - const mongoc_apm_topology_opening_t *event); -typedef void (*mongoc_apm_topology_closed_cb_t) ( - const mongoc_apm_topology_closed_t *event); -typedef void (*mongoc_apm_server_heartbeat_started_cb_t) ( - const mongoc_apm_server_heartbeat_started_t *event); -typedef void (*mongoc_apm_server_heartbeat_succeeded_cb_t) ( - const mongoc_apm_server_heartbeat_succeeded_t *event); -typedef void (*mongoc_apm_server_heartbeat_failed_cb_t) ( - const mongoc_apm_server_heartbeat_failed_t *event); - -/* - * registering callbacks - */ - -MONGOC_EXPORT (mongoc_apm_callbacks_t *) -mongoc_apm_callbacks_new (void); -MONGOC_EXPORT (void) -mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks); -MONGOC_EXPORT (void) -mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_started_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_succeeded_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_command_failed_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_changed_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_opening_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_closed_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_changed_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_opening_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks, - mongoc_apm_topology_closed_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_server_heartbeat_started_cb ( - mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_started_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_server_heartbeat_succeeded_cb ( - mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_succeeded_cb_t cb); -MONGOC_EXPORT (void) -mongoc_apm_set_server_heartbeat_failed_cb ( - mongoc_apm_callbacks_t *callbacks, - mongoc_apm_server_heartbeat_failed_cb_t cb); -BSON_END_DECLS - -#endif /* MONGOC_APM_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-array-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-array-private.h deleted file mode 100644 index c70662b674d80df27edf9d704253bd7800daf32e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-array-private.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_ARRAY_PRIVATE_H -#define MONGOC_ARRAY_PRIVATE_H - -#include <bson/bson.h> - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_array_t mongoc_array_t; - - -struct _mongoc_array_t { - size_t len; - size_t element_size; - size_t allocated; - void *data; -}; - - -#define _mongoc_array_append_val(a, v) _mongoc_array_append_vals (a, &v, 1) -#define _mongoc_array_index(a, t, i) (((t *) (a)->data)[i]) -#define _mongoc_array_clear(a) (a)->len = 0 - - -void -_mongoc_array_init (mongoc_array_t *array, size_t element_size); -void -_mongoc_array_copy (mongoc_array_t *dst, const mongoc_array_t *src); -void -_mongoc_array_append_vals (mongoc_array_t *array, - const void *data, - uint32_t n_elements); -void -_mongoc_array_destroy (mongoc_array_t *array); - - -BSON_END_DECLS - - -#endif /* MONGOC_ARRAY_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-array.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-array.c deleted file mode 100644 index ecef67d3d19938ee13d53e1922cce6364c53e8ca..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-array.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-array-private.h" - - -void -_mongoc_array_init (mongoc_array_t *array, size_t element_size) -{ - BSON_ASSERT (array); - BSON_ASSERT (element_size); - - array->len = 0; - array->element_size = element_size; - array->allocated = 128; - array->data = (void *) bson_malloc0 (array->allocated); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_array_copy -- - * - * Destroy dst and copy src into it. Both arrays must be initialized. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_array_copy (mongoc_array_t *dst, const mongoc_array_t *src) -{ - _mongoc_array_destroy (dst); - - dst->len = src->len; - dst->element_size = src->element_size; - dst->allocated = src->allocated; - dst->data = (void *) bson_malloc (dst->allocated); - memcpy (dst->data, src->data, dst->allocated); -} - - -void -_mongoc_array_destroy (mongoc_array_t *array) -{ - if (array && array->data) { - bson_free (array->data); - } -} - - -void -_mongoc_array_append_vals (mongoc_array_t *array, - const void *data, - uint32_t n_elements) -{ - size_t len; - size_t off; - size_t next_size; - - BSON_ASSERT (array); - BSON_ASSERT (data); - - off = array->element_size * array->len; - len = (size_t) n_elements * array->element_size; - if ((off + len) > array->allocated) { - next_size = bson_next_power_of_two (off + len); - array->data = (void *) bson_realloc (array->data, next_size); - array->allocated = next_size; - } - - memcpy ((uint8_t *) array->data + off, data, len); - - array->len += n_elements; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-async-cmd-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-async-cmd-private.h deleted file mode 100644 index 7f2f36e29e5a71c4bf360d6ac160c5795bb7a95f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-async-cmd-private.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_ASYNC_CMD_PRIVATE_H -#define MONGOC_ASYNC_CMD_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-async-private.h" -#include "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-buffer-private.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-stream.h" - -BSON_BEGIN_DECLS - -typedef enum { - MONGOC_ASYNC_CMD_INITIATE, - MONGOC_ASYNC_CMD_SETUP, - MONGOC_ASYNC_CMD_SEND, - MONGOC_ASYNC_CMD_RECV_LEN, - MONGOC_ASYNC_CMD_RECV_RPC, - MONGOC_ASYNC_CMD_ERROR_STATE, - MONGOC_ASYNC_CMD_CANCELED_STATE, -} mongoc_async_cmd_state_t; - -typedef struct _mongoc_async_cmd { - mongoc_stream_t *stream; - - mongoc_async_t *async; - mongoc_async_cmd_state_t state; - int events; - mongoc_async_cmd_initiate_t initiator; - mongoc_async_cmd_setup_t setup; - void *setup_ctx; - mongoc_async_cmd_cb_t cb; - void *data; - bson_error_t error; - int64_t initiate_delay_ms; - int64_t connect_started; - int64_t cmd_started; - int64_t timeout_msec; - bson_t cmd; - mongoc_buffer_t buffer; - mongoc_array_t array; - mongoc_iovec_t *iovec; - size_t niovec; - size_t bytes_written; - size_t bytes_to_read; - mongoc_rpc_t rpc; - bson_t reply; - bool reply_needs_cleanup; - char ns[MONGOC_NAMESPACE_MAX]; - struct addrinfo *dns_result; - - struct _mongoc_async_cmd *next; - struct _mongoc_async_cmd *prev; -} mongoc_async_cmd_t; - -mongoc_async_cmd_t * -mongoc_async_cmd_new (mongoc_async_t *async, - mongoc_stream_t *stream, - bool is_setup_done, - struct addrinfo *dns_result, - mongoc_async_cmd_initiate_t initiator, - int64_t initiate_delay_ms, - mongoc_async_cmd_setup_t setup, - void *setup_ctx, - const char *dbname, - const bson_t *cmd, - mongoc_async_cmd_cb_t cb, - void *cb_data, - int64_t timeout_msec); - -void -mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd); - -bool -mongoc_async_cmd_run (mongoc_async_cmd_t *acmd); - -#ifdef MONGOC_ENABLE_SSL -int -mongoc_async_cmd_tls_setup (mongoc_stream_t *stream, - int *events, - void *ctx, - int32_t timeout_msec, - bson_error_t *error); -#endif - -BSON_END_DECLS - - -#endif /* MONGOC_ASYNC_CMD_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-async-cmd.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-async-cmd.c deleted file mode 100644 index cfbe38aa72d272ec861386fe1adb36e9dae748a4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-async-cmd.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright 2014 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 <bson/bson.h> - -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-async-cmd-private.h" -#include "mongoc/mongoc-async-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-opcode.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-server-description-private.h" -#include "mongoc/mongoc-topology-scanner-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/utlist.h" - -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-stream-tls.h" -#endif - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "async" - -typedef mongoc_async_cmd_result_t (*_mongoc_async_cmd_phase_t) ( - mongoc_async_cmd_t *cmd); - -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_initiate (mongoc_async_cmd_t *cmd); -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_setup (mongoc_async_cmd_t *cmd); -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_send (mongoc_async_cmd_t *cmd); -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_recv_len (mongoc_async_cmd_t *cmd); -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *cmd); - -static const _mongoc_async_cmd_phase_t gMongocCMDPhases[] = { - _mongoc_async_cmd_phase_initiate, - _mongoc_async_cmd_phase_setup, - _mongoc_async_cmd_phase_send, - _mongoc_async_cmd_phase_recv_len, - _mongoc_async_cmd_phase_recv_rpc, - NULL, /* no callback for MONGOC_ASYNC_CMD_ERROR_STATE */ - NULL, /* no callback for MONGOC_ASYNC_CMD_CANCELED_STATE */ -}; - -#ifdef MONGOC_ENABLE_SSL -int -mongoc_async_cmd_tls_setup (mongoc_stream_t *stream, - int *events, - void *ctx, - int32_t timeout_msec, - bson_error_t *error) -{ - mongoc_stream_t *tls_stream; - const char *host = (const char *) ctx; - int retry_events = 0; - - - for (tls_stream = stream; tls_stream->type != MONGOC_STREAM_TLS; - tls_stream = mongoc_stream_get_base_stream (tls_stream)) { - } - -#if defined(MONGOC_ENABLE_SSL_OPENSSL) || \ - defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) - /* pass 0 for the timeout to begin / continue non-blocking handshake */ - timeout_msec = 0; -#endif - if (mongoc_stream_tls_handshake ( - tls_stream, host, timeout_msec, &retry_events, error)) { - return 1; - } - - if (retry_events) { - *events = retry_events; - return 0; - } - return -1; -} -#endif - -bool -mongoc_async_cmd_run (mongoc_async_cmd_t *acmd) -{ - mongoc_async_cmd_result_t result; - int64_t duration_usec; - _mongoc_async_cmd_phase_t phase_callback; - - BSON_ASSERT (acmd); - - /* if we have successfully connected to the node, call the callback. */ - if (acmd->state == MONGOC_ASYNC_CMD_SEND) { - acmd->cb (acmd, MONGOC_ASYNC_CMD_CONNECTED, NULL, 0); - } - - phase_callback = gMongocCMDPhases[acmd->state]; - if (phase_callback) { - result = phase_callback (acmd); - } else { - result = MONGOC_ASYNC_CMD_ERROR; - } - - if (result == MONGOC_ASYNC_CMD_IN_PROGRESS) { - return true; - } - - duration_usec = bson_get_monotonic_time () - acmd->cmd_started; - - if (result == MONGOC_ASYNC_CMD_SUCCESS) { - acmd->cb (acmd, result, &acmd->reply, duration_usec); - } else { - /* we're in ERROR, TIMEOUT, or CANCELED */ - acmd->cb (acmd, result, NULL, duration_usec); - } - - mongoc_async_cmd_destroy (acmd); - return false; -} - -void -_mongoc_async_cmd_init_send (mongoc_async_cmd_t *acmd, const char *dbname) -{ - bson_snprintf (acmd->ns, sizeof acmd->ns, "%s.$cmd", dbname); - - acmd->rpc.header.msg_len = 0; - acmd->rpc.header.request_id = ++acmd->async->request_id; - acmd->rpc.header.response_to = 0; - acmd->rpc.header.opcode = MONGOC_OPCODE_QUERY; - acmd->rpc.query.flags = MONGOC_QUERY_SLAVE_OK; - acmd->rpc.query.collection = acmd->ns; - acmd->rpc.query.skip = 0; - acmd->rpc.query.n_return = -1; - acmd->rpc.query.query = bson_get_data (&acmd->cmd); - acmd->rpc.query.fields = NULL; - - /* This will always be isMaster, which are not allowed to be compressed */ - _mongoc_rpc_gather (&acmd->rpc, &acmd->array); - acmd->iovec = (mongoc_iovec_t *) acmd->array.data; - acmd->niovec = acmd->array.len; - _mongoc_rpc_swab_to_le (&acmd->rpc); - acmd->bytes_written = 0; -} - -void -_mongoc_async_cmd_state_start (mongoc_async_cmd_t *acmd, bool is_setup_done) -{ - if (!acmd->stream) { - acmd->state = MONGOC_ASYNC_CMD_INITIATE; - } else if (acmd->setup && !is_setup_done) { - acmd->state = MONGOC_ASYNC_CMD_SETUP; - } else { - acmd->state = MONGOC_ASYNC_CMD_SEND; - } - - acmd->events = POLLOUT; -} - -mongoc_async_cmd_t * -mongoc_async_cmd_new (mongoc_async_t *async, - mongoc_stream_t *stream, - bool is_setup_done, - struct addrinfo *dns_result, - mongoc_async_cmd_initiate_t initiator, - int64_t initiate_delay_ms, - mongoc_async_cmd_setup_t setup, - void *setup_ctx, - const char *dbname, - const bson_t *cmd, - mongoc_async_cmd_cb_t cb, - void *cb_data, - int64_t timeout_msec) -{ - mongoc_async_cmd_t *acmd; - - BSON_ASSERT (cmd); - BSON_ASSERT (dbname); - - acmd = (mongoc_async_cmd_t *) bson_malloc0 (sizeof (*acmd)); - acmd->async = async; - acmd->dns_result = dns_result; - acmd->timeout_msec = timeout_msec; - acmd->stream = stream; - acmd->initiator = initiator; - acmd->initiate_delay_ms = initiate_delay_ms; - acmd->setup = setup; - acmd->setup_ctx = setup_ctx; - acmd->cb = cb; - acmd->data = cb_data; - acmd->connect_started = bson_get_monotonic_time (); - bson_copy_to (cmd, &acmd->cmd); - - _mongoc_array_init (&acmd->array, sizeof (mongoc_iovec_t)); - _mongoc_buffer_init (&acmd->buffer, NULL, 0, NULL, NULL); - - _mongoc_async_cmd_init_send (acmd, dbname); - - _mongoc_async_cmd_state_start (acmd, is_setup_done); - - async->ncmds++; - DL_APPEND (async->cmds, acmd); - - return acmd; -} - - -void -mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd) -{ - BSON_ASSERT (acmd); - - DL_DELETE (acmd->async->cmds, acmd); - acmd->async->ncmds--; - - bson_destroy (&acmd->cmd); - - if (acmd->reply_needs_cleanup) { - bson_destroy (&acmd->reply); - } - - _mongoc_array_destroy (&acmd->array); - _mongoc_buffer_destroy (&acmd->buffer); - - bson_free (acmd); -} - -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_initiate (mongoc_async_cmd_t *acmd) -{ - acmd->stream = acmd->initiator (acmd); - if (!acmd->stream) { - return MONGOC_ASYNC_CMD_ERROR; - } - /* reset the connect started time after connection starts. */ - acmd->connect_started = bson_get_monotonic_time (); - if (acmd->setup) { - acmd->state = MONGOC_ASYNC_CMD_SETUP; - } else { - acmd->state = MONGOC_ASYNC_CMD_SEND; - } - return MONGOC_ASYNC_CMD_IN_PROGRESS; -} - -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_setup (mongoc_async_cmd_t *acmd) -{ - int retval; - - BSON_ASSERT (acmd->timeout_msec < INT32_MAX); - retval = acmd->setup (acmd->stream, - &acmd->events, - acmd->setup_ctx, - (int32_t) acmd->timeout_msec, - &acmd->error); - switch (retval) { - case -1: - return MONGOC_ASYNC_CMD_ERROR; - case 0: - break; - case 1: - acmd->state = MONGOC_ASYNC_CMD_SEND; - acmd->events = POLLOUT; - break; - default: - abort (); - } - - return MONGOC_ASYNC_CMD_IN_PROGRESS; -} - -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_send (mongoc_async_cmd_t *acmd) -{ - size_t total_bytes = 0; - size_t offset; - ssize_t bytes; - int i; - /* if a continued write, then iovec will be set to a temporary copy */ - bool used_temp_iovec = false; - mongoc_iovec_t *iovec = acmd->iovec; - size_t niovec = acmd->niovec; - - for (i = 0; i < acmd->niovec; i++) { - total_bytes += acmd->iovec[i].iov_len; - } - - if (acmd->bytes_written > 0) { - BSON_ASSERT (acmd->bytes_written < total_bytes); - /* if bytes have been written before, compute the offset in the next - * iovec entry to be written. */ - offset = acmd->bytes_written; - - /* subtract the lengths of all iovec entries written so far. */ - for (i = 0; i < acmd->niovec; i++) { - if (offset < acmd->iovec[i].iov_len) { - break; - } - offset -= acmd->iovec[i].iov_len; - } - - BSON_ASSERT (i < acmd->niovec); - - /* create a new iovec with the remaining data to be written. */ - niovec = acmd->niovec - i; - iovec = bson_malloc (niovec * sizeof (mongoc_iovec_t)); - memcpy (iovec, acmd->iovec + i, niovec * sizeof (mongoc_iovec_t)); - iovec[0].iov_base = (char *) iovec[0].iov_base + offset; - iovec[0].iov_len -= offset; - used_temp_iovec = true; - } - - bytes = mongoc_stream_writev (acmd->stream, iovec, niovec, 0); - - if (used_temp_iovec) { - bson_free (iovec); - } - - if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) { - return MONGOC_ASYNC_CMD_IN_PROGRESS; - } - - if (bytes < 0) { - bson_set_error (&acmd->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to write rpc bytes."); - return MONGOC_ASYNC_CMD_ERROR; - } - - acmd->bytes_written += bytes; - - if (acmd->bytes_written < total_bytes) { - return MONGOC_ASYNC_CMD_IN_PROGRESS; - } - - acmd->state = MONGOC_ASYNC_CMD_RECV_LEN; - acmd->bytes_to_read = 4; - acmd->events = POLLIN; - - acmd->cmd_started = bson_get_monotonic_time (); - - return MONGOC_ASYNC_CMD_IN_PROGRESS; -} - -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_recv_len (mongoc_async_cmd_t *acmd) -{ - ssize_t bytes = _mongoc_buffer_try_append_from_stream ( - &acmd->buffer, acmd->stream, acmd->bytes_to_read, 0); - uint32_t msg_len; - - if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) { - return MONGOC_ASYNC_CMD_IN_PROGRESS; - } - - if (bytes < 0) { - bson_set_error (&acmd->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to receive length header from server."); - return MONGOC_ASYNC_CMD_ERROR; - } - - if (bytes == 0) { - bson_set_error (&acmd->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Server closed connection."); - return MONGOC_ASYNC_CMD_ERROR; - } - - acmd->bytes_to_read = (size_t) (acmd->bytes_to_read - bytes); - - if (!acmd->bytes_to_read) { - memcpy (&msg_len, acmd->buffer.data, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - - if (msg_len < 16 || msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE || - msg_len < acmd->buffer.len) { - bson_set_error (&acmd->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server."); - return MONGOC_ASYNC_CMD_ERROR; - } - - acmd->bytes_to_read = msg_len - acmd->buffer.len; - acmd->state = MONGOC_ASYNC_CMD_RECV_RPC; - - return _mongoc_async_cmd_phase_recv_rpc (acmd); - } - - return MONGOC_ASYNC_CMD_IN_PROGRESS; -} - -mongoc_async_cmd_result_t -_mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *acmd) -{ - ssize_t bytes = _mongoc_buffer_try_append_from_stream ( - &acmd->buffer, acmd->stream, acmd->bytes_to_read, 0); - - if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) { - return MONGOC_ASYNC_CMD_IN_PROGRESS; - } - - if (bytes < 0) { - bson_set_error (&acmd->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to receive rpc bytes from server."); - return MONGOC_ASYNC_CMD_ERROR; - } - - if (bytes == 0) { - bson_set_error (&acmd->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Server closed connection."); - return MONGOC_ASYNC_CMD_ERROR; - } - - acmd->bytes_to_read = (size_t) (acmd->bytes_to_read - bytes); - - if (!acmd->bytes_to_read) { - if (!_mongoc_rpc_scatter ( - &acmd->rpc, acmd->buffer.data, acmd->buffer.len)) { - bson_set_error (&acmd->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server."); - return MONGOC_ASYNC_CMD_ERROR; - } - if (BSON_UINT32_FROM_LE (acmd->rpc.header.opcode) == - MONGOC_OPCODE_COMPRESSED) { - uint8_t *buf = NULL; - size_t len = - BSON_UINT32_FROM_LE (acmd->rpc.compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); - - buf = bson_malloc0 (len); - if (!_mongoc_rpc_decompress (&acmd->rpc, buf, len)) { - bson_free (buf); - bson_set_error (&acmd->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress server reply"); - return MONGOC_ASYNC_CMD_ERROR; - } - - _mongoc_buffer_destroy (&acmd->buffer); - _mongoc_buffer_init (&acmd->buffer, buf, len, NULL, NULL); - } - - _mongoc_rpc_swab_from_le (&acmd->rpc); - - if (!_mongoc_rpc_get_first_document (&acmd->rpc, &acmd->reply)) { - bson_set_error (&acmd->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server"); - return MONGOC_ASYNC_CMD_ERROR; - } - - acmd->reply_needs_cleanup = true; - - return MONGOC_ASYNC_CMD_SUCCESS; - } - - return MONGOC_ASYNC_CMD_IN_PROGRESS; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-async-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-async-private.h deleted file mode 100644 index 0d53fd100fbd057cee22859df13f75dfb9173f9f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-async-private.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_ASYNC_PRIVATE_H -#define MONGOC_ASYNC_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-stream.h" - -BSON_BEGIN_DECLS - -struct _mongoc_async_cmd; - -typedef struct _mongoc_async { - struct _mongoc_async_cmd *cmds; - size_t ncmds; - uint32_t request_id; -} mongoc_async_t; - -typedef enum { - MONGOC_ASYNC_CMD_CONNECTED, - MONGOC_ASYNC_CMD_IN_PROGRESS, - MONGOC_ASYNC_CMD_SUCCESS, - MONGOC_ASYNC_CMD_ERROR, - MONGOC_ASYNC_CMD_TIMEOUT, -} mongoc_async_cmd_result_t; - -typedef void (*mongoc_async_cmd_cb_t) (struct _mongoc_async_cmd *acmd, - mongoc_async_cmd_result_t result, - const bson_t *bson, - int64_t duration_usec); - -typedef mongoc_stream_t *(*mongoc_async_cmd_initiate_t) ( - struct _mongoc_async_cmd *); - -typedef int (*mongoc_async_cmd_setup_t) (mongoc_stream_t *stream, - int *events, - void *ctx, - int32_t timeout_msec, - bson_error_t *error); - - -mongoc_async_t * -mongoc_async_new (); - -void -mongoc_async_destroy (mongoc_async_t *async); - -void -mongoc_async_run (mongoc_async_t *async); - -BSON_END_DECLS - -#endif /* MONGOC_ASYNC_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-async.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-async.c deleted file mode 100644 index d94564d058e880991015cd3c73de9f4b424db080..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-async.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2014 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 <bson/bson.h> - -#include "mongoc/mongoc-async-private.h" -#include "mongoc/mongoc-async-cmd-private.h" -#include "mongoc/utlist.h" -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-socket-private.h" -#include "mongoc/mongoc-util-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "async" - - -mongoc_async_t * -mongoc_async_new () -{ - mongoc_async_t *async = (mongoc_async_t *) bson_malloc0 (sizeof (*async)); - - return async; -} - -void -mongoc_async_destroy (mongoc_async_t *async) -{ - mongoc_async_cmd_t *acmd, *tmp; - - DL_FOREACH_SAFE (async->cmds, acmd, tmp) - { - mongoc_async_cmd_destroy (acmd); - } - - bson_free (async); -} - -void -mongoc_async_run (mongoc_async_t *async) -{ - mongoc_async_cmd_t *acmd, *tmp; - mongoc_async_cmd_t **acmds_polled = NULL; - mongoc_stream_poll_t *poller = NULL; - int nstreams, i; - ssize_t nactive = 0; - int64_t now; - int64_t expire_at; - int64_t poll_timeout_msec; - size_t poll_size; - - now = bson_get_monotonic_time (); - poll_size = 0; - - /* CDRIVER-1571 reset start times in case a stream initiator was slow */ - DL_FOREACH (async->cmds, acmd) - { - acmd->connect_started = now; - } - - while (async->ncmds) { - /* ncmds grows if we discover a replica & start calling ismaster on it */ - if (poll_size < async->ncmds) { - poller = (mongoc_stream_poll_t *) bson_realloc ( - poller, sizeof (*poller) * async->ncmds); - acmds_polled = (mongoc_async_cmd_t **) bson_realloc ( - acmds_polled, sizeof (*acmds_polled) * async->ncmds); - poll_size = async->ncmds; - } - - expire_at = INT64_MAX; - nstreams = 0; - - /* check if any cmds are ready to be initiated. */ - DL_FOREACH_SAFE (async->cmds, acmd, tmp) - { - if (acmd->state == MONGOC_ASYNC_CMD_INITIATE) { - BSON_ASSERT (!acmd->stream); - if (now >= acmd->initiate_delay_ms * 1000 + acmd->connect_started) { - /* time to initiate. */ - if (mongoc_async_cmd_run (acmd)) { - BSON_ASSERT (acmd->stream); - } else { - /* this command was removed. */ - continue; - } - } else { - /* don't poll longer than the earliest cmd ready to init. */ - expire_at = BSON_MIN ( - expire_at, acmd->connect_started + acmd->initiate_delay_ms); - } - } - - if (acmd->stream) { - acmds_polled[nstreams] = acmd; - poller[nstreams].stream = acmd->stream; - poller[nstreams].events = acmd->events; - poller[nstreams].revents = 0; - expire_at = BSON_MIN ( - expire_at, acmd->connect_started + acmd->timeout_msec * 1000); - ++nstreams; - } - } - - if (async->ncmds == 0) { - /* all cmds failed to initiate and removed themselves. */ - break; - } - - poll_timeout_msec = BSON_MAX (0, (expire_at - now) / 1000); - BSON_ASSERT (poll_timeout_msec < INT32_MAX); - - if (nstreams > 0) { - /* we need at least one stream to poll. */ - nactive = - mongoc_stream_poll (poller, nstreams, (int32_t) poll_timeout_msec); - } else { - /* currently this does not get hit. we always have at least one command - * initialized with a stream. */ - _mongoc_usleep (poll_timeout_msec * 1000); - } - - if (nactive > 0) { - for (i = 0; i < nstreams; i++) { - mongoc_async_cmd_t *iter = acmds_polled[i]; - if (poller[i].revents & (POLLERR | POLLHUP)) { - int hup = poller[i].revents & POLLHUP; - if (iter->state == MONGOC_ASYNC_CMD_SEND) { - bson_set_error (&iter->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - hup ? "connection refused" - : "unknown connection error"); - } else { - bson_set_error (&iter->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - hup ? "connection closed" - : "unknown socket error"); - } - - iter->state = MONGOC_ASYNC_CMD_ERROR_STATE; - } - - if ((poller[i].revents & poller[i].events) || - iter->state == MONGOC_ASYNC_CMD_ERROR_STATE) { - (void) mongoc_async_cmd_run (iter); - nactive--; - } - - if (!nactive) { - break; - } - } - } - - DL_FOREACH_SAFE (async->cmds, acmd, tmp) - { - bool remove_cmd = false; - mongoc_async_cmd_result_t result; - - /* check if an initiated cmd has passed the connection timeout. */ - if (acmd->state != MONGOC_ASYNC_CMD_INITIATE && - now > acmd->connect_started + acmd->timeout_msec * 1000) { - bson_set_error (&acmd->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - acmd->state == MONGOC_ASYNC_CMD_SEND - ? "connection timeout" - : "socket timeout"); - - remove_cmd = true; - result = MONGOC_ASYNC_CMD_TIMEOUT; - } else if (acmd->state == MONGOC_ASYNC_CMD_CANCELED_STATE) { - remove_cmd = true; - result = MONGOC_ASYNC_CMD_ERROR; - } - - if (remove_cmd) { - acmd->cb (acmd, result, NULL, (now - acmd->connect_started) / 1000); - - /* Remove acmd from the async->cmds doubly-linked list */ - mongoc_async_cmd_destroy (acmd); - } - } - - now = bson_get_monotonic_time (); - } - - bson_free (poller); - bson_free (acmds_polled); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-buffer-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-buffer-private.h deleted file mode 100644 index c0f7dc99c7ec42c370ff2f76f050ba88ad847739..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-buffer-private.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_BUFFER_PRIVATE_H -#define MONGOC_BUFFER_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-stream.h" - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_buffer_t mongoc_buffer_t; - - -struct _mongoc_buffer_t { - uint8_t *data; - size_t datalen; - size_t len; - bson_realloc_func realloc_func; - void *realloc_data; -}; - - -void -_mongoc_buffer_init (mongoc_buffer_t *buffer, - uint8_t *buf, - size_t buflen, - bson_realloc_func realloc_func, - void *realloc_data); - -bool -_mongoc_buffer_append (mongoc_buffer_t *buffer, - const uint8_t *data, - size_t data_size); - -bool -_mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer, - mongoc_stream_t *stream, - size_t size, - int32_t timeout_msec, - bson_error_t *error); - -ssize_t -_mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer, - mongoc_stream_t *stream, - size_t size, - int32_t timeout_msec); - -ssize_t -_mongoc_buffer_fill (mongoc_buffer_t *buffer, - mongoc_stream_t *stream, - size_t min_bytes, - int32_t timeout_msec, - bson_error_t *error); - -void -_mongoc_buffer_destroy (mongoc_buffer_t *buffer); - -void -_mongoc_buffer_clear (mongoc_buffer_t *buffer, bool zero); - - -BSON_END_DECLS - - -#endif /* MONGOC_BUFFER_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-buffer.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-buffer.c deleted file mode 100644 index 593f21e3cd255362ff132a70581fe1f2e0f96234..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-buffer.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2013 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 <bson/bson.h> -#include <stdarg.h> - -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-buffer-private.h" -#include "mongoc/mongoc-trace-private.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "buffer" - -#ifndef MONGOC_BUFFER_DEFAULT_SIZE -#define MONGOC_BUFFER_DEFAULT_SIZE 1024 -#endif - - -#define SPACE_FOR(_b, _sz) \ - (((ssize_t) (_b)->datalen - (ssize_t) (_b)->len) >= (ssize_t) (_sz)) - - -/** - * _mongoc_buffer_init: - * @buffer: A mongoc_buffer_t to initialize. - * @buf: A data buffer to attach to @buffer. - * @buflen: The size of @buflen. - * @realloc_func: A function to resize @buf. - * - * Initializes @buffer for use. If additional space is needed by @buffer, then - * @realloc_func will be called to resize @buf. - * - * @buffer takes ownership of @buf and will realloc it to zero bytes when - * cleaning up the data structure. - */ -void -_mongoc_buffer_init (mongoc_buffer_t *buffer, - uint8_t *buf, - size_t buflen, - bson_realloc_func realloc_func, - void *realloc_data) -{ - BSON_ASSERT (buffer); - BSON_ASSERT (buflen || !buf); - - if (!realloc_func) { - realloc_func = bson_realloc_ctx; - } - - if (!buflen) { - buflen = MONGOC_BUFFER_DEFAULT_SIZE; - } - - if (!buf) { - buf = (uint8_t *) realloc_func (NULL, buflen, NULL); - } - - memset (buffer, 0, sizeof *buffer); - - buffer->data = buf; - buffer->datalen = buflen; - buffer->len = 0; - buffer->realloc_func = realloc_func; - buffer->realloc_data = realloc_data; -} - - -/** - * _mongoc_buffer_destroy: - * @buffer: A mongoc_buffer_t. - * - * Cleanup after @buffer and release any allocated resources. - */ -void -_mongoc_buffer_destroy (mongoc_buffer_t *buffer) -{ - BSON_ASSERT (buffer); - - if (buffer->data && buffer->realloc_func) { - buffer->realloc_func (buffer->data, 0, buffer->realloc_data); - } - - memset (buffer, 0, sizeof *buffer); -} - - -/** - * _mongoc_buffer_clear: - * @buffer: A mongoc_buffer_t. - * @zero: If the memory should be zeroed. - * - * Clears a buffers contents and resets it to initial state. You can request - * that the memory is zeroed, which might be useful if you know the contents - * contain security related information. - */ -void -_mongoc_buffer_clear (mongoc_buffer_t *buffer, bool zero) -{ - BSON_ASSERT (buffer); - - if (zero) { - memset (buffer->data, 0, buffer->datalen); - } - - buffer->len = 0; -} - - -bool -_mongoc_buffer_append (mongoc_buffer_t *buffer, - const uint8_t *data, - size_t data_size) -{ - uint8_t *buf; - - ENTRY; - - BSON_ASSERT (buffer); - BSON_ASSERT (data_size); - - BSON_ASSERT (buffer->datalen); - BSON_ASSERT ((buffer->datalen + data_size) < INT_MAX); - - if (!SPACE_FOR (buffer, data_size)) { - if (buffer->len) { - memmove (&buffer->data[0], buffer->data, buffer->len); - } - - if (!SPACE_FOR (buffer, data_size)) { - buffer->datalen = bson_next_power_of_two (data_size + buffer->len); - buffer->data = (uint8_t *) buffer->realloc_func ( - buffer->data, buffer->datalen, NULL); - } - } - - buf = &buffer->data[buffer->len]; - - BSON_ASSERT ((buffer->len + data_size) <= buffer->datalen); - - memcpy (buf, data, data_size); - - buffer->len += data_size; - - RETURN (true); -} - - -/** - * mongoc_buffer_append_from_stream: - * @buffer; A mongoc_buffer_t. - * @stream: The stream to read from. - * @size: The number of bytes to read. - * @timeout_msec: The number of milliseconds to wait or -1 for the default - * @error: A location for a bson_error_t, or NULL. - * - * Reads from stream @size bytes and stores them in @buffer. This can be used - * in conjunction with reading RPCs from a stream. You read from the stream - * into this buffer and then scatter the buffer into the RPC. - * - * Returns: true if successful; otherwise false and @error is set. - */ -bool -_mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer, - mongoc_stream_t *stream, - size_t size, - int32_t timeout_msec, - bson_error_t *error) -{ - uint8_t *buf; - ssize_t ret; - - ENTRY; - - BSON_ASSERT (buffer); - BSON_ASSERT (stream); - BSON_ASSERT (size); - - BSON_ASSERT (buffer->datalen); - BSON_ASSERT ((buffer->datalen + size) < INT_MAX); - - if (!SPACE_FOR (buffer, size)) { - if (buffer->len) { - memmove (&buffer->data[0], buffer->data, buffer->len); - } - - if (!SPACE_FOR (buffer, size)) { - buffer->datalen = bson_next_power_of_two (size + buffer->len); - buffer->data = (uint8_t *) buffer->realloc_func ( - buffer->data, buffer->datalen, NULL); - } - } - - buf = &buffer->data[buffer->len]; - - BSON_ASSERT ((buffer->len + size) <= buffer->datalen); - - ret = mongoc_stream_read (stream, buf, size, size, timeout_msec); - if (ret != size) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to read %" PRIu64 - " bytes: socket error or timeout", - (uint64_t) size); - RETURN (false); - } - - buffer->len += ret; - - RETURN (true); -} - - -/** - * _mongoc_buffer_fill: - * @buffer: A mongoc_buffer_t. - * @stream: A stream to read from. - * @min_bytes: The minimum number of bytes to read. - * @error: A location for a bson_error_t or NULL. - * - * Attempts to fill the entire buffer, or at least @min_bytes. - * - * Returns: The number of buffered bytes, or -1 on failure. - */ -ssize_t -_mongoc_buffer_fill (mongoc_buffer_t *buffer, - mongoc_stream_t *stream, - size_t min_bytes, - int32_t timeout_msec, - bson_error_t *error) -{ - ssize_t ret; - size_t avail_bytes; - - ENTRY; - - BSON_ASSERT (buffer); - BSON_ASSERT (stream); - - BSON_ASSERT (buffer->data); - BSON_ASSERT (buffer->datalen); - - if (min_bytes <= buffer->len) { - RETURN (buffer->len); - } - - min_bytes -= buffer->len; - - if (buffer->len) { - memmove (&buffer->data[0], buffer->data, buffer->len); - } - - if (!SPACE_FOR (buffer, min_bytes)) { - buffer->datalen = bson_next_power_of_two (buffer->len + min_bytes); - buffer->data = (uint8_t *) buffer->realloc_func ( - buffer->data, buffer->datalen, buffer->realloc_data); - } - - avail_bytes = buffer->datalen - buffer->len; - - ret = mongoc_stream_read ( - stream, &buffer->data[buffer->len], avail_bytes, min_bytes, timeout_msec); - - if (ret == -1) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to buffer %u bytes", - (unsigned) min_bytes); - RETURN (-1); - } - - buffer->len += ret; - - if (buffer->len < min_bytes) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Could only buffer %u of %u bytes", - (unsigned) buffer->len, - (unsigned) min_bytes); - RETURN (-1); - } - - RETURN (buffer->len); -} - - -/** - * mongoc_buffer_try_append_from_stream: - * @buffer; A mongoc_buffer_t. - * @stream: The stream to read from. - * @size: The number of bytes to read. - * @timeout_msec: The number of milliseconds to wait or -1 for the default - * - * Reads from stream @size bytes and stores them in @buffer. This can be used - * in conjunction with reading RPCs from a stream. You read from the stream - * into this buffer and then scatter the buffer into the RPC. - * - * Returns: bytes read if successful; otherwise 0 or -1. - */ -ssize_t -_mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer, - mongoc_stream_t *stream, - size_t size, - int32_t timeout_msec) -{ - uint8_t *buf; - ssize_t ret; - - ENTRY; - - BSON_ASSERT (buffer); - BSON_ASSERT (stream); - BSON_ASSERT (size); - - BSON_ASSERT (buffer->datalen); - BSON_ASSERT ((buffer->datalen + size) < INT_MAX); - - if (!SPACE_FOR (buffer, size)) { - buffer->datalen = bson_next_power_of_two (size + buffer->len); - buffer->data = - (uint8_t *) buffer->realloc_func (buffer->data, buffer->datalen, NULL); - } - - buf = &buffer->data[buffer->len]; - - BSON_ASSERT ((buffer->len + size) <= buffer->datalen); - - ret = mongoc_stream_read (stream, buf, size, 0, timeout_msec); - - if (ret > 0) { - buffer->len += ret; - } - - RETURN (ret); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation-private.h deleted file mode 100644 index 69bb695df8b2cb60cc3e01bae6195febc8d49ad6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation-private.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_BULK_OPERATION_PRIVATE_H -#define MONGOC_BULK_OPERATION_PRIVATE_H - -#include "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-write-command-private.h" - - -BSON_BEGIN_DECLS - -struct _mongoc_bulk_operation_t { - char *database; - char *collection; - mongoc_client_t *client; - mongoc_client_session_t *session; - mongoc_write_concern_t *write_concern; - mongoc_bulk_write_flags_t flags; - uint32_t server_id; - mongoc_array_t commands; - mongoc_write_result_t result; - bool executed; - int64_t operation_id; -}; - - -mongoc_bulk_operation_t * -_mongoc_bulk_operation_new (mongoc_client_t *client, - const char *database, - const char *collection, - mongoc_bulk_write_flags_t flags, - const mongoc_write_concern_t *write_concern); - - -BSON_END_DECLS - - -#endif /* MONGOC_BULK_OPERATION_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation.c deleted file mode 100644 index c8654243379e7580dc3d6d0388669db47abc4381..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation.c +++ /dev/null @@ -1,934 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-bulk-operation.h" -#include "mongoc/mongoc-bulk-operation-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-opts-private.h" -#include "mongoc/mongoc-write-command-private.h" - - -/* - * This is the implementation of both write commands and bulk write commands. - * They are all implemented as one contiguous set since we'd like to cut down - * on code duplication here. - * - * This implementation is currently naive. - * - * Some interesting optimizations might be: - * - * - If unordered mode, send operations as we get them instead of waiting - * for execute() to be called. This could save us memcpy()'s too. - * - If there is no acknowledgement desired, keep a count of how many - * replies we need and ask the socket layer to skip that many bytes - * when reading. - * - Try to use iovec to send write commands with subdocuments rather than - * copying them into the write command document. - */ - - -mongoc_bulk_operation_t * -mongoc_bulk_operation_new (bool ordered) -{ - mongoc_bulk_operation_t *bulk; - - bulk = (mongoc_bulk_operation_t *) bson_malloc0 (sizeof *bulk); - bulk->flags.bypass_document_validation = false; - bulk->flags.ordered = ordered; - bulk->server_id = 0; - - _mongoc_array_init (&bulk->commands, sizeof (mongoc_write_command_t)); - _mongoc_write_result_init (&bulk->result); - - return bulk; -} - - -mongoc_bulk_operation_t * -_mongoc_bulk_operation_new ( - mongoc_client_t *client, /* IN */ - const char *database, /* IN */ - const char *collection, /* IN */ - mongoc_bulk_write_flags_t flags, /* IN */ - const mongoc_write_concern_t *write_concern) /* IN */ -{ - mongoc_bulk_operation_t *bulk; - - BSON_ASSERT (client); - BSON_ASSERT (collection); - - bulk = mongoc_bulk_operation_new (flags.ordered); - bulk->client = client; - bulk->database = bson_strdup (database); - bulk->collection = bson_strdup (collection); - bulk->write_concern = mongoc_write_concern_copy (write_concern); - bulk->executed = false; - bulk->flags = flags; - bulk->operation_id = ++client->cluster.operation_id; - - return bulk; -} - - -void -mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk) /* IN */ -{ - mongoc_write_command_t *command; - int i; - - if (bulk) { - for (i = 0; i < bulk->commands.len; i++) { - command = - &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i); - _mongoc_write_command_destroy (command); - } - - bson_free (bulk->database); - bson_free (bulk->collection); - mongoc_write_concern_destroy (bulk->write_concern); - _mongoc_array_destroy (&bulk->commands); - - _mongoc_write_result_destroy (&bulk->result); - - bson_free (bulk); - } -} - - -/* already failed, e.g. a bad call to mongoc_bulk_operation_insert? */ -#define BULK_EXIT_IF_PRIOR_ERROR \ - do { \ - if (bulk->result.error.domain) { \ - EXIT; \ - } \ - } while (0) - -#define BULK_RETURN_IF_PRIOR_ERROR \ - do { \ - if (bulk->result.error.domain) { \ - if (error != &bulk->result.error) { \ - bson_set_error (error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - "Bulk operation is invalid from prior error: %s", \ - bulk->result.error.message); \ - }; \ - return false; \ - }; \ - } while (0) - - -bool -_mongoc_bulk_operation_remove_with_opts ( - mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const mongoc_bulk_remove_opts_t *remove_opts, - int32_t limit, - bson_error_t *error) /* OUT */ -{ - mongoc_write_command_t command = {0}; - mongoc_write_command_t *last; - bson_t opts; - bool has_collation; - bool ret = false; - - ENTRY; - - BSON_ASSERT (bulk); - BSON_ASSERT (selector); - - bson_init (&opts); - - /* allow "limit" in opts, but it must be the correct limit */ - if (remove_opts->limit != limit) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid \"limit\" in opts: %" PRId32 "." - " The value must be %" PRId32 ", or omitted.", - remove_opts->limit, - limit); - GOTO (done); - } - - bson_append_int32 (&opts, "limit", 5, limit); - has_collation = !bson_empty (&remove_opts->collation); - if (has_collation) { - bson_append_document (&opts, "collation", 9, &remove_opts->collation); - } - - if (bulk->commands.len) { - last = &_mongoc_array_index ( - &bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); - if (last->type == MONGOC_WRITE_COMMAND_DELETE) { - last->flags.has_collation |= has_collation; - last->flags.has_multi_write |= (remove_opts->limit == 0); - _mongoc_write_command_delete_append (last, selector, &opts); - ret = true; - GOTO (done); - } - } - - _mongoc_write_command_init_delete ( - &command, selector, NULL, &opts, bulk->flags, bulk->operation_id); - - command.flags.has_collation = has_collation; - command.flags.has_multi_write = (remove_opts->limit == 0); - - _mongoc_array_append_val (&bulk->commands, command); - ret = true; - -done: - bson_destroy (&opts); - RETURN (ret); -} - - -bool -mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *opts, - bson_error_t *error) /* OUT */ -{ - mongoc_bulk_remove_one_opts_t remove_opts; - bool ret; - - ENTRY; - - BULK_RETURN_IF_PRIOR_ERROR; - - if (!_mongoc_bulk_remove_one_opts_parse ( - bulk->client, opts, &remove_opts, error)) { - _mongoc_bulk_remove_one_opts_cleanup (&remove_opts); - RETURN (false); - } - - ret = _mongoc_bulk_operation_remove_with_opts ( - bulk, selector, &remove_opts.remove, 1, error); - - _mongoc_bulk_remove_one_opts_cleanup (&remove_opts); - RETURN (ret); -} - - -bool -mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *opts, - bson_error_t *error) /* OUT */ -{ - mongoc_bulk_remove_many_opts_t remove_opts; - bool ret; - - ENTRY; - - BULK_RETURN_IF_PRIOR_ERROR; - - if (!_mongoc_bulk_remove_many_opts_parse ( - bulk->client, opts, &remove_opts, error)) { - _mongoc_bulk_remove_many_opts_cleanup (&remove_opts); - RETURN (false); - } - - ret = _mongoc_bulk_operation_remove_with_opts ( - bulk, selector, &remove_opts.remove, 0, error); - - _mongoc_bulk_remove_many_opts_cleanup (&remove_opts); - RETURN (ret); -} - - -void -mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, /* IN */ - const bson_t *selector) /* IN */ -{ - bson_error_t *error = &bulk->result.error; - - ENTRY; - - BULK_EXIT_IF_PRIOR_ERROR; - - if (!mongoc_bulk_operation_remove_many_with_opts ( - bulk, selector, NULL, error)) { - MONGOC_WARNING ("%s", error->message); - } - - if (error->domain) { - MONGOC_WARNING ("%s", error->message); - } - - EXIT; -} - - -void -mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, /* IN */ - const bson_t *selector) /* IN */ -{ - bson_error_t *error = &bulk->result.error; - - ENTRY; - - BULK_EXIT_IF_PRIOR_ERROR; - - if (!mongoc_bulk_operation_remove_one_with_opts ( - bulk, selector, NULL, error)) { - MONGOC_WARNING ("%s", error->message); - } - - if (error->domain) { - MONGOC_WARNING ("%s", error->message); - } - - EXIT; -} - -void -mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk, - const bson_t *selector) -{ - ENTRY; - - mongoc_bulk_operation_remove (bulk, selector); - - EXIT; -} - -void -mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector) -{ - ENTRY; - - mongoc_bulk_operation_remove_one (bulk, selector); - - EXIT; -} - -void -mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk, - const bson_t *document) -{ - ENTRY; - - BSON_ASSERT (bulk); - BSON_ASSERT (document); - - if (!mongoc_bulk_operation_insert_with_opts ( - bulk, document, NULL /* opts */, &bulk->result.error)) { - MONGOC_WARNING ("%s", bulk->result.error.message); - } - - EXIT; -} - -bool -mongoc_bulk_operation_insert_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *document, - const bson_t *opts, - bson_error_t *error) -{ - mongoc_bulk_insert_opts_t insert_opts; - mongoc_write_command_t command = {0}; - mongoc_write_command_t *last; - bool ret = false; - - ENTRY; - - BSON_ASSERT (bulk); - BSON_ASSERT (document); - - BULK_RETURN_IF_PRIOR_ERROR; - - if (!_mongoc_bulk_insert_opts_parse ( - bulk->client, opts, &insert_opts, error)) { - GOTO (done); - } - - if (!_mongoc_validate_new_document (document, insert_opts.validate, error)) { - GOTO (done); - } - - if (bulk->commands.len) { - last = &_mongoc_array_index ( - &bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); - - if (last->type == MONGOC_WRITE_COMMAND_INSERT) { - _mongoc_write_command_insert_append (last, document); - ret = true; - GOTO (done); - } - } - - _mongoc_write_command_init_insert ( - &command, - document, - &insert_opts.extra, - bulk->flags, - bulk->operation_id); - - _mongoc_array_append_val (&bulk->commands, command); - - ret = true; - -done: - _mongoc_bulk_insert_opts_cleanup (&insert_opts); - RETURN (ret); -} - -static void -_mongoc_bulk_operation_update_append ( - mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const mongoc_bulk_update_opts_t *update_opts, - const bson_t *array_filters, - const bson_t *extra_opts) -{ - mongoc_write_command_t command = {0}; - mongoc_write_command_t *last; - bson_t opts; - bool has_collation; - bool has_array_filters; - - bson_init (&opts); - bson_append_bool (&opts, "upsert", 6, update_opts->upsert); - bson_append_bool (&opts, "multi", 5, update_opts->multi); - - has_array_filters = !bson_empty0 (array_filters); - if (has_array_filters) { - bson_append_array (&opts, "arrayFilters", 12, array_filters); - } - - has_collation = !bson_empty (&update_opts->collation); - if (has_collation) { - bson_append_document (&opts, "collation", 9, &update_opts->collation); - } - - if (extra_opts) { - bson_concat (&opts, extra_opts); - } - - if (bulk->commands.len) { - last = &_mongoc_array_index ( - &bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); - if (last->type == MONGOC_WRITE_COMMAND_UPDATE) { - last->flags.has_collation |= has_collation; - last->flags.has_multi_write |= update_opts->multi; - _mongoc_write_command_update_append (last, selector, document, &opts); - bson_destroy (&opts); - return; - } - } - - _mongoc_write_command_init_update ( - &command, selector, document, &opts, bulk->flags, bulk->operation_id); - - command.flags.has_array_filters = has_array_filters; - command.flags.has_collation = has_collation; - command.flags.has_multi_write = update_opts->multi; - - _mongoc_array_append_val (&bulk->commands, command); - bson_destroy (&opts); -} - -static bool -_mongoc_bulk_operation_update_with_opts ( - mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const mongoc_bulk_update_opts_t *update_opts, - const bson_t *array_filters, - const bson_t *extra_opts, - bool multi, - bson_error_t *error) /* OUT */ -{ - ENTRY; - - BSON_ASSERT (bulk); - BSON_ASSERT (selector); - BSON_ASSERT (document); - - if (!_mongoc_validate_update (document, update_opts->validate, error)) { - RETURN (false); - } - - /* allow "multi" in opts, but it must be the correct multi */ - if (update_opts->multi != multi) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid \"multi\" in opts: %s." - " The value must be %s, or omitted.", - update_opts->multi ? "true" : "false", - multi ? "true" : "false"); - RETURN (false); - } - - _mongoc_bulk_operation_update_append ( - bulk, selector, document, update_opts, array_filters, extra_opts); - - RETURN (true); -} - -bool -mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error) /* OUT */ -{ - mongoc_bulk_update_one_opts_t update_opts; - bool ret; - - ENTRY; - - BULK_RETURN_IF_PRIOR_ERROR; - - if (!_mongoc_bulk_update_one_opts_parse ( - bulk->client, opts, &update_opts, error)) { - _mongoc_bulk_update_one_opts_cleanup (&update_opts); - RETURN (false); - } - - ret = _mongoc_bulk_operation_update_with_opts (bulk, - selector, - document, - &update_opts.update, - &update_opts.arrayFilters, - &update_opts.extra, - false /* multi */, - error); - - _mongoc_bulk_update_one_opts_cleanup (&update_opts); - RETURN (ret); -} - -bool -mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error) /* OUT */ -{ - mongoc_bulk_update_many_opts_t update_opts; - bool ret; - - ENTRY; - - BULK_RETURN_IF_PRIOR_ERROR; - - if (!_mongoc_bulk_update_many_opts_parse ( - bulk->client, opts, &update_opts, error)) { - _mongoc_bulk_update_many_opts_cleanup (&update_opts); - RETURN (false); - } - - ret = _mongoc_bulk_operation_update_with_opts (bulk, - selector, - document, - &update_opts.update, - &update_opts.arrayFilters, - &update_opts.extra, - true /* multi */, - error); - - _mongoc_bulk_update_many_opts_cleanup (&update_opts); - RETURN (ret); -} - -void -mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert) -{ - bson_t opts; - bson_error_t *error = &bulk->result.error; - - ENTRY; - - BULK_EXIT_IF_PRIOR_ERROR; - - bson_init (&opts); - if (upsert) { - BSON_APPEND_BOOL (&opts, "upsert", upsert); - } - - if (!mongoc_bulk_operation_update_many_with_opts ( - bulk, selector, document, &opts, error)) { - MONGOC_WARNING ("%s", error->message); - } - - bson_destroy (&opts); - - if (error->domain) { - MONGOC_WARNING ("%s", error->message); - } - - EXIT; -} - -void -mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert) -{ - bson_t opts; - bson_error_t *error = &bulk->result.error; - - ENTRY; - - BULK_EXIT_IF_PRIOR_ERROR; - - bson_init (&opts); - BSON_APPEND_BOOL (&opts, "upsert", upsert); - - if (!mongoc_bulk_operation_update_one_with_opts ( - bulk, selector, document, &opts, error)) { - MONGOC_WARNING ("%s", error->message); - } - - bson_destroy (&opts); - - if (error->domain) { - MONGOC_WARNING ("%s", error->message); - } - - EXIT; -} - -bool -mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error) /* OUT */ -{ - mongoc_bulk_replace_one_opts_t repl_opts; - mongoc_bulk_update_opts_t *update_opts = &repl_opts.update; - bool ret = false; - - ENTRY; - - BSON_ASSERT (bulk); - BSON_ASSERT (selector); - BSON_ASSERT (document); - - BULK_RETURN_IF_PRIOR_ERROR; - - if (!_mongoc_bulk_replace_one_opts_parse ( - bulk->client, opts, &repl_opts, error)) { - GOTO (done); - } - - if (!_mongoc_validate_replace (document, update_opts->validate, error)) { - GOTO (done); - } - - /* allow "multi" in opts, but it must be the correct multi */ - if (update_opts->multi) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid \"multi\": true in opts for" - " mongoc_bulk_operation_replace_one_with_opts." - " The value must be true, or omitted."); - GOTO (done); - } - - _mongoc_bulk_operation_update_append ( - bulk, selector, document, update_opts, NULL, &repl_opts.extra); - ret = true; - -done: - _mongoc_bulk_replace_one_opts_cleanup (&repl_opts); - RETURN (ret); -} - -void -mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert) -{ - bson_t opts = BSON_INITIALIZER; - bson_error_t *error = &bulk->result.error; - - ENTRY; - - BSON_APPEND_BOOL (&opts, "upsert", upsert); - - if (!mongoc_bulk_operation_replace_one_with_opts ( - bulk, selector, document, &opts, error)) { - MONGOC_WARNING ("%s", error->message); - } - - bson_destroy (&opts); - - EXIT; -} - -uint32_t -mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */ - bson_t *reply, /* OUT */ - bson_error_t *error) /* OUT */ -{ - mongoc_cluster_t *cluster; - mongoc_write_command_t *command; - mongoc_server_stream_t *server_stream; - bool ret; - uint32_t offset = 0; - int i; - - ENTRY; - - BSON_ASSERT (bulk); - - if (!bulk->client) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "mongoc_bulk_operation_execute() requires a client " - "and one has not been set."); - GOTO (err); - } - cluster = &bulk->client->cluster; - - if (bulk->executed) { - _mongoc_write_result_destroy (&bulk->result); - _mongoc_write_result_init (&bulk->result); - } - - bulk->executed = true; - - if (!bulk->database) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "mongoc_bulk_operation_execute() requires a database " - "and one has not been set."); - GOTO (err); - } else if (!bulk->collection) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "mongoc_bulk_operation_execute() requires a collection " - "and one has not been set."); - GOTO (err); - } - - /* error stored by functions like mongoc_bulk_operation_insert that - * can't report errors immediately */ - if (bulk->result.error.domain) { - if (error) { - memcpy (error, &bulk->result.error, sizeof (bson_error_t)); - } - - GOTO (err); - } - - if (!bulk->commands.len) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot do an empty bulk write"); - GOTO (err); - } - - for (i = 0; i < bulk->commands.len; i++) { - if (bulk->server_id) { - server_stream = - mongoc_cluster_stream_for_server (cluster, - bulk->server_id, - true /* reconnect_ok */, - bulk->session, - reply, - error); - } else { - server_stream = mongoc_cluster_stream_for_writes ( - cluster, bulk->session, reply, error); - } - - if (!server_stream) { - /* stream_for_server and stream_for_writes initialize reply on error */ - RETURN (false); - } - - command = - &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i); - - _mongoc_write_command_execute (command, - bulk->client, - server_stream, - bulk->database, - bulk->collection, - bulk->write_concern, - offset, - bulk->session, - &bulk->result); - - bulk->server_id = server_stream->sd->id; - - if (bulk->result.failed && - (bulk->flags.ordered || bulk->result.must_stop)) { - mongoc_server_stream_cleanup (server_stream); - GOTO (cleanup); - } - - offset += command->n_documents; - mongoc_server_stream_cleanup (server_stream); - } - -cleanup: - _mongoc_bson_init_if_set (reply); - ret = MONGOC_WRITE_RESULT_COMPLETE (&bulk->result, - bulk->client->error_api_version, - bulk->write_concern, - MONGOC_ERROR_COMMAND /* err domain */, - reply, - error); - - RETURN (ret ? bulk->server_id : 0); - -err: - _mongoc_bson_init_if_set (reply); - RETURN (false); -} - -void -mongoc_bulk_operation_set_write_concern ( - mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (bulk); - - if (bulk->write_concern) { - mongoc_write_concern_destroy (bulk->write_concern); - } - - if (write_concern) { - bulk->write_concern = mongoc_write_concern_copy (write_concern); - } else { - bulk->write_concern = mongoc_write_concern_new (); - } -} - -const mongoc_write_concern_t * -mongoc_bulk_operation_get_write_concern (const mongoc_bulk_operation_t *bulk) -{ - BSON_ASSERT (bulk); - - return bulk->write_concern; -} - - -void -mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk, - const char *database) -{ - BSON_ASSERT (bulk); - - if (bulk->database) { - bson_free (bulk->database); - } - - bulk->database = bson_strdup (database); -} - - -void -mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk, - const char *collection) -{ - BSON_ASSERT (bulk); - - if (bulk->collection) { - bson_free (bulk->collection); - } - - bulk->collection = bson_strdup (collection); -} - - -void -mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk, void *client) -{ - BSON_ASSERT (bulk); - BSON_ASSERT (client); - - if (bulk->session) { - BSON_ASSERT (bulk->session->client == client); - } - - bulk->client = (mongoc_client_t *) client; - - /* if you call set_client, bulk was likely made by mongoc_bulk_operation_new, - * not mongoc_collection_create_bulk_operation_with_opts(), so operation_id - * is 0. */ - if (!bulk->operation_id) { - bulk->operation_id = ++bulk->client->cluster.operation_id; - } -} - - -void -mongoc_bulk_operation_set_client_session ( - mongoc_bulk_operation_t *bulk, - struct _mongoc_client_session_t *client_session) -{ - BSON_ASSERT (bulk); - BSON_ASSERT (client_session); - - if (bulk->client) { - BSON_ASSERT (bulk->client == client_session->client); - } - - bulk->session = client_session; -} - - -uint32_t -mongoc_bulk_operation_get_hint (const mongoc_bulk_operation_t *bulk) -{ - BSON_ASSERT (bulk); - - return bulk->server_id; -} - - -void -mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk, - uint32_t server_id) -{ - BSON_ASSERT (bulk); - - bulk->server_id = server_id; -} - - -void -mongoc_bulk_operation_set_bypass_document_validation ( - mongoc_bulk_operation_t *bulk, bool bypass) -{ - BSON_ASSERT (bulk); - - bulk->flags.bypass_document_validation = bypass; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation.h deleted file mode 100644 index 7db6ab8fb2b7555967987015d480980e5e83b492..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-bulk-operation.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_BULK_OPERATION_H -#define MONGOC_BULK_OPERATION_H - - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-write-concern.h" - -/* ordered, bypass_document_validation, has_collation, multi */ -#define MONGOC_BULK_WRITE_FLAGS_INIT \ - { \ - true, false, 0 \ - } - -BSON_BEGIN_DECLS - -/* forward decl */ -struct _mongoc_client_session_t; - -typedef struct _mongoc_bulk_operation_t mongoc_bulk_operation_t; -typedef struct _mongoc_bulk_write_flags_t mongoc_bulk_write_flags_t; - - -MONGOC_EXPORT (void) -mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk); -MONGOC_EXPORT (uint32_t) -mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (void) -mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk, - const bson_t *selector) - BSON_GNUC_DEPRECATED_FOR (mongoc_bulk_operation_remove); -MONGOC_EXPORT (void) -mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector) - BSON_GNUC_DEPRECATED_FOR (mongoc_bulk_operation_remove_one); -MONGOC_EXPORT (void) -mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk, - const bson_t *document); -MONGOC_EXPORT (bool) -mongoc_bulk_operation_insert_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); /* OUT */ -MONGOC_EXPORT (void) -mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, - const bson_t *selector); -MONGOC_EXPORT (bool) -mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *opts, - bson_error_t *error); /* OUT */ -MONGOC_EXPORT (void) -mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector); -MONGOC_EXPORT (bool) -mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *opts, - bson_error_t *error); /* OUT */ -MONGOC_EXPORT (void) -mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert); -MONGOC_EXPORT (bool) -mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); /* OUT */ -MONGOC_EXPORT (void) -mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert); -MONGOC_EXPORT (bool) -mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); /* OUT */ -MONGOC_EXPORT (void) -mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert); -MONGOC_EXPORT (bool) -mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); /* OUT */ -MONGOC_EXPORT (void) -mongoc_bulk_operation_set_bypass_document_validation ( - mongoc_bulk_operation_t *bulk, bool bypass); - - -/* - * The following functions are really only useful by language bindings and - * those wanting to replay a bulk operation to a number of clients or - * collections. - */ -MONGOC_EXPORT (mongoc_bulk_operation_t *) -mongoc_bulk_operation_new (bool ordered); -MONGOC_EXPORT (void) -mongoc_bulk_operation_set_write_concern ( - mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (void) -mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk, - const char *database); -MONGOC_EXPORT (void) -mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk, - const char *collection); -MONGOC_EXPORT (void) -mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk, void *client); -MONGOC_EXPORT (void) -mongoc_bulk_operation_set_client_session ( - mongoc_bulk_operation_t *bulk, - struct _mongoc_client_session_t *client_session); -/* These names include the term "hint" for backward compatibility, should be - * mongoc_bulk_operation_get_server_id, mongoc_bulk_operation_set_server_id. */ -MONGOC_EXPORT (void) -mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk, - uint32_t server_id); -MONGOC_EXPORT (uint32_t) -mongoc_bulk_operation_get_hint (const mongoc_bulk_operation_t *bulk); -MONGOC_EXPORT (const mongoc_write_concern_t *) -mongoc_bulk_operation_get_write_concern (const mongoc_bulk_operation_t *bulk); -BSON_END_DECLS - - -#endif /* MONGOC_BULK_OPERATION_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream-private.h deleted file mode 100644 index 3717942b8c3a2bfeb381c663604aedcb11016422..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream-private.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2017-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CHANGE_STREAM_PRIVATE_H -#define MONGOC_CHANGE_STREAM_PRIVATE_H - -#include "mongoc/mongoc-change-stream.h" -#include "mongoc/mongoc-client-session.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-opts-private.h" -#include "mongoc/mongoc-opts-helpers-private.h" - -typedef enum { - MONGOC_CHANGE_STREAM_COLLECTION, - MONGOC_CHANGE_STREAM_DATABASE, - MONGOC_CHANGE_STREAM_CLIENT -} mongoc_change_stream_type_t; - -struct _mongoc_change_stream_t { - mongoc_change_stream_opts_t opts; - mongoc_timestamp_t operation_time; - bson_t pipeline_to_append; - bson_t resume_token; - bson_t *full_document; - - bson_error_t err; - bson_t err_doc; - - mongoc_cursor_t *cursor; - - mongoc_client_t *client; - mongoc_read_prefs_t *read_prefs; - mongoc_read_concern_t *read_concern; - - mongoc_change_stream_type_t change_stream_type; - char db[140]; - char coll[140]; - - int64_t max_await_time_ms; - int32_t batch_size; - - bool has_returned_results; - - /* Track whether the change stream has resumed after an error, as this - * determines how we construct an initial or resuming aggregate command. */ - bool resumed; - - mongoc_client_session_t *implicit_session; -}; - -mongoc_change_stream_t * -_mongoc_change_stream_new_from_collection (const mongoc_collection_t *coll, - const bson_t *pipeline, - const bson_t *opts); - -mongoc_change_stream_t * -_mongoc_change_stream_new_from_database (const mongoc_database_t *db, - const bson_t *pipeline, - const bson_t *opts); - -mongoc_change_stream_t * -_mongoc_change_stream_new_from_client (mongoc_client_t *client, - const bson_t *pipeline, - const bson_t *opts); - -#endif /* MONGOC_CHANGE_STREAM_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream.c deleted file mode 100644 index 9c6feddefee9a352e3ac6011fda66cdb71bbd2b7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Copyright 2017-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 <bson/bson.h> -#include "mongoc/mongoc-change-stream-private.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-client-session-private.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-database-private.h" -#include "mongoc/mongoc-error.h" - -#define CHANGE_STREAM_ERR(_str) \ - bson_set_error (&stream->err, \ - MONGOC_ERROR_CURSOR, \ - MONGOC_ERROR_BSON, \ - "Could not set " _str); - -/* the caller knows either a client or server error has occurred. - * `reply` contains the server reply or an empty document. */ -static bool -_is_resumable_error (const bson_t *reply) -{ - bson_error_t error = {0}; - - /* Change Streams Spec resumable criteria: "any error encountered which is - * not a server error (e.g. a timeout error or network error)" */ - if (bson_empty (reply)) { - return true; - } - - if (_mongoc_cmd_check_ok (reply, MONGOC_ERROR_API_VERSION_2, &error)) { - return true; - } - - if (mongoc_error_has_label (reply, "NonResumableChangeStreamError")) { - return false; - } - - /* Change Streams Spec resumable criteria: "a server error response with an - * error message containing the substring 'not master' or 'node is - * recovering' */ - if (strstr (error.message, "not master") || - strstr (error.message, "node is recovering")) { - return true; - } - - /* Change Streams Spec resumable criteria: "any server error response from a - * getMore command excluding those containing the following error codes" */ - switch (error.code) { - case 11601: /* Interrupted */ - case 136: /* CappedPositionLost */ - case 237: /* CursorKilled */ - case MONGOC_ERROR_QUERY_FAILURE: /* error code omitted */ - return false; - default: - return true; - } -} - - -static void -_set_resume_token (mongoc_change_stream_t *stream, const bson_t *resume_token) -{ - BSON_ASSERT (stream); - BSON_ASSERT (resume_token); - - bson_destroy (&stream->resume_token); - bson_copy_to (resume_token, &stream->resume_token); -} - - -/* construct the aggregate command in cmd. looks like one of the following: - * for a collection change stream: - * { aggregate: collname, pipeline: [], cursor: { batchSize: x } } - * for a database change stream: - * { aggregate: 1, pipeline: [], cursor: { batchSize: x } } - * for a client change stream: - * { aggregate: 1, pipeline: [{$changeStream: {allChangesForCluster: true}}], - * cursor: { batchSize: x } } - */ -static void -_make_command (mongoc_change_stream_t *stream, - bson_t *command, - int32_t max_wire_version) -{ - bson_iter_t iter; - bson_t change_stream_stage; /* { $changeStream: <change_stream_doc> } */ - bson_t change_stream_doc; - bson_t pipeline; - bson_t cursor_doc; - - if (stream->change_stream_type == MONGOC_CHANGE_STREAM_COLLECTION) { - bson_append_utf8 ( - command, "aggregate", 9, stream->coll, (int) strlen (stream->coll)); - } else { - bson_append_int32 (command, "aggregate", 9, 1); - } - - bson_append_array_begin (command, "pipeline", 8, &pipeline); - - /* append the $changeStream stage. */ - bson_append_document_begin (&pipeline, "0", 1, &change_stream_stage); - bson_append_document_begin ( - &change_stream_stage, "$changeStream", 13, &change_stream_doc); - bson_concat (&change_stream_doc, stream->full_document); - - if (stream->resumed) { - /* Change stream spec: Resume Process */ - /* If there is a cached resumeToken: */ - if (!bson_empty (&stream->resume_token)) { - /* If the ChangeStream was started with startAfter - and has yet to return a result document: */ - if (!bson_empty (&stream->opts.startAfter) && - !stream->has_returned_results) { - /* The driver MUST set startAfter to the cached resumeToken */ - BSON_APPEND_DOCUMENT ( - &change_stream_doc, "startAfter", &stream->resume_token); - } else { - /* The driver MUST set resumeAfter to the cached resumeToken */ - BSON_APPEND_DOCUMENT ( - &change_stream_doc, "resumeAfter", &stream->resume_token); - } - } else if (!_mongoc_timestamp_empty (&stream->operation_time) && - max_wire_version >= 7) { - /* Else if there is no cached resumeToken and the ChangeStream - has a saved operation time and the max wire version is >= 7, - the driver MUST set startAtOperationTime */ - _mongoc_timestamp_append (&stream->operation_time, - &change_stream_doc, - "startAtOperationTime"); - } - } else { - /* Change streams spec: "startAtOperationTime, resumeAfter, and startAfter - * are all mutually exclusive; if any two are set, the server will return - * an error. Drivers MUST NOT throw a custom error, and MUST defer to the - * server error." */ - if (!bson_empty (&stream->opts.resumeAfter)) { - BSON_APPEND_DOCUMENT ( - &change_stream_doc, "resumeAfter", &stream->opts.resumeAfter); - - /* Update the cached resume token */ - _set_resume_token (stream, &stream->opts.resumeAfter); - } - - if (!bson_empty (&stream->opts.startAfter)) { - BSON_APPEND_DOCUMENT ( - &change_stream_doc, "startAfter", &stream->opts.startAfter); - - /* Update the cached resume token (take precedence over resumeAfter) */ - _set_resume_token (stream, &stream->opts.startAfter); - } - - if (!_mongoc_timestamp_empty (&stream->operation_time)) { - _mongoc_timestamp_append (&stream->operation_time, - &change_stream_doc, - "startAtOperationTime"); - } - } - - if (stream->change_stream_type == MONGOC_CHANGE_STREAM_CLIENT) { - bson_append_bool (&change_stream_doc, "allChangesForCluster", 20, true); - } - bson_append_document_end (&change_stream_stage, &change_stream_doc); - bson_append_document_end (&pipeline, &change_stream_stage); - - /* Append user pipeline if it exists */ - if (bson_iter_init_find (&iter, &stream->pipeline_to_append, "pipeline") && - BSON_ITER_HOLDS_ARRAY (&iter)) { - bson_iter_t child_iter; - uint32_t key_int = 1; - char buf[16]; - const char *key_str; - - BSON_ASSERT (bson_iter_recurse (&iter, &child_iter)); - while (bson_iter_next (&child_iter)) { - /* the user pipeline may consist of invalid stages or non-documents. - * append anyway, and rely on the server error. */ - size_t keyLen = - bson_uint32_to_string (key_int, &key_str, buf, sizeof (buf)); - bson_append_value ( - &pipeline, key_str, (int) keyLen, bson_iter_value (&child_iter)); - ++key_int; - } - } - - bson_append_array_end (command, &pipeline); - - /* Add batch size if needed */ - bson_append_document_begin (command, "cursor", 6, &cursor_doc); - if (stream->batch_size > 0) { - bson_append_int32 (&cursor_doc, "batchSize", 9, stream->batch_size); - } - bson_append_document_end (command, &cursor_doc); -} - -/*--------------------------------------------------------------------------- - * - * _make_cursor -- - * - * Construct and send the aggregate command and create the resulting - * cursor. On error, stream->cursor remains NULL, otherwise it is - * created and must be destroyed. - * - * Return: - * False on error and sets stream->err. - * - *-------------------------------------------------------------------------- - */ -static bool -_make_cursor (mongoc_change_stream_t *stream) -{ - mongoc_client_session_t *cs = NULL; - bson_t command_opts; - bson_t command; /* { aggregate: "coll", pipeline: [], ... } */ - bson_t reply; - bson_t getmore_opts = BSON_INITIALIZER; - bson_iter_t iter; - mongoc_server_description_t *sd; - uint32_t server_id; - int32_t max_wire_version = -1; - - BSON_ASSERT (stream); - BSON_ASSERT (!stream->cursor); - bson_init (&command); - bson_copy_to (&(stream->opts.extra), &command_opts); - sd = mongoc_client_select_server ( - stream->client, false /* for_writes */, stream->read_prefs, &stream->err); - if (!sd) { - goto cleanup; - } - server_id = mongoc_server_description_id (sd); - bson_append_int32 (&command_opts, "serverId", 8, server_id); - bson_append_int32 (&getmore_opts, "serverId", 8, server_id); - max_wire_version = sd->max_wire_version; - mongoc_server_description_destroy (sd); - - if (bson_iter_init_find (&iter, &command_opts, "sessionId")) { - if (!_mongoc_client_session_from_iter ( - stream->client, &iter, &cs, &stream->err)) { - goto cleanup; - } - } else if (stream->implicit_session) { - /* If an implicit session was created before, and this cursor is now - * being recreated after resuming, then use the same session as before. */ - cs = stream->implicit_session; - if (!mongoc_client_session_append (cs, &command_opts, &stream->err)) { - goto cleanup; - } - } else { - /* Create an implicit session. This session lsid must be the same for the - * agg command and the subsequent getMores. Thus, this implicit session is - * passed as if it were an explicit session to - * mongoc_client_read_command_with_opts and - * _mongoc_cursor_change_stream_new, but it is still implicit and its - * lifetime is owned by this change_stream_t. */ - mongoc_session_opt_t *session_opts; - session_opts = mongoc_session_opts_new (); - mongoc_session_opts_set_causal_consistency (session_opts, false); - /* returns NULL if sessions aren't supported. ignore errors. */ - cs = mongoc_client_start_session (stream->client, session_opts, NULL); - stream->implicit_session = cs; - mongoc_session_opts_destroy (session_opts); - if (cs && - !mongoc_client_session_append (cs, &command_opts, &stream->err)) { - goto cleanup; - } - } - - if (cs && !mongoc_client_session_append (cs, &getmore_opts, &stream->err)) { - goto cleanup; - } - - if (stream->read_concern && !bson_has_field (&command_opts, "readConcern")) { - mongoc_read_concern_append (stream->read_concern, &command_opts); - } - - _make_command (stream, &command, max_wire_version); - - /* even though serverId has already been set, still pass the read prefs. - * they are necessary for OP_MSG if sending to a secondary. */ - if (!mongoc_client_read_command_with_opts (stream->client, - stream->db, - &command, - stream->read_prefs, - &command_opts, - &reply, - &stream->err)) { - bson_destroy (&stream->err_doc); - bson_copy_to (&reply, &stream->err_doc); - bson_destroy (&reply); - goto cleanup; - } - - bson_append_bool ( - &getmore_opts, MONGOC_CURSOR_TAILABLE, MONGOC_CURSOR_TAILABLE_LEN, true); - bson_append_bool (&getmore_opts, - MONGOC_CURSOR_AWAIT_DATA, - MONGOC_CURSOR_AWAIT_DATA_LEN, - true); - - /* maxTimeMS is only appended to getMores if these are set in cursor opts. */ - if (stream->max_await_time_ms > 0) { - bson_append_int64 (&getmore_opts, - MONGOC_CURSOR_MAX_AWAIT_TIME_MS, - MONGOC_CURSOR_MAX_AWAIT_TIME_MS_LEN, - stream->max_await_time_ms); - } - - if (stream->batch_size > 0) { - bson_append_int32 (&getmore_opts, - MONGOC_CURSOR_BATCH_SIZE, - MONGOC_CURSOR_BATCH_SIZE_LEN, - stream->batch_size); - } - - /* steals reply. */ - stream->cursor = - _mongoc_cursor_change_stream_new (stream->client, &reply, &getmore_opts); - - if (mongoc_cursor_error (stream->cursor, NULL)) { - goto cleanup; - } - - /* Change stream spec: "When aggregate or getMore returns: If an empty batch - * was returned and a postBatchResumeToken was included, cache it." */ - if (_mongoc_cursor_change_stream_end_of_batch (stream->cursor) && - _mongoc_cursor_change_stream_has_post_batch_resume_token ( - stream->cursor)) { - _set_resume_token ( - stream, - _mongoc_cursor_change_stream_get_post_batch_resume_token ( - stream->cursor)); - } - - /* Change stream spec: startAtOperationTime */ - if (bson_empty (&stream->opts.resumeAfter) && - bson_empty (&stream->opts.startAfter) && - _mongoc_timestamp_empty (&stream->operation_time) && - max_wire_version >= 7 && bson_empty (&stream->resume_token) && - bson_iter_init_find ( - &iter, - _mongoc_cursor_change_stream_get_reply (stream->cursor), - "operationTime") && - BSON_ITER_HOLDS_TIMESTAMP (&iter)) { - _mongoc_timestamp_set_from_bson (&stream->operation_time, &iter); - } - -cleanup: - bson_destroy (&command); - bson_destroy (&command_opts); - bson_destroy (&getmore_opts); - return stream->err.code == 0; -} - -/*--------------------------------------------------------------------------- - * - * _change_stream_init -- - * - * Called after @stream has the collection name, database name, read - * preferences, and read concern set. Creates the change streams - * cursor. - * - *-------------------------------------------------------------------------- - */ -void -_change_stream_init (mongoc_change_stream_t *stream, - const bson_t *pipeline, - const bson_t *opts) -{ - BSON_ASSERT (pipeline); - - stream->max_await_time_ms = -1; - stream->batch_size = -1; - bson_init (&stream->pipeline_to_append); - bson_init (&stream->resume_token); - bson_init (&stream->err_doc); - - if (!_mongoc_change_stream_opts_parse ( - stream->client, opts, &stream->opts, &stream->err)) { - return; - } - - stream->full_document = BCON_NEW ("fullDocument", stream->opts.fullDocument); - - _mongoc_timestamp_set (&stream->operation_time, - &stream->opts.startAtOperationTime); - - stream->batch_size = stream->opts.batchSize; - stream->max_await_time_ms = stream->opts.maxAwaitTimeMS; - - /* Accept two forms of user pipeline: - * 1. A document like: { "pipeline": [...] } - * 2. An array-like document: { "0": {}, "1": {}, ... } - * If the passed pipeline is invalid, we pass it along and let the server - * error instead. - */ - if (!bson_empty (pipeline)) { - bson_iter_t iter; - if (bson_iter_init_find (&iter, pipeline, "pipeline") && - BSON_ITER_HOLDS_ARRAY (&iter)) { - if (!BSON_APPEND_VALUE (&stream->pipeline_to_append, - "pipeline", - bson_iter_value (&iter))) { - CHANGE_STREAM_ERR ("pipeline"); - } - } else { - if (!BSON_APPEND_ARRAY ( - &stream->pipeline_to_append, "pipeline", pipeline)) { - CHANGE_STREAM_ERR ("pipeline"); - } - } - } - - if (stream->err.code == 0) { - (void) _make_cursor (stream); - } -} - -mongoc_change_stream_t * -_mongoc_change_stream_new_from_collection (const mongoc_collection_t *coll, - const bson_t *pipeline, - const bson_t *opts) -{ - mongoc_change_stream_t *stream; - BSON_ASSERT (coll); - - stream = - (mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t)); - bson_strncpy (stream->db, coll->db, sizeof (stream->db)); - bson_strncpy (stream->coll, coll->collection, sizeof (stream->coll)); - stream->read_prefs = mongoc_read_prefs_copy (coll->read_prefs); - stream->read_concern = mongoc_read_concern_copy (coll->read_concern); - stream->client = coll->client; - stream->change_stream_type = MONGOC_CHANGE_STREAM_COLLECTION; - _change_stream_init (stream, pipeline, opts); - return stream; -} - -mongoc_change_stream_t * -_mongoc_change_stream_new_from_database (const mongoc_database_t *db, - const bson_t *pipeline, - const bson_t *opts) -{ - mongoc_change_stream_t *stream; - BSON_ASSERT (db); - - stream = - (mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t)); - bson_strncpy (stream->db, db->name, sizeof (stream->db)); - stream->coll[0] = '\0'; - stream->read_prefs = mongoc_read_prefs_copy (db->read_prefs); - stream->read_concern = mongoc_read_concern_copy (db->read_concern); - stream->client = db->client; - stream->change_stream_type = MONGOC_CHANGE_STREAM_DATABASE; - _change_stream_init (stream, pipeline, opts); - return stream; -} - -mongoc_change_stream_t * -_mongoc_change_stream_new_from_client (mongoc_client_t *client, - const bson_t *pipeline, - const bson_t *opts) -{ - mongoc_change_stream_t *stream; - BSON_ASSERT (client); - - stream = - (mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t)); - bson_strncpy (stream->db, "admin", sizeof (stream->db)); - stream->coll[0] = '\0'; - stream->read_prefs = mongoc_read_prefs_copy (client->read_prefs); - stream->read_concern = mongoc_read_concern_copy (client->read_concern); - stream->client = client; - stream->change_stream_type = MONGOC_CHANGE_STREAM_CLIENT; - _change_stream_init (stream, pipeline, opts); - return stream; -} - - -const bson_t * -mongoc_change_stream_get_resume_token (mongoc_change_stream_t *stream) -{ - if (!bson_empty (&stream->resume_token)) { - return &stream->resume_token; - } - - return NULL; -} - - -bool -mongoc_change_stream_next (mongoc_change_stream_t *stream, const bson_t **bson) -{ - bson_iter_t iter; - bson_t doc_resume_token; - uint32_t len; - const uint8_t *data; - bool ret = false; - - BSON_ASSERT (stream); - BSON_ASSERT (bson); - - if (stream->err.code != 0) { - goto end; - } - - BSON_ASSERT (stream->cursor); - if (!mongoc_cursor_next (stream->cursor, bson)) { - const bson_t *err_doc; - bson_error_t err; - bool resumable = false; - - if (!mongoc_cursor_error_document (stream->cursor, &err, &err_doc)) { - /* no error occurred, just no documents left. */ - goto end; - } - - resumable = _is_resumable_error (err_doc); - while (resumable) { - /* recreate the cursor. */ - mongoc_cursor_destroy (stream->cursor); - stream->cursor = NULL; - stream->resumed = true; - if (!_make_cursor (stream)) { - goto end; - } - if (mongoc_cursor_next (stream->cursor, bson)) { - break; - } - if (!mongoc_cursor_error_document (stream->cursor, &err, &err_doc)) { - goto end; - } - if (err_doc) { - resumable = _is_resumable_error (err_doc); - } else { - resumable = false; - } - } - - if (!resumable) { - stream->err = err; - bson_destroy (&stream->err_doc); - bson_copy_to (err_doc, &stream->err_doc); - goto end; - } - } - - /* we have received documents, either from the first call to next or after a - * resume. */ - stream->has_returned_results = true; - - if (!bson_iter_init_find (&iter, *bson, "_id") || - !BSON_ITER_HOLDS_DOCUMENT (&iter)) { - bson_set_error (&stream->err, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CHANGE_STREAM_NO_RESUME_TOKEN, - "Cannot provide resume functionality when the resume " - "token is missing"); - goto end; - } - - /* copy the resume token. */ - bson_iter_document (&iter, &len, &data); - BSON_ASSERT (bson_init_static (&doc_resume_token, data, len)); - _set_resume_token (stream, &doc_resume_token); - - /* clear out the operation time, since we no longer need it to resume. */ - _mongoc_timestamp_clear (&stream->operation_time); - ret = true; - -end: - /* Change stream spec: Updating the Cached Resume Token */ - if (stream->cursor && !mongoc_cursor_error (stream->cursor, NULL) && - _mongoc_cursor_change_stream_end_of_batch (stream->cursor) && - _mongoc_cursor_change_stream_has_post_batch_resume_token ( - stream->cursor)) { - _set_resume_token ( - stream, - _mongoc_cursor_change_stream_get_post_batch_resume_token ( - stream->cursor)); - } - - - /* Driver Sessions Spec: "When an implicit session is associated with a - * cursor for use with getMore operations, the session MUST be returned to - * the pool immediately following a getMore operation that indicates that the - * cursor has been exhausted." */ - if (stream->implicit_session) { - /* if creating the change stream cursor errored, it may be null. */ - if (!stream->cursor || stream->cursor->cursor_id == 0) { - mongoc_client_session_destroy (stream->implicit_session); - stream->implicit_session = NULL; - } - } - return ret; -} - -bool -mongoc_change_stream_error_document (const mongoc_change_stream_t *stream, - bson_error_t *err, - const bson_t **bson) -{ - BSON_ASSERT (stream); - - if (stream->err.code != 0) { - if (err) { - *err = stream->err; - } - if (bson) { - *bson = &stream->err_doc; - } - return true; - } - - if (bson) { - *bson = NULL; - } - return false; -} - -void -mongoc_change_stream_destroy (mongoc_change_stream_t *stream) -{ - if (!stream) { - return; - } - - bson_destroy (&stream->pipeline_to_append); - bson_destroy (&stream->resume_token); - bson_destroy (stream->full_document); - bson_destroy (&stream->err_doc); - _mongoc_change_stream_opts_cleanup (&stream->opts); - mongoc_cursor_destroy (stream->cursor); - mongoc_client_session_destroy (stream->implicit_session); - mongoc_read_prefs_destroy (stream->read_prefs); - mongoc_read_concern_destroy (stream->read_concern); - - bson_free (stream); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream.h deleted file mode 100644 index b244f3593c99283857639082cd91954b25a761a0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-change-stream.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2017-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CHANGE_STREAM_H -#define MONGOC_CHANGE_STREAM_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -typedef struct _mongoc_change_stream_t mongoc_change_stream_t; - -MONGOC_EXPORT (void) -mongoc_change_stream_destroy (mongoc_change_stream_t *); - -MONGOC_EXPORT (const bson_t *) -mongoc_change_stream_get_resume_token (mongoc_change_stream_t *); - -MONGOC_EXPORT (bool) -mongoc_change_stream_next (mongoc_change_stream_t *, const bson_t **); - -MONGOC_EXPORT (bool) -mongoc_change_stream_error_document (const mongoc_change_stream_t *, - bson_error_t *, - const bson_t **); - -BSON_END_DECLS - -#endif /* MONGOC_CHANGE_STREAM_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool-private.h deleted file mode 100644 index 68cb9f0a11ecc07817030cfe5265da70e50a5e79..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLIENT_POOL_PRIVATE_H -#define MONGOC_CLIENT_POOL_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-client-pool.h" -#include "mongoc/mongoc-topology-description.h" -#include "mongoc/mongoc-topology-private.h" - -BSON_BEGIN_DECLS - -/* for tests */ -void -_mongoc_client_pool_set_stream_initiator (mongoc_client_pool_t *pool, - mongoc_stream_initiator_t si, - void *user_data); -size_t -mongoc_client_pool_get_size (mongoc_client_pool_t *pool); -size_t -mongoc_client_pool_num_pushed (mongoc_client_pool_t *pool); -mongoc_topology_t * -_mongoc_client_pool_get_topology (mongoc_client_pool_t *pool); - -BSON_END_DECLS - - -#endif /* MONGOC_CLIENT_POOL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool.c deleted file mode 100644 index 314c3c98acbdb00e50bac7b4c8e656014fff0f10..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc.h" -#include "mongoc/mongoc-apm-private.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-client-pool-private.h" -#include "mongoc/mongoc-client-pool.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-queue-private.h" -#include "mongoc/mongoc-thread-private.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-trace-private.h" - -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-ssl-private.h" -#endif - -struct _mongoc_client_pool_t { - bson_mutex_t mutex; - mongoc_cond_t cond; - mongoc_queue_t queue; - mongoc_topology_t *topology; - mongoc_uri_t *uri; - uint32_t min_pool_size; - uint32_t max_pool_size; - uint32_t size; -#ifdef MONGOC_ENABLE_SSL - bool ssl_opts_set; - mongoc_ssl_opt_t ssl_opts; -#endif - bool apm_callbacks_set; - mongoc_apm_callbacks_t apm_callbacks; - void *apm_context; - int32_t error_api_version; - bool error_api_set; -}; - - -#ifdef MONGOC_ENABLE_SSL -void -mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool, - const mongoc_ssl_opt_t *opts) -{ - BSON_ASSERT (pool); - - bson_mutex_lock (&pool->mutex); - - _mongoc_ssl_opts_cleanup (&pool->ssl_opts); - - memset (&pool->ssl_opts, 0, sizeof pool->ssl_opts); - pool->ssl_opts_set = false; - - if (opts) { - _mongoc_ssl_opts_copy_to (opts, &pool->ssl_opts); - pool->ssl_opts_set = true; - } - - mongoc_topology_scanner_set_ssl_opts (pool->topology->scanner, - &pool->ssl_opts); - - bson_mutex_unlock (&pool->mutex); -} -#endif - - -mongoc_client_pool_t * -mongoc_client_pool_new (const mongoc_uri_t *uri) -{ - mongoc_topology_t *topology; - mongoc_client_pool_t *pool; - const bson_t *b; - bson_iter_t iter; - const char *appname; - - - ENTRY; - - BSON_ASSERT (uri); - -#ifndef MONGOC_ENABLE_SSL - if (mongoc_uri_get_tls (uri)) { - MONGOC_ERROR ("Can't create SSL client pool," - " SSL not enabled in this build."); - return NULL; - } -#endif - - pool = (mongoc_client_pool_t *) bson_malloc0 (sizeof *pool); - bson_mutex_init (&pool->mutex); - _mongoc_queue_init (&pool->queue); - pool->uri = mongoc_uri_copy (uri); - pool->min_pool_size = 0; - pool->max_pool_size = 100; - pool->size = 0; - - topology = mongoc_topology_new (uri, false); - pool->topology = topology; - pool->error_api_version = MONGOC_ERROR_API_VERSION_LEGACY; - - b = mongoc_uri_get_options (pool->uri); - - if (bson_iter_init_find_case (&iter, b, MONGOC_URI_MINPOOLSIZE)) { - MONGOC_WARNING ( - MONGOC_URI_MINPOOLSIZE - " is deprecated; its behavior does not match its name, and its actual" - " behavior will likely hurt performance."); - - if (BSON_ITER_HOLDS_INT32 (&iter)) { - pool->min_pool_size = BSON_MAX (0, bson_iter_int32 (&iter)); - } - } - - if (bson_iter_init_find_case (&iter, b, MONGOC_URI_MAXPOOLSIZE)) { - if (BSON_ITER_HOLDS_INT32 (&iter)) { - pool->max_pool_size = BSON_MAX (1, bson_iter_int32 (&iter)); - } - } - - appname = - mongoc_uri_get_option_as_utf8 (pool->uri, MONGOC_URI_APPNAME, NULL); - if (appname) { - /* the appname should have already been validated */ - BSON_ASSERT (mongoc_client_pool_set_appname (pool, appname)); - } - -#ifdef MONGOC_ENABLE_SSL - if (mongoc_uri_get_tls (pool->uri)) { - mongoc_ssl_opt_t ssl_opt = {0}; - - _mongoc_ssl_opts_from_uri (&ssl_opt, pool->uri); - /* sets use_ssl = true */ - mongoc_client_pool_set_ssl_opts (pool, &ssl_opt); - } -#endif - mongoc_counter_client_pools_active_inc (); - - RETURN (pool); -} - - -void -mongoc_client_pool_destroy (mongoc_client_pool_t *pool) -{ - mongoc_client_t *client; - - ENTRY; - - if (!pool) { - EXIT; - } - - if (pool->topology->session_pool) { - client = mongoc_client_pool_pop (pool); - _mongoc_client_end_sessions (client); - mongoc_client_pool_push (pool, client); - } - - while ( - (client = (mongoc_client_t *) _mongoc_queue_pop_head (&pool->queue))) { - mongoc_client_destroy (client); - } - - mongoc_topology_destroy (pool->topology); - - mongoc_uri_destroy (pool->uri); - bson_mutex_destroy (&pool->mutex); - mongoc_cond_destroy (&pool->cond); - -#ifdef MONGOC_ENABLE_SSL - _mongoc_ssl_opts_cleanup (&pool->ssl_opts); -#endif - - bson_free (pool); - - mongoc_counter_client_pools_active_dec (); - mongoc_counter_client_pools_disposed_inc (); - - EXIT; -} - - -/* - * Start the background topology scanner. - * - * This function assumes the pool's mutex is locked - */ -static void -_start_scanner_if_needed (mongoc_client_pool_t *pool) -{ - if (!_mongoc_topology_start_background_scanner (pool->topology)) { - MONGOC_ERROR ("Background scanner did not start!"); - abort (); - } -} - -static void -_initialize_new_client (mongoc_client_pool_t *pool, mongoc_client_t *client) -{ - /* for tests */ - mongoc_client_set_stream_initiator ( - client, - pool->topology->scanner->initiator, - pool->topology->scanner->initiator_context); - - client->error_api_version = pool->error_api_version; - _mongoc_client_set_apm_callbacks_private ( - client, &pool->apm_callbacks, pool->apm_context); - -#ifdef MONGOC_ENABLE_SSL - if (pool->ssl_opts_set) { - mongoc_client_set_ssl_opts (client, &pool->ssl_opts); - } -#endif -} - -mongoc_client_t * -mongoc_client_pool_pop (mongoc_client_pool_t *pool) -{ - mongoc_client_t *client; - - ENTRY; - - BSON_ASSERT (pool); - - bson_mutex_lock (&pool->mutex); - -again: - if (!(client = (mongoc_client_t *) _mongoc_queue_pop_head (&pool->queue))) { - if (pool->size < pool->max_pool_size) { - client = _mongoc_client_new_from_uri (pool->topology); - _initialize_new_client (pool, client); - pool->size++; - } else { - mongoc_cond_wait (&pool->cond, &pool->mutex); - GOTO (again); - } - } - - _start_scanner_if_needed (pool); - bson_mutex_unlock (&pool->mutex); - - RETURN (client); -} - - -mongoc_client_t * -mongoc_client_pool_try_pop (mongoc_client_pool_t *pool) -{ - mongoc_client_t *client; - - ENTRY; - - BSON_ASSERT (pool); - - bson_mutex_lock (&pool->mutex); - - if (!(client = (mongoc_client_t *) _mongoc_queue_pop_head (&pool->queue))) { - if (pool->size < pool->max_pool_size) { - client = _mongoc_client_new_from_uri (pool->topology); - _initialize_new_client (pool, client); - pool->size++; - } - } - - if (client) { - _start_scanner_if_needed (pool); - } - bson_mutex_unlock (&pool->mutex); - - RETURN (client); -} - - -void -mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client) -{ - ENTRY; - - BSON_ASSERT (pool); - BSON_ASSERT (client); - - bson_mutex_lock (&pool->mutex); - _mongoc_queue_push_head (&pool->queue, client); - - if (pool->min_pool_size && - _mongoc_queue_get_length (&pool->queue) > pool->min_pool_size) { - mongoc_client_t *old_client; - old_client = (mongoc_client_t *) _mongoc_queue_pop_tail (&pool->queue); - if (old_client) { - mongoc_client_destroy (old_client); - pool->size--; - } - } - - mongoc_cond_signal (&pool->cond); - bson_mutex_unlock (&pool->mutex); - - EXIT; -} - -/* for tests */ -void -_mongoc_client_pool_set_stream_initiator (mongoc_client_pool_t *pool, - mongoc_stream_initiator_t si, - void *context) -{ - mongoc_topology_scanner_set_stream_initiator ( - pool->topology->scanner, si, context); -} - -/* for tests */ -size_t -mongoc_client_pool_get_size (mongoc_client_pool_t *pool) -{ - size_t size = 0; - - ENTRY; - - bson_mutex_lock (&pool->mutex); - size = pool->size; - bson_mutex_unlock (&pool->mutex); - - RETURN (size); -} - - -size_t -mongoc_client_pool_num_pushed (mongoc_client_pool_t *pool) -{ - size_t num_pushed = 0; - - ENTRY; - - bson_mutex_lock (&pool->mutex); - num_pushed = pool->queue.length; - bson_mutex_unlock (&pool->mutex); - - RETURN (num_pushed); -} - - -mongoc_topology_t * -_mongoc_client_pool_get_topology (mongoc_client_pool_t *pool) -{ - return pool->topology; -} - - -void -mongoc_client_pool_max_size (mongoc_client_pool_t *pool, uint32_t max_pool_size) -{ - ENTRY; - - bson_mutex_lock (&pool->mutex); - pool->max_pool_size = max_pool_size; - bson_mutex_unlock (&pool->mutex); - - EXIT; -} - -void -mongoc_client_pool_min_size (mongoc_client_pool_t *pool, uint32_t min_pool_size) -{ - ENTRY; - - MONGOC_WARNING ( - "mongoc_client_pool_min_size is deprecated; its behavior does not match" - " its name, and its actual behavior will likely hurt performance."); - - bson_mutex_lock (&pool->mutex); - pool->min_pool_size = min_pool_size; - bson_mutex_unlock (&pool->mutex); - - EXIT; -} - -bool -mongoc_client_pool_set_apm_callbacks (mongoc_client_pool_t *pool, - mongoc_apm_callbacks_t *callbacks, - void *context) -{ - mongoc_topology_t *topology; - - topology = pool->topology; - - if (pool->apm_callbacks_set) { - MONGOC_ERROR ("Can only set callbacks once"); - return false; - } - - bson_mutex_lock (&topology->mutex); - - if (callbacks) { - memcpy (&topology->description.apm_callbacks, - callbacks, - sizeof (mongoc_apm_callbacks_t)); - memcpy (&pool->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t)); - } - - mongoc_topology_set_apm_callbacks (topology, callbacks, context); - topology->description.apm_context = context; - pool->apm_context = context; - pool->apm_callbacks_set = true; - - bson_mutex_unlock (&topology->mutex); - - return true; -} - -bool -mongoc_client_pool_set_error_api (mongoc_client_pool_t *pool, int32_t version) -{ - if (version != MONGOC_ERROR_API_VERSION_LEGACY && - version != MONGOC_ERROR_API_VERSION_2) { - MONGOC_ERROR ("Unsupported Error API Version: %" PRId32, version); - return false; - } - - if (pool->error_api_set) { - MONGOC_ERROR ("Can only set Error API Version once"); - return false; - } - - pool->error_api_version = version; - pool->error_api_set = true; - - return true; -} - -bool -mongoc_client_pool_set_appname (mongoc_client_pool_t *pool, const char *appname) -{ - bool ret; - - bson_mutex_lock (&pool->mutex); - ret = _mongoc_topology_set_appname (pool->topology, appname); - bson_mutex_unlock (&pool->mutex); - - return ret; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool.h deleted file mode 100644 index 0746950caf9c8806eb10e22a0125c89f1e94ae87..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-pool.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLIENT_POOL_H -#define MONGOC_CLIENT_POOL_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-apm.h" -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-config.h" -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-ssl.h" -#endif -#include "mongoc/mongoc-uri.h" - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_client_pool_t mongoc_client_pool_t; - - -MONGOC_EXPORT (mongoc_client_pool_t *) -mongoc_client_pool_new (const mongoc_uri_t *uri); -MONGOC_EXPORT (void) -mongoc_client_pool_destroy (mongoc_client_pool_t *pool); -MONGOC_EXPORT (mongoc_client_t *) -mongoc_client_pool_pop (mongoc_client_pool_t *pool); -MONGOC_EXPORT (void) -mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client); -MONGOC_EXPORT (mongoc_client_t *) -mongoc_client_pool_try_pop (mongoc_client_pool_t *pool); -MONGOC_EXPORT (void) -mongoc_client_pool_max_size (mongoc_client_pool_t *pool, - uint32_t max_pool_size); -MONGOC_EXPORT (void) -mongoc_client_pool_min_size (mongoc_client_pool_t *pool, - uint32_t min_pool_size) BSON_GNUC_DEPRECATED; -#ifdef MONGOC_ENABLE_SSL -MONGOC_EXPORT (void) -mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool, - const mongoc_ssl_opt_t *opts); -#endif -MONGOC_EXPORT (bool) -mongoc_client_pool_set_apm_callbacks (mongoc_client_pool_t *pool, - mongoc_apm_callbacks_t *callbacks, - void *context); -MONGOC_EXPORT (bool) -mongoc_client_pool_set_error_api (mongoc_client_pool_t *pool, int32_t version); -MONGOC_EXPORT (bool) -mongoc_client_pool_set_appname (mongoc_client_pool_t *pool, - const char *appname); -BSON_END_DECLS - - -#endif /* MONGOC_CLIENT_POOL_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-private.h deleted file mode 100644 index 4db06e27d4e0e1e9e72ff1c4ff9f465ae404d33a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-private.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLIENT_PRIVATE_H -#define MONGOC_CLIENT_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-apm-private.h" -#include "mongoc/mongoc-buffer-private.h" -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-host-list.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-opcode.h" -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-ssl.h" -#endif -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-write-concern.h" - -#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION -#include <mongocrypt/mongocrypt.h> -#endif - -BSON_BEGIN_DECLS - -/* protocol versions this driver can speak */ -#define WIRE_VERSION_MIN 3 -#define WIRE_VERSION_MAX 8 - -/* first version that supported "find" and "getMore" commands */ -#define WIRE_VERSION_FIND_CMD 4 -/* first version with "killCursors" command */ -#define WIRE_VERSION_KILLCURSORS_CMD 4 -/* first version when findAndModify accepts writeConcern */ -#define WIRE_VERSION_FAM_WRITE_CONCERN 4 -/* first version to support readConcern */ -#define WIRE_VERSION_READ_CONCERN 4 -/* first version to support maxStalenessSeconds */ -#define WIRE_VERSION_MAX_STALENESS 5 -/* first version to support writeConcern */ -#define WIRE_VERSION_CMD_WRITE_CONCERN 5 -/* first version to support collation */ -#define WIRE_VERSION_COLLATION 5 -/* first version to support OP_MSG */ -#define WIRE_VERSION_OP_MSG 6 -/* first version to support array filters for "update" command */ -#define WIRE_VERSION_ARRAY_FILTERS 6 -/* first version to support retryable reads */ -#define WIRE_VERSION_RETRY_READS 6 -/* first version to support retryable writes */ -#define WIRE_VERSION_RETRY_WRITES 6 -/* version corresponding to server 4.0 release */ -#define WIRE_VERSION_4_0 7 -/* version corresponding to server 4.2 release */ -#define WIRE_VERSION_4_2 8 -/* version corresponding to client side field level encryption support. */ -#define WIRE_VERSION_CSE 8 - -struct _mongoc_collection_t; - -struct _mongoc_client_t { - mongoc_uri_t *uri; - mongoc_cluster_t cluster; - bool in_exhaust; - - mongoc_stream_initiator_t initiator; - void *initiator_data; - -#ifdef MONGOC_ENABLE_SSL - bool use_ssl; - mongoc_ssl_opt_t ssl_opts; -#endif - - mongoc_topology_t *topology; - - mongoc_read_prefs_t *read_prefs; - mongoc_read_concern_t *read_concern; - mongoc_write_concern_t *write_concern; - - mongoc_apm_callbacks_t apm_callbacks; - void *apm_context; - - int32_t error_api_version; - bool error_api_set; - - /* mongoc_client_session_t's in use, to look up lsids and clusterTimes */ - mongoc_set_t *client_sessions; - unsigned int csid_rand_seed; - - uint32_t generation; - - /* Is client side encryption enabled? */ - bool cse_enabled; - -#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION - mongocrypt_t *crypt; - mongoc_client_t *mongocryptd_client; - struct _mongoc_collection_t *key_vault_coll; - bool bypass_auto_encryption; -#endif -}; - -/* Defines whether _mongoc_client_command_with_opts() is acting as a read - * command helper for a command like "distinct", or a write command helper for - * a command like "createRole", or both, like "aggregate" with "$out". - */ -typedef enum { - MONGOC_CMD_RAW = 0, - MONGOC_CMD_READ = 1, - MONGOC_CMD_WRITE = 2, - MONGOC_CMD_RW = 3, -} mongoc_command_mode_t; - -BSON_STATIC_ASSERT2 (mongoc_cmd_rw, - MONGOC_CMD_RW == (MONGOC_CMD_READ | MONGOC_CMD_WRITE)); - -typedef enum { MONGOC_RR_SRV, MONGOC_RR_TXT } mongoc_rr_type_t; - -typedef struct _mongoc_rr_data_t { - /* Number of records returned by DNS. */ - uint32_t count; - - /* Set to lowest TTL found when polling SRV records. */ - uint32_t min_ttl; - - /* Initialized with copy of uri->hosts prior to polling. - * Any remaining records after DNS query are no longer active. - */ - mongoc_host_list_t *hosts; -} mongoc_rr_data_t; - -bool -_mongoc_client_get_rr (const char *service, - mongoc_rr_type_t rr_type, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error); - -mongoc_client_t * -_mongoc_client_new_from_uri (mongoc_topology_t *topology); - -bool -_mongoc_client_set_apm_callbacks_private (mongoc_client_t *client, - mongoc_apm_callbacks_t *callbacks, - void *context); - -mongoc_stream_t * -mongoc_client_default_stream_initiator (const mongoc_uri_t *uri, - const mongoc_host_list_t *host, - void *user_data, - bson_error_t *error); - -mongoc_stream_t * -_mongoc_client_create_stream (mongoc_client_t *client, - const mongoc_host_list_t *host, - bson_error_t *error); - -bool -_mongoc_client_recv (mongoc_client_t *client, - mongoc_rpc_t *rpc, - mongoc_buffer_t *buffer, - mongoc_server_stream_t *server_stream, - bson_error_t *error); - -void -_mongoc_client_kill_cursor (mongoc_client_t *client, - uint32_t server_id, - int64_t cursor_id, - int64_t operation_id, - const char *db, - const char *collection, - mongoc_client_session_t *cs); -bool -_mongoc_client_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - mongoc_command_mode_t mode, - const bson_t *opts, - mongoc_query_flags_t flags, - const mongoc_read_prefs_t *user_prefs, - const mongoc_read_prefs_t *default_prefs, - mongoc_read_concern_t *default_rc, - mongoc_write_concern_t *default_wc, - bson_t *reply, - bson_error_t *error); - -mongoc_server_session_t * -_mongoc_client_pop_server_session (mongoc_client_t *client, - bson_error_t *error); - -bool -_mongoc_client_lookup_session (const mongoc_client_t *client, - uint32_t client_session_id, - mongoc_client_session_t **cs, - bson_error_t *error); - -void -_mongoc_client_unregister_session (mongoc_client_t *client, - mongoc_client_session_t *session); - -void -_mongoc_client_push_server_session (mongoc_client_t *client, - mongoc_server_session_t *server_session); -void -_mongoc_client_end_sessions (mongoc_client_t *client); - -mongoc_stream_t * -mongoc_client_connect_tcp (int32_t connecttimeoutms, - const mongoc_host_list_t *host, - bson_error_t *error); -BSON_END_DECLS - -#endif /* MONGOC_CLIENT_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session-private.h deleted file mode 100644 index 140864bae2911cfd91d64c4c2e108c387b0b1f58..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session-private.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLIENT_SESSION_PRIVATE_H -#define MONGOC_CLIENT_SESSION_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-client-session.h" - -/* error labels: see Transactions Spec */ -#define TRANSIENT_TXN_ERR "TransientTransactionError" -#define UNKNOWN_COMMIT_RESULT "UnknownTransactionCommitResult" -#define MAX_TIME_MS_EXPIRED "MaxTimeMSExpired" -#define DEFAULT_MAX_COMMIT_TIME_MS 0 - -#define MONGOC_DEFAULT_WTIMEOUT_FOR_COMMIT_RETRY 10000 - -struct _mongoc_transaction_opt_t { - mongoc_read_concern_t *read_concern; - mongoc_write_concern_t *write_concern; - mongoc_read_prefs_t *read_prefs; - int64_t max_commit_time_ms; -}; - -typedef enum { - MONGOC_SESSION_NO_OPTS = 0, - MONGOC_SESSION_CAUSAL_CONSISTENCY = (1 << 0), -} mongoc_session_flag_t; - -struct _mongoc_session_opt_t { - mongoc_session_flag_t flags; - mongoc_transaction_opt_t default_txn_opts; -}; - -typedef struct _mongoc_server_session_t { - struct _mongoc_server_session_t *prev, *next; - int64_t last_used_usec; - bson_t lsid; /* logical session id */ - int64_t txn_number; /* transaction number */ -} mongoc_server_session_t; - -typedef enum { - MONGOC_INTERNAL_TRANSACTION_NONE, - MONGOC_INTERNAL_TRANSACTION_STARTING, - MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS, - MONGOC_INTERNAL_TRANSACTION_ENDING, - MONGOC_INTERNAL_TRANSACTION_COMMITTED, - MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY, - MONGOC_INTERNAL_TRANSACTION_ABORTED, -} mongoc_internal_transaction_state_t; - -typedef struct _mongoc_transaction_t { - mongoc_internal_transaction_state_t state; - mongoc_transaction_opt_t opts; -} mongoc_transaction_t; - -struct _mongoc_client_session_t { - mongoc_client_t *client; - mongoc_session_opt_t opts; - mongoc_server_session_t *server_session; - mongoc_transaction_t txn; - uint32_t client_session_id; - bson_t cluster_time; - uint32_t operation_timestamp; - uint32_t operation_increment; - uint32_t client_generation; - uint32_t server_id; - bson_t *recovery_token; - - /* For testing only */ - int64_t with_txn_timeout_ms; - const char *fail_commit_label; -}; - -bool -_mongoc_parse_cluster_time (const bson_t *cluster_time, - uint32_t *timestamp, - uint32_t *increment); - -bool -_mongoc_cluster_time_greater (const bson_t *new, const bson_t *old); - -void -_mongoc_client_session_handle_reply (mongoc_client_session_t *session, - bool is_acknowledged, - const bson_t *reply); - -mongoc_server_session_t * -_mongoc_server_session_new (bson_error_t *error); - -bool -_mongoc_server_session_timed_out (const mongoc_server_session_t *server_session, - int64_t session_timeout_minutes); - -void -_mongoc_server_session_destroy (mongoc_server_session_t *server_session); - -mongoc_client_session_t * -_mongoc_client_session_new (mongoc_client_t *client, - mongoc_server_session_t *server_session, - const mongoc_session_opt_t *opts, - uint32_t client_session_id); - -bool -_mongoc_client_session_from_iter (mongoc_client_t *client, - const bson_iter_t *iter, - mongoc_client_session_t **cs, - bson_error_t *error); - -bool -_mongoc_client_session_in_txn (const mongoc_client_session_t *session); - -bool -_mongoc_client_session_in_txn_or_ending ( - const mongoc_client_session_t *session); - -bool -_mongoc_client_session_txn_in_progress (const mongoc_client_session_t *session); - -bool -_mongoc_client_session_append_txn (mongoc_client_session_t *session, - bson_t *cmd, - bson_error_t *error); - -void -_mongoc_client_session_append_read_concern (const mongoc_client_session_t *cs, - const bson_t *user_read_concern, - bool is_read_command, - bson_t *cmd); - -void -_mongoc_client_session_unpin (mongoc_client_session_t *session); - -void -_mongoc_client_session_pin (mongoc_client_session_t *session, - uint32_t server_id); - - -#endif /* MONGOC_CLIENT_SESSION_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session.c deleted file mode 100644 index 6169550900239619b1a6b8b6d12d993018337f06..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session.c +++ /dev/null @@ -1,1646 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-client-session-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-rand-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-read-prefs-private.h" - -#define SESSION_NEVER_USED (-1) - -#define WITH_TXN_TIMEOUT_MS (120 * 1000) - -static void -txn_opts_set (mongoc_transaction_opt_t *opts, - const mongoc_read_concern_t *read_concern, - const mongoc_write_concern_t *write_concern, - const mongoc_read_prefs_t *read_prefs, - int64_t max_commit_time_ms) -{ - if (read_concern) { - mongoc_transaction_opts_set_read_concern (opts, read_concern); - } - - if (write_concern) { - mongoc_transaction_opts_set_write_concern (opts, write_concern); - } - - if (read_prefs) { - mongoc_transaction_opts_set_read_prefs (opts, read_prefs); - } - - if (max_commit_time_ms != DEFAULT_MAX_COMMIT_TIME_MS) { - mongoc_transaction_opts_set_max_commit_time_ms (opts, max_commit_time_ms); - } -} - - -static void -txn_opts_cleanup (mongoc_transaction_opt_t *opts) -{ - /* null inputs are ok */ - mongoc_read_concern_destroy (opts->read_concern); - mongoc_write_concern_destroy (opts->write_concern); - mongoc_read_prefs_destroy (opts->read_prefs); - /* prepare opts for reuse */ - opts->read_concern = NULL; - opts->write_concern = NULL; - opts->read_prefs = NULL; - opts->max_commit_time_ms = DEFAULT_MAX_COMMIT_TIME_MS; -} - - -static void -txn_opts_copy (const mongoc_transaction_opt_t *src, - mongoc_transaction_opt_t *dst) -{ - txn_opts_cleanup (dst); - /* null inputs are ok for these copy functions */ - dst->read_concern = mongoc_read_concern_copy (src->read_concern); - dst->write_concern = mongoc_write_concern_copy (src->write_concern); - dst->read_prefs = mongoc_read_prefs_copy (src->read_prefs); - dst->max_commit_time_ms = src->max_commit_time_ms; -} - - -static void -copy_labels_plus_unknown_commit_result (const bson_t *src, bson_t *dst) -{ - bson_iter_t iter; - bson_iter_t src_label; - bson_t dst_labels; - char str[16]; - uint32_t i = 0; - const char *key; - - BSON_APPEND_ARRAY_BEGIN (dst, "errorLabels", &dst_labels); - BSON_APPEND_UTF8 (&dst_labels, "0", UNKNOWN_COMMIT_RESULT); - - /* append any other errorLabels already in "src" */ - if (bson_iter_init_find (&iter, src, "errorLabels") && - bson_iter_recurse (&iter, &src_label)) { - while (bson_iter_next (&src_label) && BSON_ITER_HOLDS_UTF8 (&src_label)) { - if (strcmp (bson_iter_utf8 (&src_label, NULL), - UNKNOWN_COMMIT_RESULT) != 0) { - i++; - bson_uint32_to_string (i, &key, str, sizeof str); - BSON_APPEND_UTF8 ( - &dst_labels, key, bson_iter_utf8 (&src_label, NULL)); - } - } - } - - bson_append_array_end (dst, &dst_labels); -} - - -static bool -txn_abort (mongoc_client_session_t *session, bson_t *reply, bson_error_t *error) -{ - bson_t cmd = BSON_INITIALIZER; - bson_t opts = BSON_INITIALIZER; - bson_error_t err_local; - bson_error_t *err_ptr = error ? error : &err_local; - bson_t reply_local = BSON_INITIALIZER; - mongoc_write_err_type_t error_type; - bool r = false; - - _mongoc_bson_init_if_set (reply); - - if (!mongoc_client_session_append (session, &opts, err_ptr)) { - GOTO (done); - } - - if (session->txn.opts.write_concern) { - if (!mongoc_write_concern_append (session->txn.opts.write_concern, - &opts)) { - bson_set_error (err_ptr, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Invalid transaction write concern"); - GOTO (done); - } - } - - BSON_APPEND_INT32 (&cmd, "abortTransaction", 1); - if (session->recovery_token) { - BSON_APPEND_DOCUMENT (&cmd, "recoveryToken", session->recovery_token); - } - - /* will be reinitialized by mongoc_client_write_command_with_opts */ - bson_destroy (&reply_local); - r = mongoc_client_write_command_with_opts ( - session->client, "admin", &cmd, &opts, &reply_local, err_ptr); - - /* Transactions Spec: "Drivers MUST retry the commitTransaction command once - * after it fails with a retryable error", same for abort */ - error_type = _mongoc_write_error_get_type (r, err_ptr, &reply_local); - if (error_type == MONGOC_WRITE_ERR_RETRY) { - _mongoc_client_session_unpin (session); - bson_destroy (&reply_local); - r = mongoc_client_write_command_with_opts ( - session->client, "admin", &cmd, &opts, &reply_local, err_ptr); - } - - if (!r) { - /* we won't return an error from abortTransaction, so warn */ - MONGOC_WARNING ("Error in abortTransaction: %s", err_ptr->message); - _mongoc_client_session_unpin (session); - } - -done: - bson_destroy (&reply_local); - bson_destroy (&cmd); - bson_destroy (&opts); - - return r; -} - - -static mongoc_write_concern_t * -create_commit_retry_wc (const mongoc_write_concern_t *existing_wc) -{ - mongoc_write_concern_t *wc; - - wc = existing_wc ? mongoc_write_concern_copy (existing_wc) - : mongoc_write_concern_new (); - - /* Transactions spec: "If the modified write concern does not include a - * wtimeout value, drivers MUST also apply wtimeout: 10000 to the write - * concern in order to avoid waiting forever if the majority write concern - * cannot be satisfied." */ - if (mongoc_write_concern_get_wtimeout_int64 (wc) <= 0) { - mongoc_write_concern_set_wtimeout_int64 ( - wc, MONGOC_DEFAULT_WTIMEOUT_FOR_COMMIT_RETRY); - } - - /* Transactions spec: "If the transaction is using a write concern that is - * not the server default, any other write concern options MUST be left as-is - * when applying w:majority. */ - mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_MAJORITY); - - return wc; -} - - -static bool -txn_commit (mongoc_client_session_t *session, - bool explicitly_retrying, - bson_t *reply, - bson_error_t *error) -{ - bson_t cmd = BSON_INITIALIZER; - bson_t opts = BSON_INITIALIZER; - bson_error_t err_local = {0}; - bson_error_t *err_ptr = error ? error : &err_local; - bson_t reply_local = BSON_INITIALIZER; - mongoc_write_err_type_t error_type; - bool r = false; - bool retrying_after_error = false; - mongoc_write_concern_t *retry_wc = NULL; - - _mongoc_bson_init_if_set (reply); - - BSON_APPEND_INT32 (&cmd, "commitTransaction", 1); - if (session->recovery_token) { - BSON_APPEND_DOCUMENT (&cmd, "recoveryToken", session->recovery_token); - } - -retry: - if (!mongoc_client_session_append (session, &opts, err_ptr)) { - GOTO (done); - } - - if (session->txn.opts.max_commit_time_ms != DEFAULT_MAX_COMMIT_TIME_MS) { - if (!bson_append_int64 ( - &opts, "maxTimeMS", -1, session->txn.opts.max_commit_time_ms)) { - bson_set_error (err_ptr, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "error appending maxCommitTimeMS"); - GOTO (done); - } - } - - /* Transactions Spec: "When commitTransaction is retried, either by the - * driver's internal retry-once logic or explicitly by the user calling - * commitTransaction again, drivers MUST apply w:majority to the write - * concern of the commitTransaction command." */ - if (!retry_wc && (retrying_after_error || explicitly_retrying)) { - retry_wc = create_commit_retry_wc (session->txn.opts.write_concern - ? session->txn.opts.write_concern - : session->client->write_concern); - } - - if (retry_wc || session->txn.opts.write_concern) { - if (!mongoc_write_concern_append ( - retry_wc ? retry_wc : session->txn.opts.write_concern, &opts)) { - bson_set_error (err_ptr, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Invalid transaction write concern"); - GOTO (done); - } - } - - /* will be reinitialized by mongoc_client_write_command_with_opts */ - bson_destroy (&reply_local); - r = mongoc_client_write_command_with_opts ( - session->client, "admin", &cmd, &opts, &reply_local, err_ptr); - - /* Transactions Spec: "Drivers MUST retry the commitTransaction command once - * after it fails with a retryable error", same for abort */ - error_type = _mongoc_write_error_get_type (r, err_ptr, &reply_local); - if (!retrying_after_error && error_type == MONGOC_WRITE_ERR_RETRY) { - retrying_after_error = true; /* retry after error only once */ - _mongoc_client_session_unpin (session); - bson_reinit (&opts); - GOTO (retry); - } - - /* Transactions Spec: "add the UnknownTransactionCommitResult error label - * when commitTransaction fails with a network error, server selection - * error, MaxTimeMSExpired error, or write concern failed / timeout." */ - if (!r && (err_ptr->domain == MONGOC_ERROR_SERVER_SELECTION || - error_type == MONGOC_WRITE_ERR_RETRY || - error_type == MONGOC_WRITE_ERR_WRITE_CONCERN || - err_ptr->code == MONGOC_ERROR_MAX_TIME_MS_EXPIRED)) { - /* Drivers MUST unpin a ClientSession when any individual - * commitTransaction command attempt fails with an - * UnknownTransactionCommitResult error label. Do this even if we won't - * actually apply the error label due to reply being NULL */ - _mongoc_client_session_unpin (session); - if (reply) { - bson_copy_to_excluding_noinit ( - &reply_local, reply, "errorLabels", NULL); - copy_labels_plus_unknown_commit_result (&reply_local, reply); - } - } else if (reply) { - /* maintain invariants: reply & reply_local are valid until the end */ - bson_destroy (reply); - bson_steal (reply, &reply_local); - bson_init (&reply_local); - } - -done: - bson_destroy (&reply_local); - bson_destroy (&cmd); - bson_destroy (&opts); - - if (retry_wc) { - mongoc_write_concern_destroy (retry_wc); - } - - return r; -} - - -mongoc_transaction_opt_t * -mongoc_transaction_opts_new (void) -{ - mongoc_transaction_opt_t *opts; - opts = (mongoc_transaction_opt_t *) bson_malloc0 ( - sizeof (mongoc_transaction_opt_t)); - opts->max_commit_time_ms = DEFAULT_MAX_COMMIT_TIME_MS; - - return opts; -} - - -mongoc_transaction_opt_t * -mongoc_transaction_opts_clone (const mongoc_transaction_opt_t *opts) -{ - mongoc_transaction_opt_t *cloned_opts; - - ENTRY; - - BSON_ASSERT (opts); - - cloned_opts = mongoc_transaction_opts_new (); - txn_opts_copy (opts, cloned_opts); - - RETURN (cloned_opts); -} - - -void -mongoc_transaction_opts_destroy (mongoc_transaction_opt_t *opts) -{ - ENTRY; - - if (!opts) { - EXIT; - } - - txn_opts_cleanup (opts); - bson_free (opts); - - EXIT; -} - - -void -mongoc_transaction_opts_set_max_commit_time_ms (mongoc_transaction_opt_t *opts, - int64_t max_commit_time_ms) -{ - BSON_ASSERT (opts); - opts->max_commit_time_ms = max_commit_time_ms; -} - - -int64_t -mongoc_transaction_opts_get_max_commit_time_ms (mongoc_transaction_opt_t *opts) -{ - BSON_ASSERT (opts); - return opts->max_commit_time_ms; -} - - -void -mongoc_transaction_opts_set_read_concern ( - mongoc_transaction_opt_t *opts, const mongoc_read_concern_t *read_concern) -{ - BSON_ASSERT (opts); - mongoc_read_concern_destroy (opts->read_concern); - opts->read_concern = mongoc_read_concern_copy (read_concern); -} - - -const mongoc_read_concern_t * -mongoc_transaction_opts_get_read_concern (const mongoc_transaction_opt_t *opts) -{ - BSON_ASSERT (opts); - return opts->read_concern; -} - - -void -mongoc_transaction_opts_set_write_concern ( - mongoc_transaction_opt_t *opts, const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (opts); - mongoc_write_concern_destroy (opts->write_concern); - opts->write_concern = mongoc_write_concern_copy (write_concern); -} - - -const mongoc_write_concern_t * -mongoc_transaction_opts_get_write_concern (const mongoc_transaction_opt_t *opts) -{ - BSON_ASSERT (opts); - return opts->write_concern; -} - - -void -mongoc_transaction_opts_set_read_prefs (mongoc_transaction_opt_t *opts, - const mongoc_read_prefs_t *read_prefs) -{ - BSON_ASSERT (opts); - mongoc_read_prefs_destroy (opts->read_prefs); - opts->read_prefs = mongoc_read_prefs_copy (read_prefs); -} - - -const mongoc_read_prefs_t * -mongoc_transaction_opts_get_read_prefs (const mongoc_transaction_opt_t *opts) -{ - BSON_ASSERT (opts); - return opts->read_prefs; -} - - -mongoc_session_opt_t * -mongoc_session_opts_new (void) -{ - mongoc_session_opt_t *opts = bson_malloc0 (sizeof (mongoc_session_opt_t)); - - /* Driver Sessions Spec: causal consistency is true by default */ - mongoc_session_opts_set_causal_consistency (opts, true); - - return opts; -} - - -void -mongoc_session_opts_set_causal_consistency (mongoc_session_opt_t *opts, - bool causal_consistency) -{ - ENTRY; - - BSON_ASSERT (opts); - - if (causal_consistency) { - opts->flags |= MONGOC_SESSION_CAUSAL_CONSISTENCY; - } else { - opts->flags &= ~MONGOC_SESSION_CAUSAL_CONSISTENCY; - } - - EXIT; -} - -bool -mongoc_session_opts_get_causal_consistency (const mongoc_session_opt_t *opts) -{ - ENTRY; - - BSON_ASSERT (opts); - - RETURN (!!(opts->flags & MONGOC_SESSION_CAUSAL_CONSISTENCY)); -} - - -void -mongoc_session_opts_set_default_transaction_opts ( - mongoc_session_opt_t *opts, const mongoc_transaction_opt_t *txn_opts) -{ - ENTRY; - - BSON_ASSERT (opts); - BSON_ASSERT (txn_opts); - - txn_opts_set (&opts->default_txn_opts, - txn_opts->read_concern, - txn_opts->write_concern, - txn_opts->read_prefs, - txn_opts->max_commit_time_ms); - - EXIT; -} - - -const mongoc_transaction_opt_t * -mongoc_session_opts_get_default_transaction_opts ( - const mongoc_session_opt_t *opts) -{ - ENTRY; - - BSON_ASSERT (opts); - - RETURN (&opts->default_txn_opts); -} - - -mongoc_transaction_opt_t * -mongoc_session_opts_get_transaction_opts ( - const mongoc_client_session_t *session) -{ - ENTRY; - - BSON_ASSERT (session); - - if (mongoc_client_session_in_transaction (session)) { - RETURN (mongoc_transaction_opts_clone (&session->txn.opts)); - } - - RETURN (NULL); -} - -static void -_mongoc_session_opts_copy (const mongoc_session_opt_t *src, - mongoc_session_opt_t *dst) -{ - dst->flags = src->flags; - txn_opts_copy (&src->default_txn_opts, &dst->default_txn_opts); -} - - -mongoc_session_opt_t * -mongoc_session_opts_clone (const mongoc_session_opt_t *opts) -{ - mongoc_session_opt_t *cloned_opts; - - ENTRY; - - BSON_ASSERT (opts); - - cloned_opts = bson_malloc0 (sizeof (mongoc_session_opt_t)); - _mongoc_session_opts_copy (opts, cloned_opts); - - RETURN (cloned_opts); -} - - -void -mongoc_session_opts_destroy (mongoc_session_opt_t *opts) -{ - ENTRY; - - if (!opts) { - EXIT; - } - - txn_opts_cleanup (&opts->default_txn_opts); - bson_free (opts); - - EXIT; -} - - -static bool -_mongoc_server_session_uuid (uint8_t *data /* OUT */, bson_error_t *error) -{ -#ifdef MONGOC_ENABLE_CRYPTO - /* https://tools.ietf.org/html/rfc4122#page-14 - * o Set the two most significant bits (bits 6 and 7) of the - * clock_seq_hi_and_reserved to zero and one, respectively. - * - * o Set the four most significant bits (bits 12 through 15) of the - * time_hi_and_version field to the 4-bit version number from - * Section 4.1.3. - * - * o Set all the other bits to randomly (or pseudo-randomly) chosen - * values. - */ - - if (!_mongoc_rand_bytes (data, 16)) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_SESSION_FAILURE, - "Could not generate UUID for logical session id"); - - return false; - } - - data[6] = (uint8_t) (0x40 | (data[6] & 0xf)); - data[8] = (uint8_t) (0x80 | (data[8] & 0x3f)); - - return true; -#else - /* no _mongoc_rand_bytes without a crypto library */ - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_SESSION_FAILURE, - "Could not generate UUID for logical session id, we need a" - " cryptography library like libcrypto, Common Crypto, or" - " CNG"); - - return false; -#endif -} - - -bool -_mongoc_parse_cluster_time (const bson_t *cluster_time, - uint32_t *timestamp, - uint32_t *increment) -{ - bson_iter_t iter; - char *s; - - if (!cluster_time || - !bson_iter_init_find (&iter, cluster_time, "clusterTime") || - !BSON_ITER_HOLDS_TIMESTAMP (&iter)) { - s = bson_as_json (cluster_time, NULL); - MONGOC_ERROR ("Cannot parse cluster time from %s\n", s); - bson_free (s); - return false; - } - - bson_iter_timestamp (&iter, timestamp, increment); - - return true; -} - - -bool -_mongoc_cluster_time_greater (const bson_t *new, const bson_t *old) -{ - uint32_t new_t, new_i, old_t, old_i; - - if (!_mongoc_parse_cluster_time (new, &new_t, &new_i) || - !_mongoc_parse_cluster_time (old, &old_t, &old_i)) { - return false; - } - - return (new_t > old_t) || (new_t == old_t && new_i > old_i); -} - - -void -_mongoc_client_session_handle_reply (mongoc_client_session_t *session, - bool is_acknowledged, - const bson_t *reply) -{ - bson_iter_t iter; - uint32_t len; - const uint8_t *data; - bson_t cluster_time; - uint32_t t; - uint32_t i; - - BSON_ASSERT (session); - - if (!reply || !bson_iter_init (&iter, reply)) { - return; - } - - if (mongoc_error_has_label (reply, "TransientTransactionError")) { - /* Transaction Spec: "Drivers MUST unpin a ClientSession when a command - * within a transaction, including commitTransaction and abortTransaction, - * fails with a TransientTransactionError". If the server reply included - * a TransientTransactionError, we unpin here. If a network error caused - * us to add a label client-side, we unpin in network_error_reply. */ - session->server_id = 0; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "$clusterTime") && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - bson_iter_document (&iter, &len, &data); - BSON_ASSERT (bson_init_static (&cluster_time, data, (size_t) len)); - - mongoc_client_session_advance_cluster_time (session, &cluster_time); - } else if (!strcmp (bson_iter_key (&iter), "operationTime") && - BSON_ITER_HOLDS_TIMESTAMP (&iter) && is_acknowledged) { - bson_iter_timestamp (&iter, &t, &i); - mongoc_client_session_advance_operation_time (session, t, i); - } - } -} - - -mongoc_server_session_t * -_mongoc_server_session_new (bson_error_t *error) -{ - uint8_t uuid_data[16]; - mongoc_server_session_t *s; - - ENTRY; - - if (!_mongoc_server_session_uuid (uuid_data, error)) { - RETURN (NULL); - } - - s = bson_malloc0 (sizeof (mongoc_server_session_t)); - s->last_used_usec = SESSION_NEVER_USED; - s->prev = NULL; - s->next = NULL; - bson_init (&s->lsid); - bson_append_binary ( - &s->lsid, "id", 2, BSON_SUBTYPE_UUID, uuid_data, sizeof uuid_data); - - /* transaction number is a positive integer and will be incremented before - * each use, so ensure it is initialized to zero. */ - s->txn_number = 0; - - RETURN (s); -} - - -bool -_mongoc_server_session_timed_out (const mongoc_server_session_t *server_session, - int64_t session_timeout_minutes) -{ - int64_t timeout_usec; - const int64_t minute_to_usec = 60 * 1000 * 1000; - - ENTRY; - - if (session_timeout_minutes == MONGOC_NO_SESSIONS) { - /* not connected right now; keep the session */ - return false; - } - - if (server_session->last_used_usec == SESSION_NEVER_USED) { - return false; - } - - /* Driver Sessions Spec: if a session has less than one minute left before - * becoming stale, discard it */ - timeout_usec = - server_session->last_used_usec + session_timeout_minutes * minute_to_usec; - - RETURN (timeout_usec - bson_get_monotonic_time () < 1 * minute_to_usec); -} - - -void -_mongoc_server_session_destroy (mongoc_server_session_t *server_session) -{ - ENTRY; - - bson_destroy (&server_session->lsid); - bson_free (server_session); - - EXIT; -} - - -mongoc_client_session_t * -_mongoc_client_session_new (mongoc_client_t *client, - mongoc_server_session_t *server_session, - const mongoc_session_opt_t *opts, - uint32_t client_session_id) -{ - mongoc_client_session_t *session; - - ENTRY; - - BSON_ASSERT (client); - - session = bson_malloc0 (sizeof (mongoc_client_session_t)); - session->client = client; - session->client_generation = client->generation; - session->server_session = server_session; - session->client_session_id = client_session_id; - bson_init (&session->cluster_time); - - txn_opts_set (&session->opts.default_txn_opts, - client->read_concern, - client->write_concern, - client->read_prefs, - DEFAULT_MAX_COMMIT_TIME_MS); - - if (opts) { - session->opts.flags = opts->flags; - txn_opts_set (&session->opts.default_txn_opts, - opts->default_txn_opts.read_concern, - opts->default_txn_opts.write_concern, - opts->default_txn_opts.read_prefs, - opts->default_txn_opts.max_commit_time_ms); - } else { - /* sessions are causally consistent by default */ - session->opts.flags = MONGOC_SESSION_CAUSAL_CONSISTENCY; - } - - /* these values are used for testing only. */ - session->with_txn_timeout_ms = 0; - session->fail_commit_label = NULL; - - RETURN (session); -} - - -mongoc_client_t * -mongoc_client_session_get_client (const mongoc_client_session_t *session) -{ - BSON_ASSERT (session); - - return session->client; -} - - -const mongoc_session_opt_t * -mongoc_client_session_get_opts (const mongoc_client_session_t *session) -{ - BSON_ASSERT (session); - - return &session->opts; -} - - -const bson_t * -mongoc_client_session_get_lsid (const mongoc_client_session_t *session) -{ - BSON_ASSERT (session); - - return &session->server_session->lsid; -} - -const bson_t * -mongoc_client_session_get_cluster_time (const mongoc_client_session_t *session) -{ - BSON_ASSERT (session); - - if (bson_empty (&session->cluster_time)) { - return NULL; - } - - return &session->cluster_time; -} - -uint32_t -mongoc_client_session_get_server_id (const mongoc_client_session_t *session) -{ - BSON_ASSERT (session); - - return session->server_id; -} - -void -mongoc_client_session_advance_cluster_time (mongoc_client_session_t *session, - const bson_t *cluster_time) -{ - uint32_t t, i; - - ENTRY; - - if (bson_empty (&session->cluster_time) && - _mongoc_parse_cluster_time (cluster_time, &t, &i)) { - bson_destroy (&session->cluster_time); - bson_copy_to (cluster_time, &session->cluster_time); - EXIT; - } - - if (_mongoc_cluster_time_greater (cluster_time, &session->cluster_time)) { - bson_destroy (&session->cluster_time); - bson_copy_to (cluster_time, &session->cluster_time); - } - - EXIT; -} - -void -mongoc_client_session_get_operation_time ( - const mongoc_client_session_t *session, - uint32_t *timestamp, - uint32_t *increment) -{ - BSON_ASSERT (session); - BSON_ASSERT (timestamp); - BSON_ASSERT (increment); - - *timestamp = session->operation_timestamp; - *increment = session->operation_increment; -} - -void -mongoc_client_session_advance_operation_time (mongoc_client_session_t *session, - uint32_t timestamp, - uint32_t increment) -{ - ENTRY; - - BSON_ASSERT (session); - - if (timestamp > session->operation_timestamp || - (timestamp == session->operation_timestamp && - increment > session->operation_increment)) { - session->operation_timestamp = timestamp; - session->operation_increment = increment; - } - - EXIT; -} - -static bool -timeout_exceeded (int64_t expire_at) -{ - int64_t current_time = bson_get_monotonic_time (); - return current_time >= expire_at; -} - -static bool -_max_time_ms_failure (bson_t *reply) -{ - bson_iter_t iter; - bson_iter_t descendant; - - if (!reply) { - return false; - } - - /* We can fail with a maxTimeMS error with the error code at the top - level, or nested within a writeConcernError. */ - if (bson_iter_init_find (&iter, reply, "codeName") && - BSON_ITER_HOLDS_UTF8 (&iter) && - 0 == strcmp (bson_iter_utf8 (&iter, NULL), MAX_TIME_MS_EXPIRED)) { - return true; - } - - bson_iter_init (&iter, reply); - if (bson_iter_find_descendant ( - &iter, "writeConcernError.codeName", &descendant) && - BSON_ITER_HOLDS_UTF8 (&descendant) && - 0 == strcmp (bson_iter_utf8 (&descendant, NULL), MAX_TIME_MS_EXPIRED)) { - return true; - } - - return false; -} - -bool -mongoc_client_session_with_transaction ( - mongoc_client_session_t *session, - mongoc_client_session_with_transaction_cb_t cb, - const mongoc_transaction_opt_t *opts, - void *ctx, - bson_t *reply, - bson_error_t *error) -{ - mongoc_internal_transaction_state_t state; - int64_t timeout; - int64_t expire_at; - bson_t local_reply; - bson_t *active_reply = NULL; - bool res; - - ENTRY; - - timeout = session->with_txn_timeout_ms > 0 ? session->with_txn_timeout_ms - : WITH_TXN_TIMEOUT_MS; - - expire_at = bson_get_monotonic_time () + ((int64_t) timeout * 1000); - - /* Attempt to wrap a user callback in start- and end- transaction semantics. - If this fails for transient reasons, restart, either from the very - beginning, or just retry committing the transaction. Will retry until - the timeout WITH_TXN_TIMEOUT_MS is exhausted. - - At the top of this loop, active_reply should always be NULL, and - local_reply should always be uninitialized. */ - while (true) { - res = mongoc_client_session_start_transaction (session, opts, error); - - if (!res) { - GOTO (done); - } - - res = cb (session, ctx, &active_reply, error); - state = session->txn.state; - - /* If the user cb set a reply, use it. Otherwise, sub in local_reply - since we must have an active reply object one way or another. */ - if (!active_reply) { - bson_init (&local_reply); - active_reply = &local_reply; - } - - if (!res) { - if (state == MONGOC_INTERNAL_TRANSACTION_STARTING || - state == MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS) { - BSON_ASSERT ( - mongoc_client_session_abort_transaction (session, NULL)); - } - - if (mongoc_error_has_label (active_reply, TRANSIENT_TXN_ERR) && - !timeout_exceeded (expire_at)) { - bson_destroy (active_reply); - active_reply = NULL; - continue; - } - - /* Unknown error running callback, fail. */ - GOTO (done); - } - - if (state == MONGOC_INTERNAL_TRANSACTION_ABORTED || - state == MONGOC_INTERNAL_TRANSACTION_NONE || - state == MONGOC_INTERNAL_TRANSACTION_COMMITTED || - state == MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY) { - GOTO (done); - } - - /* Whether or not we used local_reply above, use it now, but access it - * through active_reply so cleanup in DONE is simpler. */ - bson_destroy (active_reply); - active_reply = &local_reply; - - /* Commit the transaction, retrying either from here or from the outer - loop on error. - - At the top of this loop, active_reply should always be pointing to - an uninitialized stack-allocated bson_t, so we can pass it into - commit_transaction, which requires this like our other public - functions that take a bson_t reply. */ - while (true) { - res = mongoc_client_session_commit_transaction ( - session, active_reply, error); - - if (!res) { - /* If we have a MaxTimeMsExpired error, fail and propogate - the error to the caller. */ - if (_max_time_ms_failure (active_reply)) { - GOTO (done); - } - - if (mongoc_error_has_label (active_reply, UNKNOWN_COMMIT_RESULT) && - !timeout_exceeded (expire_at)) { - /* Commit_transaction applies majority write concern on retry - * attempts. - * - * Here, we don't want to set active_reply = NULL when we - * destroy, because we want it to point to an uninitialized - * bson_t at the top of this loop every time.*/ - bson_destroy (active_reply); - continue; - } - - if (mongoc_error_has_label (active_reply, TRANSIENT_TXN_ERR) && - !timeout_exceeded (expire_at)) { - /* In the case of a transient txn error, go back to outside loop. - We must set the reply to NULL so it may be used by the cb. */ - bson_destroy (active_reply); - active_reply = NULL; - break; - } - - /* Unknown error committing transaction, fail. */ - GOTO (done); - } - - /* Transaction successfully committed! */ - GOTO (done); - } - } - -done: - /* At this point, active_reply is either pointing to the user's reply - object, or our local one on the stack, or is NULL. */ - if (reply && active_reply) { - bson_copy_to (active_reply, reply); - } else if (reply) { - bson_init (reply); - } - - bson_destroy (active_reply); - - RETURN (res); -} - -bool -mongoc_client_session_start_transaction (mongoc_client_session_t *session, - const mongoc_transaction_opt_t *opts, - bson_error_t *error) -{ - mongoc_server_description_t *sd; - bool ret; - - ENTRY; - BSON_ASSERT (session); - - ret = true; - sd = mongoc_client_select_server ( - session->client, true /* primary */, NULL, error); - if (!sd) { - ret = false; - GOTO (done); - } - - if (sd->max_wire_version < 7 || - (sd->max_wire_version < 8 && sd->type == MONGOC_SERVER_MONGOS)) { - bson_set_error (error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Multi-document transactions are not supported by this " - "server version"); - ret = false; - GOTO (done); - } - - /* use "switch" so that static checkers ensure we handle all states */ - switch (session->txn.state) { - case MONGOC_INTERNAL_TRANSACTION_STARTING: - case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS: - bson_set_error (error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Transaction already in progress"); - ret = false; - GOTO (done); - case MONGOC_INTERNAL_TRANSACTION_ENDING: - MONGOC_ERROR ( - "starting txn in invalid state MONGOC_INTERNAL_TRANSACTION_ENDING"); - abort (); - case MONGOC_INTERNAL_TRANSACTION_COMMITTED: - case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY: - case MONGOC_INTERNAL_TRANSACTION_ABORTED: - case MONGOC_INTERNAL_TRANSACTION_NONE: - default: - break; - } - - session->server_session->txn_number++; - - txn_opts_set (&session->txn.opts, - session->opts.default_txn_opts.read_concern, - session->opts.default_txn_opts.write_concern, - session->opts.default_txn_opts.read_prefs, - session->opts.default_txn_opts.max_commit_time_ms); - - if (opts) { - txn_opts_set (&session->txn.opts, - opts->read_concern, - opts->write_concern, - opts->read_prefs, - opts->max_commit_time_ms); - } - - if (!mongoc_write_concern_is_acknowledged ( - session->txn.opts.write_concern)) { - bson_set_error ( - error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Transactions do not support unacknowledged write concern"); - ret = false; - GOTO (done); - } - - /* Transactions Spec: Starting a new transaction on a pinned ClientSession - * MUST unpin the session. */ - _mongoc_client_session_unpin (session); - session->txn.state = MONGOC_INTERNAL_TRANSACTION_STARTING; - /* Transactions spec: "Drivers MUST clear a session's cached - * 'recoveryToken' when transitioning to the 'no transaction' or - * 'starting transaction' state." */ - bson_destroy (session->recovery_token); - session->recovery_token = NULL; - -done: - mongoc_server_description_destroy (sd); - return ret; -} - - -bool -mongoc_client_session_in_transaction (const mongoc_client_session_t *session) -{ - ENTRY; - - BSON_ASSERT (session); - - /* call the internal function, which would allow a NULL session */ - RETURN (_mongoc_client_session_in_txn (session)); -} - - -mongoc_transaction_state_t -mongoc_client_session_get_transaction_state ( - const mongoc_client_session_t *session) -{ - ENTRY; - - BSON_ASSERT (session); - - switch (session->txn.state) { - case MONGOC_INTERNAL_TRANSACTION_NONE: - RETURN (MONGOC_TRANSACTION_NONE); - case MONGOC_INTERNAL_TRANSACTION_STARTING: - RETURN (MONGOC_TRANSACTION_STARTING); - case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS: - RETURN (MONGOC_TRANSACTION_IN_PROGRESS); - case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY: - case MONGOC_INTERNAL_TRANSACTION_COMMITTED: - RETURN (MONGOC_TRANSACTION_COMMITTED); - case MONGOC_INTERNAL_TRANSACTION_ABORTED: - RETURN (MONGOC_TRANSACTION_ABORTED); - case MONGOC_INTERNAL_TRANSACTION_ENDING: - MONGOC_ERROR ("invalid state MONGOC_INTERNAL_TRANSACTION_ENDING when " - "getting transaction state"); - abort (); - default: - MONGOC_ERROR ("invalid state %d when getting transaction state", - (int) session->txn.state); - abort (); - break; - } -} - -bool -mongoc_client_session_commit_transaction (mongoc_client_session_t *session, - bson_t *reply, - bson_error_t *error) -{ - bool r = false; - - ENTRY; - - BSON_ASSERT (session); - - /* For testing only, mock out certain kinds of errors. */ - if (session->fail_commit_label) { - bson_t labels; - - BSON_ASSERT (reply); - - bson_init (reply); - BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels); - BSON_APPEND_UTF8 (&labels, "0", session->fail_commit_label); - - /* Waste the test timeout, if there is one set. */ - if (session->with_txn_timeout_ms) { - _mongoc_usleep (session->with_txn_timeout_ms * 1000); - } - - RETURN (r); - } - - /* See Transactions Spec for state diagram. In COMMITTED state, user can call - * commit again to retry after network error */ - - switch (session->txn.state) { - case MONGOC_INTERNAL_TRANSACTION_NONE: - bson_set_error (error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "No transaction started"); - _mongoc_bson_init_if_set (reply); - break; - case MONGOC_INTERNAL_TRANSACTION_STARTING: - case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY: - /* we sent no commands, not actually started on server */ - session->txn.state = MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY; - _mongoc_bson_init_if_set (reply); - r = true; - break; - case MONGOC_INTERNAL_TRANSACTION_COMMITTED: - case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS: { - bool explicitly_retrying = - (session->txn.state == MONGOC_INTERNAL_TRANSACTION_COMMITTED); - /* in MONGOC_INTERNAL_TRANSACTION_ENDING we add txnNumber and autocommit: - * false to the commitTransaction command, but if it fails with network - * error we add UnknownTransactionCommitResult not - * TransientTransactionError */ - session->txn.state = MONGOC_INTERNAL_TRANSACTION_ENDING; - r = txn_commit (session, explicitly_retrying, reply, error); - session->txn.state = MONGOC_INTERNAL_TRANSACTION_COMMITTED; - break; - } - case MONGOC_INTERNAL_TRANSACTION_ENDING: - MONGOC_ERROR ( - "commit called in invalid state MONGOC_INTERNAL_TRANSACTION_ENDING"); - abort (); - case MONGOC_INTERNAL_TRANSACTION_ABORTED: - default: - bson_set_error ( - error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Cannot call commitTransaction after calling abortTransaction"); - _mongoc_bson_init_if_set (reply); - break; - } - - RETURN (r); -} - - -bool -mongoc_client_session_abort_transaction (mongoc_client_session_t *session, - bson_error_t *error) -{ - ENTRY; - - BSON_ASSERT (session); - - switch (session->txn.state) { - case MONGOC_INTERNAL_TRANSACTION_STARTING: - /* we sent no commands, not actually started on server */ - session->txn.state = MONGOC_INTERNAL_TRANSACTION_ABORTED; - txn_opts_cleanup (&session->txn.opts); - RETURN (true); - case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS: - session->txn.state = MONGOC_INTERNAL_TRANSACTION_ENDING; - /* Transactions Spec: ignore errors from abortTransaction command */ - txn_abort (session, NULL, NULL); - session->txn.state = MONGOC_INTERNAL_TRANSACTION_ABORTED; - RETURN (true); - case MONGOC_INTERNAL_TRANSACTION_COMMITTED: - case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY: - bson_set_error ( - error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Cannot call abortTransaction after calling commitTransaction"); - RETURN (false); - case MONGOC_INTERNAL_TRANSACTION_ABORTED: - bson_set_error (error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Cannot call abortTransaction twice"); - RETURN (false); - case MONGOC_INTERNAL_TRANSACTION_ENDING: - MONGOC_ERROR ( - "abort called in invalid state MONGOC_INTERNAL_TRANSACTION_ENDING"); - abort (); - case MONGOC_INTERNAL_TRANSACTION_NONE: - default: - bson_set_error (error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "No transaction started"); - RETURN (false); - } -} - - -bool -_mongoc_client_session_from_iter (mongoc_client_t *client, - const bson_iter_t *iter, - mongoc_client_session_t **cs, - bson_error_t *error) -{ - ENTRY; - - /* must be int64 that fits in uint32 */ - if (!BSON_ITER_HOLDS_INT64 (iter) || bson_iter_int64 (iter) > 0xffffffff) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid sessionId"); - RETURN (false); - } - - RETURN (_mongoc_client_lookup_session ( - client, (uint32_t) bson_iter_int64 (iter), cs, error)); -} - -/* Returns true if in the middle of a transaction. Note: this returns false if - * the commit/abort is running. */ -bool -_mongoc_client_session_in_txn (const mongoc_client_session_t *session) -{ - if (!session) { - return false; - } - - /* use "switch" so that static checkers ensure we handle all states */ - switch (session->txn.state) { - case MONGOC_INTERNAL_TRANSACTION_STARTING: - case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS: - return true; - case MONGOC_INTERNAL_TRANSACTION_NONE: - case MONGOC_INTERNAL_TRANSACTION_ENDING: - case MONGOC_INTERNAL_TRANSACTION_COMMITTED: - case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY: - case MONGOC_INTERNAL_TRANSACTION_ABORTED: - default: - return false; - } -} - -/* Like _mongoc_client_session_in_txn, but also returns true if running the - * commit/abort for this transaction. */ -bool -_mongoc_client_session_in_txn_or_ending (const mongoc_client_session_t *session) -{ - if (!session) { - return false; - } - - /* use "switch" so that static checkers ensure we handle all states */ - switch (session->txn.state) { - case MONGOC_INTERNAL_TRANSACTION_STARTING: - case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS: - case MONGOC_INTERNAL_TRANSACTION_ENDING: - return true; - case MONGOC_INTERNAL_TRANSACTION_NONE: - case MONGOC_INTERNAL_TRANSACTION_COMMITTED: - case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY: - case MONGOC_INTERNAL_TRANSACTION_ABORTED: - default: - return false; - } -} - - -bool -_mongoc_client_session_txn_in_progress (const mongoc_client_session_t *session) -{ - if (!session) { - return false; - } - - return session->txn.state == MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_session_append_txn -- - * - * Add transaction fields besides "readConcern" to @cmd. - * - * Returns: - * Returns false and sets @error if @cmd is empty, otherwise returns - * true. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_client_session_append_txn (mongoc_client_session_t *session, - bson_t *cmd, - bson_error_t *error) -{ - mongoc_transaction_t *txn; - - ENTRY; - - if (!session) { - RETURN (true); - } - - if (bson_empty0 (cmd)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Empty command in transaction"); - RETURN (false); - } - - txn = &session->txn; - - /* See Transactions Spec for state transitions. In COMMITTED / ABORTED, the - * next operation resets the session and moves to TRANSACTION_NONE */ - switch (session->txn.state) { - case MONGOC_INTERNAL_TRANSACTION_STARTING: - txn->state = MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS; - bson_append_bool (cmd, "startTransaction", 16, true); - /* FALL THROUGH */ - case MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS: - case MONGOC_INTERNAL_TRANSACTION_ENDING: - bson_append_int64 ( - cmd, "txnNumber", 9, session->server_session->txn_number); - bson_append_bool (cmd, "autocommit", 10, false); - RETURN (true); - case MONGOC_INTERNAL_TRANSACTION_COMMITTED: - if (!strcmp (_mongoc_get_command_name (cmd), "commitTransaction")) { - /* send commitTransaction again */ - bson_append_int64 ( - cmd, "txnNumber", 9, session->server_session->txn_number); - bson_append_bool (cmd, "autocommit", 10, false); - RETURN (true); - } - /* FALL THROUGH */ - case MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY: - case MONGOC_INTERNAL_TRANSACTION_ABORTED: - txn_opts_cleanup (&session->txn.opts); - txn->state = MONGOC_INTERNAL_TRANSACTION_NONE; - - /* Transactions spec: "Drivers MUST clear a session's cached - * 'recoveryToken' when transitioning to the 'no transaction' or - * 'starting transaction' state." */ - bson_destroy (session->recovery_token); - session->recovery_token = NULL; - RETURN (true); - case MONGOC_INTERNAL_TRANSACTION_NONE: - default: - RETURN (true); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_session_append_read_concern -- - * - * Add read concern if we're doing a read outside a transaction, or if - * we're starting a transaction, or if the user explicitly passed a read - * concern in some function's "opts". The contents of the read concern - * are "level" and/or "afterClusterTime" - if both are empty, don't add - * read concern. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_client_session_append_read_concern (const mongoc_client_session_t *cs, - const bson_t *rc, - bool is_read_command, - bson_t *cmd) -{ - const mongoc_read_concern_t *txn_rc; - mongoc_internal_transaction_state_t txn_state; - bool user_rc_has_level; - bool txn_has_level; - bool has_timestamp; - bool has_level; - bson_t child; - - ENTRY; - - BSON_ASSERT (cs); - - txn_state = cs->txn.state; - txn_rc = cs->txn.opts.read_concern; - - if (txn_state == MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS) { - return; - } - - has_timestamp = - (txn_state == MONGOC_INTERNAL_TRANSACTION_STARTING || is_read_command) && - mongoc_session_opts_get_causal_consistency (&cs->opts) && - cs->operation_timestamp; - user_rc_has_level = rc && bson_has_field (rc, "level"); - txn_has_level = txn_state == MONGOC_INTERNAL_TRANSACTION_STARTING && - !mongoc_read_concern_is_default (txn_rc); - has_level = user_rc_has_level || txn_has_level; - - if (!has_timestamp && !has_level) { - return; - } - - bson_append_document_begin (cmd, "readConcern", 11, &child); - if (rc) { - bson_concat (&child, rc); - } - - if (txn_state == MONGOC_INTERNAL_TRANSACTION_STARTING) { - /* add transaction's read concern level unless user overrides */ - if (txn_has_level && !user_rc_has_level) { - bson_append_utf8 (&child, "level", 5, txn_rc->level, -1); - } - } - - if (has_timestamp) { - bson_append_timestamp (&child, - "afterClusterTime", - 16, - cs->operation_timestamp, - cs->operation_increment); - } - - bson_append_document_end (cmd, &child); -} - - -bool -mongoc_client_session_append (const mongoc_client_session_t *client_session, - bson_t *opts, - bson_error_t *error) -{ - ENTRY; - - BSON_ASSERT (client_session); - BSON_ASSERT (opts); - - if (!bson_append_int64 ( - opts, "sessionId", 9, client_session->client_session_id)) { - bson_set_error ( - error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "invalid opts"); - - RETURN (false); - } - - RETURN (true); -} - - -void -mongoc_client_session_destroy (mongoc_client_session_t *session) -{ - ENTRY; - - if (!session) { - EXIT; - } - - if (session->client_generation == session->client->generation) { - if (mongoc_client_session_in_transaction (session)) { - mongoc_client_session_abort_transaction (session, NULL); - } - - _mongoc_client_unregister_session (session->client, session); - _mongoc_client_push_server_session (session->client, - session->server_session); - } else { - /* If the client has been reset, destroy the server session instead of - pushing it back into the topology's pool. */ - _mongoc_server_session_destroy (session->server_session); - } - - txn_opts_cleanup (&session->opts.default_txn_opts); - txn_opts_cleanup (&session->txn.opts); - - bson_destroy (&session->cluster_time); - bson_destroy (session->recovery_token); - bson_free (session); - - EXIT; -} - -void -_mongoc_client_session_unpin (mongoc_client_session_t *session) -{ - BSON_ASSERT (session); - - session->server_id = 0; -} - -void -_mongoc_client_session_pin (mongoc_client_session_t *session, - uint32_t server_id) -{ - BSON_ASSERT (session); - - session->server_id = server_id; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session.h deleted file mode 100644 index 05b925bd531612369e77e694a5985593eac70841..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-session.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLIENT_SESSION_H -#define MONGOC_CLIENT_SESSION_H - -#include <bson/bson.h> -#include "mongoc/mongoc-macros.h" -/* mongoc_client_session_t, mongoc_transaction_opt_t, and - mongoc_session_opt_t are typedef'ed here */ -#include "mongoc/mongoc-client.h" - -BSON_BEGIN_DECLS - -typedef bool (*mongoc_client_session_with_transaction_cb_t) ( - mongoc_client_session_t *session, - void *ctx, - bson_t **reply, - bson_error_t *error); - -typedef enum { - MONGOC_TRANSACTION_NONE = 0, - MONGOC_TRANSACTION_STARTING = 1, - MONGOC_TRANSACTION_IN_PROGRESS = 2, - MONGOC_TRANSACTION_COMMITTED = 3, - MONGOC_TRANSACTION_ABORTED = 4, -} mongoc_transaction_state_t; - -/* these options types are named "opt_t" but their functions are named with - * "opts", for consistency with the older mongoc_ssl_opt_t */ -MONGOC_EXPORT (mongoc_transaction_opt_t *) -mongoc_transaction_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT; - -MONGOC_EXPORT (mongoc_transaction_opt_t *) -mongoc_transaction_opts_clone (const mongoc_transaction_opt_t *opts); - -MONGOC_EXPORT (void) -mongoc_transaction_opts_destroy (mongoc_transaction_opt_t *opts); - -MONGOC_EXPORT (void) -mongoc_transaction_opts_set_max_commit_time_ms (mongoc_transaction_opt_t *opts, - int64_t max_commit_time_ms); - -MONGOC_EXPORT (int64_t) -mongoc_transaction_opts_get_max_commit_time_ms (mongoc_transaction_opt_t *opts); - -MONGOC_EXPORT (void) -mongoc_transaction_opts_set_read_concern ( - mongoc_transaction_opt_t *opts, const mongoc_read_concern_t *read_concern); - -MONGOC_EXPORT (const mongoc_read_concern_t *) -mongoc_transaction_opts_get_read_concern (const mongoc_transaction_opt_t *opts); - -MONGOC_EXPORT (void) -mongoc_transaction_opts_set_write_concern ( - mongoc_transaction_opt_t *opts, const mongoc_write_concern_t *write_concern); - -MONGOC_EXPORT (const mongoc_write_concern_t *) -mongoc_transaction_opts_get_write_concern ( - const mongoc_transaction_opt_t *opts); - -MONGOC_EXPORT (void) -mongoc_transaction_opts_set_read_prefs (mongoc_transaction_opt_t *opts, - const mongoc_read_prefs_t *read_prefs); - -MONGOC_EXPORT (const mongoc_read_prefs_t *) -mongoc_transaction_opts_get_read_prefs (const mongoc_transaction_opt_t *opts); - -MONGOC_EXPORT (mongoc_session_opt_t *) -mongoc_session_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT; - -MONGOC_EXPORT (void) -mongoc_session_opts_set_causal_consistency (mongoc_session_opt_t *opts, - bool causal_consistency); - -MONGOC_EXPORT (bool) -mongoc_session_opts_get_causal_consistency (const mongoc_session_opt_t *opts); - -MONGOC_EXPORT (void) -mongoc_session_opts_set_default_transaction_opts ( - mongoc_session_opt_t *opts, const mongoc_transaction_opt_t *txn_opts); - -MONGOC_EXPORT (const mongoc_transaction_opt_t *) -mongoc_session_opts_get_default_transaction_opts ( - const mongoc_session_opt_t *opts); - -MONGOC_EXPORT (mongoc_transaction_opt_t *) -mongoc_session_opts_get_transaction_opts ( - const mongoc_client_session_t *session); - -MONGOC_EXPORT (mongoc_session_opt_t *) -mongoc_session_opts_clone (const mongoc_session_opt_t *opts); - -MONGOC_EXPORT (void) -mongoc_session_opts_destroy (mongoc_session_opt_t *opts); - -MONGOC_EXPORT (mongoc_client_t *) -mongoc_client_session_get_client (const mongoc_client_session_t *session); - -MONGOC_EXPORT (const mongoc_session_opt_t *) -mongoc_client_session_get_opts (const mongoc_client_session_t *session); - -MONGOC_EXPORT (const bson_t *) -mongoc_client_session_get_lsid (const mongoc_client_session_t *session); - -MONGOC_EXPORT (const bson_t *) -mongoc_client_session_get_cluster_time (const mongoc_client_session_t *session); - -MONGOC_EXPORT (void) -mongoc_client_session_advance_cluster_time (mongoc_client_session_t *session, - const bson_t *cluster_time); - -MONGOC_EXPORT (void) -mongoc_client_session_get_operation_time ( - const mongoc_client_session_t *session, - uint32_t *timestamp, - uint32_t *increment); - -MONGOC_EXPORT (uint32_t) -mongoc_client_session_get_server_id (const mongoc_client_session_t *session); - -MONGOC_EXPORT (void) -mongoc_client_session_advance_operation_time (mongoc_client_session_t *session, - uint32_t timestamp, - uint32_t increment); - -MONGOC_EXPORT (bool) -mongoc_client_session_with_transaction ( - mongoc_client_session_t *session, - mongoc_client_session_with_transaction_cb_t cb, - const mongoc_transaction_opt_t *opts, - void *ctx, - bson_t *reply, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_client_session_start_transaction (mongoc_client_session_t *session, - const mongoc_transaction_opt_t *opts, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_client_session_in_transaction (const mongoc_client_session_t *session); - -MONGOC_EXPORT (mongoc_transaction_state_t) -mongoc_client_session_get_transaction_state ( - const mongoc_client_session_t *session); - -MONGOC_EXPORT (bool) -mongoc_client_session_commit_transaction (mongoc_client_session_t *session, - bson_t *reply, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_client_session_abort_transaction (mongoc_client_session_t *session, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_client_session_append (const mongoc_client_session_t *client_session, - bson_t *opts, - bson_error_t *error); - -/* There is no mongoc_client_session_end, only mongoc_client_session_destroy. - * Driver Sessions Spec: "In languages that have idiomatic ways of disposing of - * resources, drivers SHOULD support that in addition to or instead of - * endSession." - */ - -MONGOC_EXPORT (void) -mongoc_client_session_destroy (mongoc_client_session_t *session); - -BSON_END_DECLS - - -#endif /* MONGOC_CLIENT_SESSION_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h deleted file mode 100644 index f299f507694fd698e8ab695731ad3421e62e7c18..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2019-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLIENT_SIDE_ENCRYPTION_PRIVATE_H -#define MONGOC_CLIENT_SIDE_ENCRYPTION_PRIVATE_H - -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-client-side-encryption.h" -#include "mongoc/mongoc-cmd-private.h" -#include "bson/bson.h" - -/* cse is an abbreviation for "Client Side Encryption" */ - -bool -_mongoc_cse_auto_encrypt (mongoc_client_t *client, - const mongoc_cmd_t *cmd, - mongoc_cmd_t *encrypted_cmd, - bson_t *encrypted, - bson_error_t *error); - -bool -_mongoc_cse_auto_decrypt (mongoc_client_t *client, - const char *db_name, - const bson_t *reply, - bson_t *decrypted, - bson_error_t *error); - -bool -_mongoc_cse_enable_auto_encryption ( - mongoc_client_t *client, - mongoc_auto_encryption_opts_t *opts /* may be NULL */, - bson_error_t *error); - -bool -_mongoc_fle_spawn_mongocryptd (const char *mongocryptd_spawn_path, - const bson_iter_t *mongocryptd_spawn_args, - bson_error_t *error); - -#endif /* MONGOC_CLIENT_SIDE_ENCRYPTION_PRIVATE_H */ \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption.c deleted file mode 100644 index 5b439da42d00382eef8b6d03af593fff655498ee..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption.c +++ /dev/null @@ -1,1545 +0,0 @@ -/* - * Copyright 2019-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. - */ - -#define MONGOC_LOG_DOMAIN "client-side-encryption" - -#include "mongoc/mongoc-client-side-encryption-private.h" - -#ifndef _WIN32 -#include <sys/wait.h> -#include <signal.h> -#endif - -#include "mongoc/mongoc.h" - -/* Auto encryption opts. */ -struct _mongoc_auto_encryption_opts_t { - /* key_vault_client is not owned and must outlive auto encrypted client. */ - mongoc_client_t *key_vault_client; - char *db; - char *coll; - bson_t *kms_providers; - bson_t *schema_map; - bool bypass_auto_encryption; - bson_t *extra; -}; - -mongoc_auto_encryption_opts_t * -mongoc_auto_encryption_opts_new (void) -{ - return bson_malloc0 (sizeof (mongoc_auto_encryption_opts_t)); -} - -void -mongoc_auto_encryption_opts_destroy (mongoc_auto_encryption_opts_t *opts) -{ - bson_destroy (opts->extra); - bson_destroy (opts->kms_providers); - bson_destroy (opts->schema_map); - bson_free (opts->db); - bson_free (opts->coll); - bson_free (opts); -} - -void -mongoc_auto_encryption_opts_set_key_vault_client ( - mongoc_auto_encryption_opts_t *opts, mongoc_client_t *client) -{ - /* Does not own. */ - opts->key_vault_client = client; -} - -void -mongoc_auto_encryption_opts_set_key_vault_namespace ( - mongoc_auto_encryption_opts_t *opts, const char *db, const char *coll) -{ - bson_free (opts->db); - opts->db = bson_strdup (db); - bson_free (opts->coll); - opts->coll = bson_strdup (coll); -} - -void -mongoc_auto_encryption_opts_set_kms_providers ( - mongoc_auto_encryption_opts_t *opts, const bson_t *providers) -{ - bson_destroy (opts->kms_providers); - opts->kms_providers = NULL; - if (providers) { - opts->kms_providers = bson_copy (providers); - } -} - -void -mongoc_auto_encryption_opts_set_schema_map (mongoc_auto_encryption_opts_t *opts, - const bson_t *schema_map) -{ - bson_destroy (opts->schema_map); - opts->schema_map = NULL; - if (schema_map) { - opts->schema_map = bson_copy (schema_map); - } -} - -void -mongoc_auto_encryption_opts_set_bypass_auto_encryption ( - mongoc_auto_encryption_opts_t *opts, bool bypass_auto_encryption) -{ - opts->bypass_auto_encryption = bypass_auto_encryption; -} - -void -mongoc_auto_encryption_opts_set_extra (mongoc_auto_encryption_opts_t *opts, - const bson_t *extra) -{ - bson_destroy (opts->extra); - opts->extra = NULL; - if (extra) { - opts->extra = bson_copy (extra); - } -} - - -#ifndef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION - -bool -_mongoc_cse_auto_encrypt (mongoc_client_t *client, - const mongoc_cmd_t *cmd, - mongoc_cmd_t *encrypted_cmd, - bson_t *encrypted, - bson_error_t *error) -{ - bson_init (encrypted); - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "libmongoc is not built with support for Client-Side Field " - "Level Encryption. Configure with " - "ENABLE_CLIENT_SIDE_ENCRYPTION=ON."); - return false; -} - -bool -_mongoc_cse_auto_decrypt (mongoc_client_t *client, - const char *db_name, - const bson_t *reply, - bson_t *decrypted, - bson_error_t *error) -{ - bson_init (decrypted); - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "libmongoc is not built with support for Client-Side Field " - "Level Encryption. Configure with " - "ENABLE_CLIENT_SIDE_ENCRYPTION=ON."); - return false; -} - -bool -_mongoc_cse_enable_auto_encryption ( - mongoc_client_t *client, - mongoc_auto_encryption_opts_t *opts /* may be NULL */, - bson_error_t *error) -{ - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "libmongoc is not built with support for Client-Side Field " - "Level Encryption. Configure with " - "ENABLE_CLIENT_SIDE_ENCRYPTION=ON."); - return false; -} - -#else - -#include <mongocrypt/mongocrypt.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" - -static void -_prefix_mongocryptd_error (bson_error_t *error) -{ - char buf[sizeof (error->message)]; - - bson_snprintf (buf, sizeof (buf), "mongocryptd error: %s:", error->message); - memcpy (error->message, buf, sizeof (buf)); -} - -static void -_prefix_key_vault_error (bson_error_t *error) -{ - char buf[sizeof (error->message)]; - - bson_snprintf (buf, sizeof (buf), "key vault error: %s:", error->message); - memcpy (error->message, buf, sizeof (buf)); -} - -static void -_status_to_error (mongocrypt_status_t *status, bson_error_t *error) -{ - bson_set_error (error, - MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION, - mongocrypt_status_code (status), - "%s", - mongocrypt_status_message (status, NULL)); -} - -/* Checks for an error on mongocrypt context. - * If error_expected, then we expect mongocrypt_ctx_status to report a failure - * status (due to a previous failed function call). If it did not, return a - * generic error. - * Returns true if ok, and does not modify @error. - * Returns false if error, and sets @error. - */ -bool -_ctx_check_error (mongocrypt_ctx_t *ctx, - bson_error_t *error, - bool error_expected) -{ - mongocrypt_status_t *status; - - status = mongocrypt_status_new (); - if (!mongocrypt_ctx_status (ctx, status)) { - _status_to_error (status, error); - mongocrypt_status_destroy (status); - return false; - } else if (error_expected) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "generic error from libmongocrypt operation"); - mongocrypt_status_destroy (status); - return false; - } - mongocrypt_status_destroy (status); - return true; -} - -bool -_kms_ctx_check_error (mongocrypt_kms_ctx_t *kms_ctx, - bson_error_t *error, - bool error_expected) -{ - mongocrypt_status_t *status; - - status = mongocrypt_status_new (); - if (!mongocrypt_kms_ctx_status (kms_ctx, status)) { - _status_to_error (status, error); - mongocrypt_status_destroy (status); - return false; - } else if (error_expected) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "generic error from libmongocrypt KMS operation"); - mongocrypt_status_destroy (status); - return false; - } - mongocrypt_status_destroy (status); - return true; -} - -bool -_crypt_check_error (mongocrypt_t *crypt, - bson_error_t *error, - bool error_expected) -{ - mongocrypt_status_t *status; - - status = mongocrypt_status_new (); - if (!mongocrypt_status (crypt, status)) { - _status_to_error (status, error); - mongocrypt_status_destroy (status); - return false; - } else if (error_expected) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "generic error from libmongocrypt handle"); - mongocrypt_status_destroy (status); - return false; - } - mongocrypt_status_destroy (status); - return true; -} - -/* Convert a mongocrypt_binary_t to a static bson_t */ -static bool -_bin_to_static_bson (mongocrypt_binary_t *bin, bson_t *out, bson_error_t *error) -{ - /* Copy bin into bson_t result. */ - if (!bson_init_static ( - out, mongocrypt_binary_data (bin), mongocrypt_binary_len (bin))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "invalid returned bson"); - return false; - } - return true; -} - -/* State handler MONGOCRYPT_CTX_NEED_MONGO_COLLINFO */ -static bool -_state_need_mongo_collinfo (mongoc_client_t *client, - const char *db_name, - mongocrypt_ctx_t *ctx, - bson_error_t *error) -{ - mongoc_database_t *db = NULL; - mongoc_cursor_t *cursor = NULL; - bson_t filter_bson; - const bson_t *collinfo_bson = NULL; - bson_t opts = BSON_INITIALIZER; - mongocrypt_binary_t *filter_bin = NULL; - mongocrypt_binary_t *collinfo_bin = NULL; - bool ret = false; - - /* 1. Run listCollections on the encrypted MongoClient with the filter - * provided by mongocrypt_ctx_mongo_op */ - filter_bin = mongocrypt_binary_new (); - if (!mongocrypt_ctx_mongo_op (ctx, filter_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - if (!_bin_to_static_bson (filter_bin, &filter_bson, error)) { - goto fail; - } - - bson_append_document (&opts, "filter", -1, &filter_bson); - db = mongoc_client_get_database (client, db_name); - cursor = mongoc_database_find_collections_with_opts (db, &opts); - if (mongoc_cursor_error (cursor, error)) { - goto fail; - } - - /* 2. Return the first result (if any) with mongocrypt_ctx_mongo_feed or - * proceed to the next step if nothing was returned. */ - if (mongoc_cursor_next (cursor, &collinfo_bson)) { - collinfo_bin = mongocrypt_binary_new_from_data ( - (uint8_t *) bson_get_data (collinfo_bson), collinfo_bson->len); - if (!mongocrypt_ctx_mongo_feed (ctx, collinfo_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - } else if (mongoc_cursor_error (cursor, error)) { - goto fail; - } - - /* 3. Call mongocrypt_ctx_mongo_done */ - if (!mongocrypt_ctx_mongo_done (ctx)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - ret = true; - -fail: - - bson_destroy (&opts); - mongocrypt_binary_destroy (filter_bin); - mongocrypt_binary_destroy (collinfo_bin); - mongoc_cursor_destroy (cursor); - mongoc_database_destroy (db); - return ret; -} - -static bool -_state_need_mongo_markings (mongoc_client_t *client, - mongocrypt_ctx_t *ctx, - bson_error_t *error) -{ - bool ret = false; - mongocrypt_binary_t *mongocryptd_cmd_bin = NULL; - mongocrypt_binary_t *mongocryptd_reply_bin = NULL; - bson_t mongocryptd_cmd_bson; - bson_t reply = BSON_INITIALIZER; - - mongocryptd_cmd_bin = mongocrypt_binary_new (); - - if (!mongocrypt_ctx_mongo_op (ctx, mongocryptd_cmd_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - if (!_bin_to_static_bson ( - mongocryptd_cmd_bin, &mongocryptd_cmd_bson, error)) { - goto fail; - } - - /* 1. Use db.runCommand to run the command provided by - * mongocrypt_ctx_mongo_op on the MongoClient connected to mongocryptd. */ - bson_destroy (&reply); - if (!mongoc_client_command_simple (client->mongocryptd_client, - "admin", - &mongocryptd_cmd_bson, - NULL /* read_prefs */, - &reply, - error)) { - _prefix_mongocryptd_error (error); - goto fail; - } - - /* 2. Feed the reply back with mongocrypt_ctx_mongo_feed. */ - mongocryptd_reply_bin = mongocrypt_binary_new_from_data ( - (uint8_t *) bson_get_data (&reply), reply.len); - if (!mongocrypt_ctx_mongo_feed (ctx, mongocryptd_reply_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - /* 3. Call mongocrypt_ctx_mongo_done. */ - if (!mongocrypt_ctx_mongo_done (ctx)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - ret = true; -fail: - bson_destroy (&reply); - mongocrypt_binary_destroy (mongocryptd_cmd_bin); - mongocrypt_binary_destroy (mongocryptd_reply_bin); - return ret; -} - -static bool -_state_need_mongo_keys (mongoc_client_t *client, - mongocrypt_ctx_t *ctx, - bson_error_t *error) -{ - bool ret = false; - mongocrypt_binary_t *filter_bin = NULL; - bson_t filter_bson; - bson_t opts = BSON_INITIALIZER; - mongocrypt_binary_t *key_bin = NULL; - const bson_t *key_bson; - mongoc_cursor_t *cursor = NULL; - mongoc_read_concern_t *rc = NULL; - mongoc_collection_t *key_vault_coll = NULL; - - /* 1. Use MongoCollection.find on the MongoClient connected to the key vault - * client (which may be the same as the encrypted client). Use the filter - * provided by mongocrypt_ctx_mongo_op. */ - filter_bin = mongocrypt_binary_new (); - if (!mongocrypt_ctx_mongo_op (ctx, filter_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - if (!_bin_to_static_bson (filter_bin, &filter_bson, error)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - if (!mongoc_read_concern_append (rc, &opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "%s", - "could not set read concern"); - goto fail; - } - key_vault_coll = client->key_vault_coll; - cursor = mongoc_collection_find_with_opts ( - key_vault_coll, &filter_bson, &opts, NULL /* read prefs */); - /* 2. Feed all resulting documents back (if any) with repeated calls to - * mongocrypt_ctx_mongo_feed. */ - while (mongoc_cursor_next (cursor, &key_bson)) { - mongocrypt_binary_destroy (key_bin); - key_bin = mongocrypt_binary_new_from_data ( - (uint8_t *) bson_get_data (key_bson), key_bson->len); - if (!mongocrypt_ctx_mongo_feed (ctx, key_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - } - if (mongoc_cursor_error (cursor, error)) { - _prefix_key_vault_error (error); - goto fail; - } - - /* 3. Call mongocrypt_ctx_mongo_done. */ - if (!mongocrypt_ctx_mongo_done (ctx)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - ret = true; -fail: - mongocrypt_binary_destroy (filter_bin); - mongoc_cursor_destroy (cursor); - mongoc_read_concern_destroy (rc); - bson_destroy (&opts); - mongocrypt_binary_destroy (key_bin); - return ret; -} - -static mongoc_stream_t * -_get_stream (const char *endpoint, - int32_t connecttimeoutms, - bson_error_t *error) -{ - mongoc_stream_t *base_stream = NULL; - mongoc_stream_t *tls_stream = NULL; - bool ret = false; - mongoc_ssl_opt_t ssl_opts = {0}; - mongoc_host_list_t host; - char *copied_endpoint = NULL; - - if (!strchr (endpoint, ':')) { - copied_endpoint = bson_strdup_printf ("%s:443", endpoint); - } - - if (!_mongoc_host_list_from_string_with_err ( - &host, copied_endpoint ? copied_endpoint : endpoint, error)) { - goto fail; - } - - base_stream = mongoc_client_connect_tcp (connecttimeoutms, &host, error); - if (!base_stream) { - goto fail; - } - - /* Wrap in a tls_stream. */ - memcpy (&ssl_opts, mongoc_ssl_opt_get_default (), sizeof ssl_opts); - tls_stream = mongoc_stream_tls_new_with_hostname ( - base_stream, endpoint, &ssl_opts, 1 /* client */); - - if (!mongoc_stream_tls_handshake_block ( - tls_stream, endpoint, connecttimeoutms, error)) { - goto fail; - } - - ret = true; -fail: - bson_free (copied_endpoint); - if (!ret) { - if (tls_stream) { - /* destroys base_stream too */ - mongoc_stream_destroy (tls_stream); - } else if (base_stream) { - mongoc_stream_destroy (base_stream); - } - return NULL; - } - return tls_stream; -} - -static bool -_state_need_kms (mongoc_client_t *client, - mongocrypt_ctx_t *ctx, - bson_error_t *error) -{ - mongocrypt_kms_ctx_t *kms_ctx = NULL; - mongoc_stream_t *tls_stream = NULL; - bool ret = false; - mongocrypt_binary_t *http_req = NULL; - mongocrypt_binary_t *http_reply = NULL; - const char *endpoint; - - kms_ctx = mongocrypt_ctx_next_kms_ctx (ctx); - while (kms_ctx) { - mongoc_iovec_t iov; - - mongocrypt_binary_destroy (http_req); - http_req = mongocrypt_binary_new (); - if (!mongocrypt_kms_ctx_message (kms_ctx, http_req)) { - _kms_ctx_check_error (kms_ctx, error, true); - goto fail; - } - - if (!mongocrypt_kms_ctx_endpoint (kms_ctx, &endpoint)) { - _kms_ctx_check_error (kms_ctx, error, true); - goto fail; - } - - tls_stream = - _get_stream (endpoint, client->cluster.sockettimeoutms, error); - if (!tls_stream) { - goto fail; - } - - iov.iov_base = (char *) mongocrypt_binary_data (http_req); - iov.iov_len = mongocrypt_binary_len (http_req); - - if (!_mongoc_stream_writev_full ( - tls_stream, &iov, 1, client->cluster.sockettimeoutms, error)) { - goto fail; - } - - /* Read and feed reply. */ - while (mongocrypt_kms_ctx_bytes_needed (kms_ctx) > 0) { -#define BUFFER_SIZE 1024 - uint8_t buf[BUFFER_SIZE]; - uint32_t bytes_needed = mongocrypt_kms_ctx_bytes_needed (kms_ctx); - ssize_t read_ret; - - /* Cap the bytes requested at the buffer size. */ - if (bytes_needed > BUFFER_SIZE) { - bytes_needed = BUFFER_SIZE; - } - - read_ret = mongoc_stream_read (tls_stream, - buf, - bytes_needed, - 1 /* min_bytes. */, - client->cluster.sockettimeoutms); - if (read_ret == -1) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "failed to read from KMS stream: %d", - errno); - goto fail; - } - - if (read_ret == 0) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "unexpected EOF from KMS stream"); - goto fail; - } - - mongocrypt_binary_destroy (http_reply); - http_reply = mongocrypt_binary_new_from_data (buf, read_ret); - if (!mongocrypt_kms_ctx_feed (kms_ctx, http_reply)) { - _kms_ctx_check_error (kms_ctx, error, true); - goto fail; - } - } - kms_ctx = mongocrypt_ctx_next_kms_ctx (ctx); - } - /* When NULL is returned by mongocrypt_ctx_next_kms_ctx, this can either be - * an error or end-of-list. */ - if (!_ctx_check_error (ctx, error, false)) { - goto fail; - } - - if (!mongocrypt_ctx_kms_done (ctx)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - ret = true; -fail: - mongoc_stream_destroy (tls_stream); - mongocrypt_binary_destroy (http_req); - mongocrypt_binary_destroy (http_reply); - return ret; -#undef BUFFER_SIZE -} - -static bool -_state_ready (mongoc_client_t *client, - mongocrypt_ctx_t *ctx, - bson_t **result, - bson_error_t *error) -{ - mongocrypt_binary_t *result_bin = NULL; - bson_t tmp; - bool ret = false; - - result_bin = mongocrypt_binary_new (); - if (!mongocrypt_ctx_finalize (ctx, result_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - if (!_bin_to_static_bson (result_bin, &tmp, error)) { - goto fail; - } - - *result = bson_copy (&tmp); - - ret = true; -fail: - mongocrypt_binary_destroy (result_bin); - return ret; -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_cse_run_state_machine -- - * Run the mongocrypt_ctx state machine. - * - * Post-conditions: - * *result may be set to a new bson_t, or NULL otherwise. Caller should - * not assume return value of true means *result is set. If false returned, - * @error is set. - * - * -------------------------------------------------------------------------- - */ -bool -_mongoc_cse_run_state_machine (mongoc_client_t *client, - const char *db_name, - mongocrypt_ctx_t *ctx, - bson_t **result, - bson_error_t *error) -{ - bool ret = false; - mongocrypt_binary_t *bin = NULL; - - *result = NULL; - while (true) { - switch (mongocrypt_ctx_state (ctx)) { - default: - case MONGOCRYPT_CTX_ERROR: - _ctx_check_error (ctx, error, true); - goto fail; - case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO: - if (!_state_need_mongo_collinfo (client, db_name, ctx, error)) { - goto fail; - } - break; - case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: - if (!_state_need_mongo_markings (client, ctx, error)) { - goto fail; - } - break; - case MONGOCRYPT_CTX_NEED_MONGO_KEYS: - if (!_state_need_mongo_keys (client, ctx, error)) { - goto fail; - } - break; - case MONGOCRYPT_CTX_NEED_KMS: - if (!_state_need_kms (client, ctx, error)) { - goto fail; - } - break; - case MONGOCRYPT_CTX_READY: - if (!_state_ready (client, ctx, result, error)) { - goto fail; - } - break; - case MONGOCRYPT_CTX_DONE: - goto success; - break; - } - } - -success: - ret = true; -fail: - mongocrypt_binary_destroy (bin); - return ret; -} - - -/*-------------------------------------------------------------------------- - * - * _prep_for_auto_encryption -- - * If @cmd contains a type=1 payload (document sequence), convert it into - * a type=0 payload (array payload). See OP_MSG spec for details. - * Place the command BSON that should be encrypted into @out. - * - * Post-conditions: - * @out is initialized and set to the full payload. If @cmd did not include - * a type=1 payload, @out is statically initialized. Caller must not modify - * @out after, but must call bson_destroy. - * - * -------------------------------------------------------------------------- - */ -static void -_prep_for_auto_encryption (const mongoc_cmd_t *cmd, bson_t *out) -{ - /* If there is no type=1 payload, return the command unchanged. */ - if (!cmd->payload || !cmd->payload_size) { - bson_init_static (out, bson_get_data (cmd->command), cmd->command->len); - return; - } - - /* Otherwise, append the type=1 payload as an array. */ - bson_copy_to (cmd->command, out); - _mongoc_cmd_append_payload_as_array (cmd, out); -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_cse_auto_encrypt -- - * - * Perform automatic encryption if enabled. - * - * Return: - * True on success, false on error. - * - * Pre-conditions: - * CSE is enabled on client. - * - * Post-conditions: - * If return false, @error is set. @encrypted is always initialized. - * @encrypted_cmd is set to the mongoc_cmd_t to send, which may refer - * to @encrypted. - * If automatic encryption was bypassed, @encrypted is set to an empty - * document, but @encrypted_cmd is a copy of @cmd. Caller must always - * bson_destroy @encrypted. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_cse_auto_encrypt (mongoc_client_t *client, - const mongoc_cmd_t *cmd, - mongoc_cmd_t *encrypted_cmd, - bson_t *encrypted, - bson_error_t *error) -{ - mongocrypt_ctx_t *ctx = NULL; - mongocrypt_binary_t *cmd_bin = NULL; - bool ret = false; - bson_t cmd_bson = BSON_INITIALIZER; - bson_t *result = NULL; - bson_iter_t iter; - - ENTRY; - - bson_init (encrypted); - - if (client->bypass_auto_encryption) { - memcpy (encrypted_cmd, cmd, sizeof (mongoc_cmd_t)); - bson_destroy (&cmd_bson); - return true; - } - - if (!client->bypass_auto_encryption && - cmd->server_stream->sd->max_wire_version < WIRE_VERSION_CSE) { - bson_set_error ( - error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "%s", - "Auto-encryption requires a minimum MongoDB version of 4.2"); - goto fail; - } - - /* Create the context for the operation. */ - ctx = mongocrypt_ctx_new (client->crypt); - if (!ctx) { - _crypt_check_error (client->crypt, error, true); - goto fail; - } - - /* Construct the command we're sending to libmongocrypt. If cmd includes a - * type 1 payload, convert it to a type 0 payload. */ - bson_destroy (&cmd_bson); - _prep_for_auto_encryption (cmd, &cmd_bson); - cmd_bin = mongocrypt_binary_new_from_data ( - (uint8_t *) bson_get_data (&cmd_bson), cmd_bson.len); - if (!mongocrypt_ctx_encrypt_init (ctx, cmd->db_name, -1, cmd_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - if (!_mongoc_cse_run_state_machine ( - client, cmd->db_name, ctx, &result, error)) { - goto fail; - } - - if (result) { - bson_destroy (encrypted); - bson_steal (encrypted, result); - result = NULL; - } - - /* Re-append $db if encryption stripped it. */ - if (!bson_iter_init_find (&iter, encrypted, "$db")) { - BSON_APPEND_UTF8 (encrypted, "$db", cmd->db_name); - } - - /* Create the modified cmd_t. */ - memcpy (encrypted_cmd, cmd, sizeof (mongoc_cmd_t)); - /* Modify the mongoc_cmd_t and clear the payload, since - * _mongoc_cse_auto_encrypt converted the payload into an embedded array. */ - encrypted_cmd->payload = NULL; - encrypted_cmd->payload_size = 0; - encrypted_cmd->command = encrypted; - - ret = true; - -fail: - bson_destroy (result); - bson_destroy (&cmd_bson); - mongocrypt_binary_destroy (cmd_bin); - mongocrypt_ctx_destroy (ctx); - RETURN (ret); -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_cse_auto_decrypt -- - * - * Perform automatic decryption. - * - * Return: - * True on success, false on error. - * - * Pre-conditions: - * FLE is enabled on client. - * - * Post-conditions: - * If return false, @error is set. @decrypted is always initialized. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_cse_auto_decrypt (mongoc_client_t *client, - const char *db_name, - const bson_t *reply, - bson_t *decrypted, - bson_error_t *error) -{ - mongocrypt_ctx_t *ctx = NULL; - mongocrypt_binary_t *reply_bin = NULL; - bool ret = false; - bson_t *result = NULL; - - ENTRY; - bson_init (decrypted); - - /* Create the context for the operation. */ - ctx = mongocrypt_ctx_new (client->crypt); - if (!ctx) { - _crypt_check_error (client->crypt, error, true); - goto fail; - } - - reply_bin = mongocrypt_binary_new_from_data ( - (uint8_t *) bson_get_data (reply), reply->len); - if (!mongocrypt_ctx_decrypt_init (ctx, reply_bin)) { - _ctx_check_error (ctx, error, true); - goto fail; - } - - if (!_mongoc_cse_run_state_machine (client, db_name, ctx, &result, error)) { - goto fail; - } - - if (result) { - bson_destroy (decrypted); - bson_steal (decrypted, result); - result = NULL; - } - - ret = true; - -fail: - bson_destroy (result); - mongocrypt_binary_destroy (reply_bin); - mongocrypt_ctx_destroy (ctx); - RETURN (ret); -} - -static void -_log_callback (mongocrypt_log_level_t mongocrypt_log_level, - const char *message, - uint32_t message_len, - void *ctx) -{ - mongoc_log_level_t log_level = MONGOC_LOG_LEVEL_ERROR; - - switch (mongocrypt_log_level) { - case MONGOCRYPT_LOG_LEVEL_FATAL: - log_level = MONGOC_LOG_LEVEL_CRITICAL; - break; - case MONGOCRYPT_LOG_LEVEL_ERROR: - log_level = MONGOC_LOG_LEVEL_ERROR; - break; - case MONGOCRYPT_LOG_LEVEL_WARNING: - log_level = MONGOC_LOG_LEVEL_WARNING; - break; - case MONGOCRYPT_LOG_LEVEL_INFO: - log_level = MONGOC_LOG_LEVEL_INFO; - break; - case MONGOCRYPT_LOG_LEVEL_TRACE: - log_level = MONGOC_LOG_LEVEL_TRACE; - break; - } - - mongoc_log (log_level, MONGOC_LOG_DOMAIN, "%s", message, NULL); -} - -static void -_uri_construction_error (bson_error_t *error) -{ - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "Error constructing URI to mongocryptd"); -} - -bool -_mongoc_cse_enable_auto_encryption (mongoc_client_t *client, - mongoc_auto_encryption_opts_t *opts, - bson_error_t *error) -{ - bson_iter_t iter; - bool ret = false; - mongocrypt_binary_t *local_masterkey_bin = NULL; - mongocrypt_binary_t *schema_map_bin = NULL; - mongoc_uri_t *mongocryptd_uri = NULL; - - ENTRY; - - - if (!client->topology->single_threaded) { - bson_set_error ( - error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, - "Automatic encryption on pooled clients must be set on the pool"); - goto fail; - } - - if (client->cse_enabled) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "Automatic encryption already set"); - goto fail; - } - - if (!opts) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, - "Auto encryption options required"); - goto fail; - } - - /* Check for required options */ - if (!opts->db || !opts->coll) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, - "Key vault namespace option required"); - goto fail; - } - - if (!opts->kms_providers) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, - "KMS providers option required"); - goto fail; - } - - client->cse_enabled = true; - client->bypass_auto_encryption = opts->bypass_auto_encryption; - - if (!client->bypass_auto_encryption) { - /* Spawn mongocryptd if needed, and create a client to it. */ - bool mongocryptd_bypass_spawn = false; - const char *mongocryptd_spawn_path = NULL; - bson_iter_t mongocryptd_spawn_args; - bool has_spawn_args = false; - - if (opts->extra) { - if (bson_iter_init_find ( - &iter, opts->extra, "mongocryptdBypassSpawn") && - bson_iter_as_bool (&iter)) { - mongocryptd_bypass_spawn = true; - } - if (bson_iter_init_find (&iter, opts->extra, "mongocryptdSpawnPath") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - mongocryptd_spawn_path = bson_iter_utf8 (&iter, NULL); - } - if (bson_iter_init_find (&iter, opts->extra, "mongocryptdSpawnArgs") && - BSON_ITER_HOLDS_ARRAY (&iter)) { - memcpy (&mongocryptd_spawn_args, &iter, sizeof (bson_iter_t)); - has_spawn_args = true; - } - - if (bson_iter_init_find (&iter, opts->extra, "mongocryptdURI")) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, - "Expected string for option 'mongocryptdURI'"); - goto fail; - } - mongocryptd_uri = - mongoc_uri_new_with_error (bson_iter_utf8 (&iter, NULL), error); - if (!mongocryptd_uri) { - goto fail; - } - } - } - - if (!mongocryptd_bypass_spawn) { - if (!_mongoc_fle_spawn_mongocryptd ( - mongocryptd_spawn_path, - has_spawn_args ? &mongocryptd_spawn_args : NULL, - error)) { - goto fail; - } - } - - if (!mongocryptd_uri) { - /* Always default to connecting to TCP, despite spec v1.0.0. Because - * starting mongocryptd when one is running removes the domain socket - * file per SERVER-41029. Connecting over TCP is more reliable. - */ - mongocryptd_uri = - mongoc_uri_new_with_error ("mongodb://localhost:27020", error); - - if (!mongocryptd_uri) { - goto fail; - } - - if (!mongoc_uri_set_option_as_int32 ( - mongocryptd_uri, MONGOC_URI_SERVERSELECTIONTIMEOUTMS, 5000)) { - _uri_construction_error (error); - goto fail; - } - } - - /* By default, single threaded clients set serverSelectionTryOnce to - * true, which means server selection fails if a topology scan fails - * the first time (i.e. it will not make repeat attempts until - * serverSelectionTimeoutMS expires). Override this, since the first - * attempt to connect to mongocryptd may fail when spawning, as it - * takes some time for mongocryptd to listen on sockets. */ - if (!mongoc_uri_set_option_as_bool ( - mongocryptd_uri, MONGOC_URI_SERVERSELECTIONTRYONCE, false)) { - _uri_construction_error (error); - goto fail; - } - - client->mongocryptd_client = mongoc_client_new_from_uri (mongocryptd_uri); - - if (!client->mongocryptd_client) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "Unable to create client to mongocryptd"); - goto fail; - } - /* Similarly, single threaded clients will by default wait for 5 second - * cooldown period after failing to connect to a server before making - * another attempt. Meaning if the first attempt to mongocryptd fails - * to connect, then the user observes a 5 second delay. This is not - * configurable in the URI, so override. */ - _mongoc_topology_bypass_cooldown (client->mongocryptd_client->topology); - } - - /* Get the key vault collection. */ - if (opts->key_vault_client) { - client->key_vault_coll = mongoc_client_get_collection ( - opts->key_vault_client, opts->db, opts->coll); - } else { - client->key_vault_coll = - mongoc_client_get_collection (client, opts->db, opts->coll); - } - - /* Create the handle to libmongocrypt. */ - client->crypt = mongocrypt_new (); - - mongocrypt_setopt_log_handler ( - client->crypt, _log_callback, NULL /* context */); - - /* Take options from the kms_providers map. */ - if (bson_iter_init_find (&iter, opts->kms_providers, "aws")) { - bson_iter_t subiter; - const char *aws_access_key_id = NULL; - uint32_t aws_access_key_id_len = 0; - const char *aws_secret_access_key = NULL; - uint32_t aws_secret_access_key_len = 0; - - if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, - "Expected document for KMS provider 'aws'"); - goto fail; - } - - BSON_ASSERT (bson_iter_recurse (&iter, &subiter)); - if (bson_iter_find (&subiter, "accessKeyId")) { - aws_access_key_id = bson_iter_utf8 (&subiter, &aws_access_key_id_len); - } - - BSON_ASSERT (bson_iter_recurse (&iter, &subiter)); - if (bson_iter_find (&subiter, "secretAccessKey")) { - aws_secret_access_key = - bson_iter_utf8 (&subiter, &aws_secret_access_key_len); - } - - /* libmongocrypt returns error if options are NULL. */ - if (!mongocrypt_setopt_kms_provider_aws (client->crypt, - aws_access_key_id, - aws_access_key_id_len, - aws_secret_access_key, - aws_secret_access_key_len)) { - _crypt_check_error (client->crypt, error, true); - goto fail; - } - } - - if (bson_iter_init_find (&iter, opts->kms_providers, "local")) { - bson_iter_t subiter; - - if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, - "Expected document for KMS provider 'local'"); - goto fail; - } - - bson_iter_recurse (&iter, &subiter); - if (bson_iter_find (&subiter, "key")) { - uint32_t key_len; - const uint8_t *key_data; - - bson_iter_binary (&subiter, NULL /* subtype */, &key_len, &key_data); - local_masterkey_bin = - mongocrypt_binary_new_from_data ((uint8_t *) key_data, key_len); - } - - /* libmongocrypt returns error if options are NULL. */ - if (!mongocrypt_setopt_kms_provider_local (client->crypt, - local_masterkey_bin)) { - _crypt_check_error (client->crypt, error, true); - goto fail; - } - } - - if (opts->schema_map) { - schema_map_bin = mongocrypt_binary_new_from_data ( - (uint8_t *) bson_get_data (opts->schema_map), opts->schema_map->len); - if (!mongocrypt_setopt_schema_map (client->crypt, schema_map_bin)) { - _crypt_check_error (client->crypt, error, true); - goto fail; - } - } - - if (!mongocrypt_init (client->crypt)) { - _crypt_check_error (client->crypt, error, true); - goto fail; - } - - ret = true; -fail: - mongocrypt_binary_destroy (local_masterkey_bin); - mongocrypt_binary_destroy (schema_map_bin); - mongoc_uri_destroy (mongocryptd_uri); - RETURN (ret); -} - -#ifdef _WIN32 -static bool -_do_spawn (const char *path, char **args, bson_error_t *error) -{ - bson_string_t *command; - char **arg; - PROCESS_INFORMATION process_information; - STARTUPINFO startup_info; - - /* Construct the full command, quote path and arguments. */ - command = bson_string_new (""); - bson_string_append (command, "\""); - if (path) { - bson_string_append (command, path); - } - bson_string_append (command, "mongocryptd.exe"); - bson_string_append (command, "\""); - /* skip the "mongocryptd" first arg. */ - arg = args + 1; - while (*arg) { - bson_string_append (command, " \""); - bson_string_append (command, *arg); - bson_string_append (command, "\""); - arg++; - } - - ZeroMemory (&process_information, sizeof (process_information)); - ZeroMemory (&startup_info, sizeof (startup_info)); - - startup_info.cb = sizeof (startup_info); - - if (!CreateProcessA (NULL, - command->str, - NULL, - NULL, - false /* inherit descriptors */, - DETACHED_PROCESS /* FLAGS */, - NULL /* environment */, - NULL /* current directory */, - &startup_info, - &process_information)) { - long lastError = GetLastError (); - LPSTR message = NULL; - - FormatMessageA ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastError, - 0, - (LPSTR) &message, - 0, - NULL); - - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "failed to spawn mongocryptd: %s", - message); - LocalFree (message); - bson_string_free (command, true); - return false; - } - - bson_string_free (command, true); - return true; -} -#else - -/*-------------------------------------------------------------------------- - * - * _do_spawn -- - * - * Spawn process defined by arg[0] on POSIX systems. - * - * Note, if mongocryptd fails to spawn (due to not being found on the path), - * an error is not reported and true is returned. Users will get an error - * later, upon first attempt to use mongocryptd. - * - * These comments refer to three distinct processes: parent, child, and - * mongocryptd. - * - parent is initial calling process - * - child is the first forked child. It fork-execs mongocryptd then - * terminates. This makes mongocryptd an orphan, making it immediately - * adopted by the init process. - * - mongocryptd is the final background daemon (grandchild process). - * - * Return: - * False if an error definitely occurred. Returns true if no reportable - * error occurred (though an error may have occurred in starting - * mongocryptd, resulting in the process not running). - * - * Arguments: - * args - A NULL terminated list of arguments. The first argument MUST - * be the name of the process to execute, and the last argument MUST be - * NULL. - * - * Post-conditions: - * If return false, @error is set. - * - *-------------------------------------------------------------------------- - */ -static bool -_do_spawn (const char *path, char **args, bson_error_t *error) -{ - pid_t pid; - int fd; - char *to_exec; - - /* Fork. The child will terminate immediately (after fork-exec'ing - * mongocryptd). This orphans mongocryptd, and allows parent to wait on - * child. */ - pid = fork (); - if (pid < 0) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "failed to fork (errno=%d) '%s'", - errno, - strerror (errno)); - return false; - } else if (pid > 0) { - int child_status; - - /* Child will spawn mongocryptd and immediately terminate to turn - * mongocryptd into an orphan. */ - if (waitpid (pid, &child_status, 0 /* options */) < 0) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - "failed to wait for child (errno=%d) '%s'", - errno, - strerror (errno)); - return false; - } - /* parent is done at this point, return. */ - return true; - } - - /* We're no longer in the parent process. Errors encountered result in an - * exit. - * Note, we're not logging here, because that would require the user's log - * callback to be fork-safe. - */ - - /* Start a new session for the child, so it is not bound to the current - * session (e.g. terminal session). */ - if (setsid () < 0) { - exit (EXIT_FAILURE); - } - - /* Fork again. Child terminates so mongocryptd gets orphaned and immedately - * adopted by init. */ - signal (SIGHUP, SIG_IGN); - pid = fork (); - if (pid < 0) { - exit (EXIT_FAILURE); - } else if (pid > 0) { - /* Child terminates immediately. */ - exit (EXIT_SUCCESS); - } - - /* TODO: Depending on the outcome of MONGOCRYPT-115, possibly change the - * process's working directory with chdir like: `chdir (default_pid_path)`. - * Currently pid file ends up in application's working directory. */ - - /* Set the user file creation mask to zero. */ - umask (0); - - /* Close and reopen stdin. */ - fd = open ("/dev/null", O_RDONLY); - if (fd < 0) { - exit (EXIT_FAILURE); - } - dup2 (fd, STDIN_FILENO); - close (fd); - - /* Close and reopen stdout. */ - fd = open ("/dev/null", O_WRONLY); - if (fd < 0) { - exit (EXIT_FAILURE); - } - if (dup2 (fd, STDOUT_FILENO) < 0 || close (fd) < 0) { - exit (EXIT_FAILURE); - } - - /* Close and reopen stderr. */ - fd = open ("/dev/null", O_RDWR); - if (fd < 0) { - exit (EXIT_FAILURE); - } - if (dup2 (fd, STDERR_FILENO) < 0 || close (fd) < 0) { - exit (EXIT_FAILURE); - } - fd = 0; - - if (path) { - to_exec = bson_strdup_printf ("%s%s", path, args[0]); - } else { - to_exec = bson_strdup (args[0]); - } - if (execvp (to_exec, args) < 0) { - /* Need to exit. */ - exit (EXIT_FAILURE); - } - - /* Will never execute. */ - return false; -} -#endif - -/*-------------------------------------------------------------------------- - * - * _mongoc_fle_spawn_mongocryptd -- - * - * Attempt to spawn mongocryptd as a background process. - * - * Return: - * False if an error definitely occurred. Returns true if no reportable - * error occurred (though an error may have occurred in starting - * mongocryptd, resulting in the process not running). - * - * Arguments: - * mongocryptd_spawn_path May be NULL, otherwise the path to mongocryptd. - * mongocryptd_spawn_args May be NULL, otherwise a bson_iter_t to the - * value "mongocryptdSpawnArgs" in AutoEncryptionOpts.extraOptions - * (see spec). - * - * Post-conditions: - * If return false, @error is set. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_fle_spawn_mongocryptd (const char *mongocryptd_spawn_path, - const bson_iter_t *mongocryptd_spawn_args, - bson_error_t *error) -{ - char **args = NULL; - bson_iter_t iter; - bool passed_idle_shutdown_timeout_secs = false; - int num_args = 2; /* for leading "mongocrypt" and trailing NULL */ - int i; - - /* iterate once to get length and validate all are strings */ - if (mongocryptd_spawn_args) { - BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (mongocryptd_spawn_args)); - bson_iter_recurse (mongocryptd_spawn_args, &iter); - while (bson_iter_next (&iter)) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG, - "invalid argument for mongocryptd, must be string"); - return false; - } - /* Check if the arg starts with --idleShutdownTimeoutSecs= or is equal - * to --idleShutdownTimeoutSecs */ - if (0 == strncmp ("--idleShutdownTimeoutSecs=", - bson_iter_utf8 (&iter, NULL), - 26) || - 0 == strcmp ("--idleShutdownTimeoutSecs", - bson_iter_utf8 (&iter, NULL))) { - passed_idle_shutdown_timeout_secs = true; - } - num_args++; - } - } - - if (!passed_idle_shutdown_timeout_secs) { - /* add one more */ - num_args++; - } - - args = (char **) bson_malloc (sizeof (char *) * num_args); - i = 0; - args[i++] = "mongocryptd"; - - if (mongocryptd_spawn_args) { - BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (mongocryptd_spawn_args)); - bson_iter_recurse (mongocryptd_spawn_args, &iter); - while (bson_iter_next (&iter)) { - args[i++] = (char *) bson_iter_utf8 (&iter, NULL); - } - } - - if (!passed_idle_shutdown_timeout_secs) { - args[i++] = "--idleShutdownTimeoutSecs=60"; - } - - BSON_ASSERT (i == num_args - 1); - args[i++] = NULL; - - return _do_spawn (mongocryptd_spawn_path, args, error); -} - -#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */ \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption.h deleted file mode 100644 index d721b28d23c2b6e67c5a323906c4dea78615e8a3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client-side-encryption.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2019-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLIENT_SIDE_ENCRYPTION_H -#define MONGOC_CLIENT_SIDE_ENCRYPTION_H - -#include <bson/bson.h> - -/* Forward declare */ -struct _mongoc_client_t; - -BSON_BEGIN_DECLS - -typedef struct _mongoc_auto_encryption_opts_t mongoc_auto_encryption_opts_t; - -MONGOC_EXPORT (mongoc_auto_encryption_opts_t *) -mongoc_auto_encryption_opts_new (void); - -MONGOC_EXPORT (void) -mongoc_auto_encryption_opts_destroy (mongoc_auto_encryption_opts_t *opts); - -MONGOC_EXPORT (void) -mongoc_auto_encryption_opts_set_key_vault_client ( - mongoc_auto_encryption_opts_t *opts, struct _mongoc_client_t *client); - -MONGOC_EXPORT (void) -mongoc_auto_encryption_opts_set_key_vault_namespace ( - mongoc_auto_encryption_opts_t *opts, const char *db, const char *coll); - -MONGOC_EXPORT (void) -mongoc_auto_encryption_opts_set_kms_providers ( - mongoc_auto_encryption_opts_t *opts, const bson_t *kms_providers); - -MONGOC_EXPORT (void) -mongoc_auto_encryption_opts_set_schema_map (mongoc_auto_encryption_opts_t *opts, - const bson_t *schema_map); - -MONGOC_EXPORT (void) -mongoc_auto_encryption_opts_set_bypass_auto_encryption ( - mongoc_auto_encryption_opts_t *opts, bool bypass_auto_encryption); - -MONGOC_EXPORT (void) -mongoc_auto_encryption_opts_set_extra (mongoc_auto_encryption_opts_t *opts, - const bson_t *extra); - -BSON_END_DECLS - -#endif /* MONGOC_CLIENT_SIDE_ENCRYPTION_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-client.c deleted file mode 100644 index 1ac86d327631bfcd38d5d34e372877ce1437962c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client.c +++ /dev/null @@ -1,2998 +0,0 @@ -/* - * Copyright 2013 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 <bson/bson.h> -#include "mongoc/mongoc-config.h" -#ifdef MONGOC_HAVE_DNSAPI -/* for DnsQuery_UTF8 */ -#include <Windows.h> -#include <WinDNS.h> -#include <ws2tcpip.h> -#else -#if defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH) -#include <netdb.h> -#include <netinet/tcp.h> -#include <arpa/nameser.h> -#include <resolv.h> -#define BSON_INSIDE -#include <bson/bson-string.h> -#undef BSON_INSIDE - -#endif -#endif - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-client-side-encryption-private.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-database-private.h" -#include "mongoc/mongoc-gridfs-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-error-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-queue-private.h" -#include "mongoc/mongoc-socket.h" -#include "mongoc/mongoc-stream-buffered.h" -#include "mongoc/mongoc-stream-socket.h" -#include "mongoc/mongoc-thread-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-set-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-change-stream-private.h" -#include "mongoc/mongoc-client-session-private.h" -#include "mongoc/mongoc-cursor-private.h" - -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-ssl-private.h" -#include "mongoc/mongoc-cmd-private.h" -#include "mongoc/mongoc-opts-private.h" -#endif - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "client" - - -static void -_mongoc_client_op_killcursors (mongoc_cluster_t *cluster, - mongoc_server_stream_t *server_stream, - int64_t cursor_id, - int64_t operation_id, - const char *db, - const char *collection); - -static void -_mongoc_client_killcursors_command (mongoc_cluster_t *cluster, - mongoc_server_stream_t *server_stream, - int64_t cursor_id, - const char *db, - const char *collection, - mongoc_client_session_t *cs); - -#define DNS_ERROR(_msg, ...) \ - do { \ - bson_set_error (error, \ - MONGOC_ERROR_STREAM, \ - MONGOC_ERROR_STREAM_NAME_RESOLUTION, \ - _msg, \ - __VA_ARGS__); \ - GOTO (done); \ - } while (0) - - -#ifdef MONGOC_HAVE_DNSAPI - -typedef bool (*mongoc_rr_callback_t) (const char *service, - PDNS_RECORD pdns, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error); - -static bool -srv_callback (const char *service, - PDNS_RECORD pdns, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error) -{ - if (rr_data && rr_data->hosts) { - _mongoc_host_list_remove_host ( - &(rr_data->hosts), pdns->Data.SRV.pNameTarget, pdns->Data.SRV.wPort); - } - - return mongoc_uri_upsert_host ( - uri, pdns->Data.SRV.pNameTarget, pdns->Data.SRV.wPort, error); -} - -/* rr_data is unused, but here to match srv_callback signature */ -static bool -txt_callback (const char *service, - PDNS_RECORD pdns, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error) -{ - DWORD i; - bson_string_t *txt; - bool r; - - txt = bson_string_new (NULL); - - for (i = 0; i < pdns->Data.TXT.dwStringCount; i++) { - bson_string_append (txt, pdns->Data.TXT.pStringArray[i]); - } - - r = mongoc_uri_parse_options (uri, txt->str, true /* from_dns */, error); - bson_string_free (txt, true); - - return r; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_get_rr_dnsapi -- - * - * Fetch SRV or TXT resource records using the Windows DNS API and - * update @uri. - * - * Returns: - * Success or failure. - * - * For an SRV lookup, returns false if there is any error. - * - * For TXT lookup, ignores any error fetching the resource record, but - * returns false if the resource record is found and there is an error - * reading its contents as URI options. - * - * Side effects: - * @error is set if there is a failure. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_get_rr_dnsapi (const char *service, - mongoc_rr_type_t rr_type, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error) -{ - const char *rr_type_name; - WORD nst; - mongoc_rr_callback_t callback; - PDNS_RECORD pdns = NULL; - DNS_STATUS res; - LPVOID lpMsgBuf = NULL; - bool dns_success; - bool callback_success = true; - int i; - - ENTRY; - - if (rr_type == MONGOC_RR_SRV) { - /* return true only if DNS succeeds */ - dns_success = false; - rr_type_name = "SRV"; - nst = DNS_TYPE_SRV; - callback = srv_callback; - } else { - /* return true whether or not DNS succeeds */ - dns_success = true; - rr_type_name = "TXT"; - nst = DNS_TYPE_TEXT; - callback = txt_callback; - } - - res = DnsQuery_UTF8 (service, - nst, - DNS_QUERY_BYPASS_CACHE, - NULL /* IP Address */, - &pdns, - 0 /* reserved */); - - if (res) { - DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; - - if (FormatMessage (flags, - 0, - res, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, - 0)) { - DNS_ERROR ("Failed to look up %s record \"%s\": %s", - rr_type_name, - service, - (char *) lpMsgBuf); - } - - DNS_ERROR ("Failed to look up %s record \"%s\": Unknown error", - rr_type_name, - service); - } - - if (!pdns) { - DNS_ERROR ("No %s records for \"%s\"", rr_type_name, service); - } - - dns_success = true; - i = 0; - - do { - /* DnsQuery can return additional records not of the requested type */ - if ((rr_type == MONGOC_RR_TXT && pdns->wType == DNS_TYPE_TEXT) || - (rr_type == MONGOC_RR_SRV && pdns->wType == DNS_TYPE_SRV)) { - if (i > 0 && rr_type == MONGOC_RR_TXT) { - /* Initial DNS Seedlist Discovery Spec: a client "MUST raise an - error when multiple TXT records are encountered". */ - callback_success = false; - DNS_ERROR ("Multiple TXT records for \"%s\"", service); - } - - if (rr_data) { - if ((i == 0) || (pdns->dwTtl < rr_data->min_ttl)) { - rr_data->min_ttl = pdns->dwTtl; - } - } - - if (!callback (service, pdns, uri, rr_data, error)) { - callback_success = false; - GOTO (done); - } - - i++; - } - - pdns = pdns->pNext; - } while (pdns); - - if (rr_data) { - rr_data->count = i; - } - -done: - if (pdns) { - DnsRecordListFree (pdns, DnsFreeRecordList); - } - - if (lpMsgBuf) { - LocalFree (lpMsgBuf); - } - - RETURN (dns_success && callback_success); -} - -#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH)) - -typedef bool (*mongoc_rr_callback_t) (const char *service, - ns_msg *ns_answer, - ns_rr *rr, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error); - -static bool -srv_callback (const char *service, - ns_msg *ns_answer, - ns_rr *rr, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error) -{ - const uint8_t *data; - char name[1024]; - uint16_t port; - int size; - bool ret = false; - - data = ns_rr_rdata (*rr); - /* memcpy the network endian port before converting to host endian. we cannot - * cast (data + 4) directly as a uint16_t*, because it may not align on an - * 2-byte boundary. */ - memcpy (&port, data + 4, sizeof (port)); - port = ntohs (port); - size = dn_expand (ns_msg_base (*ns_answer), - ns_msg_end (*ns_answer), - data + 6, - name, - sizeof (name)); - - if (size < 1) { - DNS_ERROR ("Invalid record in SRV answer for \"%s\": \"%s\"", - service, - strerror (h_errno)); - } - - if (rr_data && rr_data->hosts) { - _mongoc_host_list_remove_host (&(rr_data->hosts), name, port); - } - ret = mongoc_uri_upsert_host (uri, name, port, error); - -done: - return ret; -} - -/* rr_data is unused, but here to match srv_callback signature */ -static bool -txt_callback (const char *service, - ns_msg *ns_answer, - ns_rr *rr, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error) -{ - char s[256]; - const uint8_t *data; - bson_string_t *txt; - uint16_t pos, total; - uint8_t len; - bool r = false; - - total = (uint16_t) ns_rr_rdlen (*rr); - if (total < 1 || total > 255) { - DNS_ERROR ("Invalid TXT record size %hu for \"%s\"", total, service); - } - - /* a TXT record has one or more strings, each up to 255 chars, each is - * prefixed by its length as 1 byte. thus endianness doesn't matter. */ - txt = bson_string_new (NULL); - pos = 0; - data = ns_rr_rdata (*rr); - - while (pos < total) { - memcpy (&len, data + pos, sizeof (uint8_t)); - pos++; - bson_strncpy (s, (const char *) (data + pos), (size_t) len + 1); - bson_string_append (txt, s); - pos += len; - } - - r = mongoc_uri_parse_options (uri, txt->str, true /* from_dns */, error); - bson_string_free (txt, true); - -done: - return r; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_get_rr_search -- - * - * Fetch SRV or TXT resource records using libresolv and update @uri. - * - * Returns: - * Success or failure. - * - * For an SRV lookup, returns false if there is any error. - * - * For TXT lookup, ignores any error fetching the resource record, but - * returns false if the resource record is found and there is an error - * reading its contents as URI options. - * - * Side effects: - * @error is set if there is a failure. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_get_rr_search (const char *service, - mongoc_rr_type_t rr_type, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error) -{ -#ifdef MONGOC_HAVE_RES_NSEARCH - struct __res_state state = {0}; -#endif - int size = 0; - unsigned char *search_buf = NULL; - size_t buffer_size = 1024; - ns_msg ns_answer; - int n; - int i; - const char *rr_type_name; - ns_type nst; - mongoc_rr_callback_t callback; - ns_rr resource_record; - bool dns_success; - bool callback_success = true; - - ENTRY; - - if (rr_type == MONGOC_RR_SRV) { - /* return true only if DNS succeeds */ - dns_success = false; - rr_type_name = "SRV"; - nst = ns_t_srv; - callback = srv_callback; - } else { - /* return true whether or not DNS succeeds */ - dns_success = true; - rr_type_name = "TXT"; - nst = ns_t_txt; - callback = txt_callback; - } - - do { - if (search_buf) { - free (search_buf); - - /* increase buffer size by the previous response size. This ensures - * that even if a subsequent response is larger, we'll still be able - * to fit it in the response buffer */ - buffer_size = buffer_size + size; - } - - search_buf = (unsigned char *) bson_malloc (buffer_size); - BSON_ASSERT (search_buf); - -#ifdef MONGOC_HAVE_RES_NSEARCH - /* thread-safe */ - res_ninit (&state); - size = - res_nsearch (&state, service, ns_c_in, nst, search_buf, buffer_size); -#elif defined(MONGOC_HAVE_RES_SEARCH) - size = res_search (service, ns_c_in, nst, search_buf, buffer_size); -#endif - - if (size < 0) { - DNS_ERROR ("Failed to look up %s record \"%s\": %s", - rr_type_name, - service, - strerror (h_errno)); - } - } while (size > buffer_size); - - if (ns_initparse (search_buf, size, &ns_answer)) { - DNS_ERROR ("Invalid %s answer for \"%s\"", rr_type_name, service); - } - - n = ns_msg_count (ns_answer, ns_s_an); - if (!n) { - DNS_ERROR ("No %s records for \"%s\"", rr_type_name, service); - } - - if (rr_data) { - rr_data->count = n; - } - - for (i = 0; i < n; i++) { - if (i > 0 && rr_type == MONGOC_RR_TXT) { - /* Initial DNS Seedlist Discovery Spec: a client "MUST raise an error - * when multiple TXT records are encountered". */ - callback_success = false; - DNS_ERROR ("Multiple TXT records for \"%s\"", service); - } - - if (ns_parserr (&ns_answer, ns_s_an, i, &resource_record)) { - DNS_ERROR ("Invalid record %d of %s answer for \"%s\": \"%s\"", - i, - rr_type_name, - service, - strerror (h_errno)); - } - - if (rr_data) { - uint32_t ttl; - - ttl = ns_rr_ttl (resource_record); - if ((i == 0) || (ttl < rr_data->min_ttl)) { - rr_data->min_ttl = ttl; - } - } - - if (!callback ( - service, &ns_answer, &resource_record, uri, rr_data, error)) { - callback_success = false; - GOTO (done); - } - } - - dns_success = true; - -done: - - free (search_buf); - -#ifdef MONGOC_HAVE_RES_NDESTROY - /* defined on BSD/Darwin, and only if MONGOC_HAVE_RES_NSEARCH is defined */ - res_ndestroy (&state); -#elif defined(MONGOC_HAVE_RES_NCLOSE) - /* defined on Linux, and only if MONGOC_HAVE_RES_NSEARCH is defined */ - res_nclose (&state); -#endif - RETURN (dns_success && callback_success); -} -#endif - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_get_rr -- - * - * Fetch an SRV or TXT resource record and update @uri. See RFCs 1464 - * and 2782, and MongoDB's Initial DNS Seedlist Discovery Spec. - * - * Returns: - * Success or failure. - * - * Side effects: - * @error is set if there is a failure. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_client_get_rr (const char *service, - mongoc_rr_type_t rr_type, - mongoc_uri_t *uri, - mongoc_rr_data_t *rr_data, - bson_error_t *error) -{ -#ifdef MONGOC_HAVE_DNSAPI - return _mongoc_get_rr_dnsapi (service, rr_type, uri, rr_data, error); -#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH)) - return _mongoc_get_rr_search (service, rr_type, uri, rr_data, error); -#else - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NAME_RESOLUTION, - "libresolv unavailable, cannot use mongodb+srv URI"); - return false; -#endif -} - -#undef DNS_ERROR - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_connect_tcp -- - * - * Connect to a host using a TCP socket. - * - * This will be performed synchronously and return a mongoc_stream_t - * that can be used to connect with the remote host. - * - * Returns: - * A newly allocated mongoc_stream_t if successful; otherwise - * NULL and @error is set. - * - * Side effects: - * @error is set if return value is NULL. - * - *-------------------------------------------------------------------------- - */ - -mongoc_stream_t * -mongoc_client_connect_tcp (int32_t connecttimeoutms, - const mongoc_host_list_t *host, - bson_error_t *error) -{ - mongoc_socket_t *sock = NULL; - struct addrinfo hints; - struct addrinfo *result, *rp; - int64_t expire_at; - char portstr[8]; - int s; - - ENTRY; - - BSON_ASSERT (connecttimeoutms); - BSON_ASSERT (host); - - bson_snprintf (portstr, sizeof portstr, "%hu", host->port); - - memset (&hints, 0, sizeof hints); - hints.ai_family = host->family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = 0; - hints.ai_protocol = 0; - - s = getaddrinfo (host->host, portstr, &hints, &result); - - if (s != 0) { - mongoc_counter_dns_failure_inc (); - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NAME_RESOLUTION, - "Failed to resolve %s", - host->host); - RETURN (NULL); - } - - mongoc_counter_dns_success_inc (); - - for (rp = result; rp; rp = rp->ai_next) { - /* - * Create a new non-blocking socket. - */ - if (!(sock = mongoc_socket_new ( - rp->ai_family, rp->ai_socktype, rp->ai_protocol))) { - continue; - } - - /* - * Try to connect to the peer. - */ - expire_at = bson_get_monotonic_time () + (connecttimeoutms * 1000L); - if (0 != - mongoc_socket_connect ( - sock, rp->ai_addr, (mongoc_socklen_t) rp->ai_addrlen, expire_at)) { - mongoc_socket_destroy (sock); - sock = NULL; - continue; - } - - break; - } - - if (!sock) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "Failed to connect to target host: %s", - host->host_and_port); - freeaddrinfo (result); - RETURN (NULL); - } - - freeaddrinfo (result); - - return mongoc_stream_socket_new (sock); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_connect_unix -- - * - * Connect to a MongoDB server using a UNIX domain socket. - * - * Returns: - * A newly allocated mongoc_stream_t if successful; otherwise - * NULL and @error is set. - * - * Side effects: - * @error is set if return value is NULL. - * - *-------------------------------------------------------------------------- - */ - -static mongoc_stream_t * -mongoc_client_connect_unix (const mongoc_host_list_t *host, bson_error_t *error) -{ -#ifdef _WIN32 - ENTRY; - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "UNIX domain sockets not supported on win32."); - RETURN (NULL); -#else - struct sockaddr_un saddr; - mongoc_socket_t *sock; - mongoc_stream_t *ret = NULL; - - ENTRY; - - BSON_ASSERT (host); - - memset (&saddr, 0, sizeof saddr); - saddr.sun_family = AF_UNIX; - bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host); - - sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0); - - if (sock == NULL) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to create socket."); - RETURN (NULL); - } - - if (-1 == mongoc_socket_connect ( - sock, (struct sockaddr *) &saddr, sizeof saddr, -1)) { - mongoc_socket_destroy (sock); - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "Failed to connect to UNIX domain socket."); - RETURN (NULL); - } - - ret = mongoc_stream_socket_new (sock); - - RETURN (ret); -#endif -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_default_stream_initiator -- - * - * A mongoc_stream_initiator_t that will handle the various type - * of supported sockets by MongoDB including TCP and UNIX. - * - * Language binding authors may want to implement an alternate - * version of this method to use their native stream format. - * - * Returns: - * A mongoc_stream_t if successful; otherwise NULL and @error is set. - * - * Side effects: - * @error is set if return value is NULL. - * - *-------------------------------------------------------------------------- - */ - -mongoc_stream_t * -mongoc_client_default_stream_initiator (const mongoc_uri_t *uri, - const mongoc_host_list_t *host, - void *user_data, - bson_error_t *error) -{ - mongoc_stream_t *base_stream = NULL; - int32_t connecttimeoutms; -#ifdef MONGOC_ENABLE_SSL - mongoc_client_t *client = (mongoc_client_t *) user_data; - const char *mechanism; -#endif - - BSON_ASSERT (uri); - BSON_ASSERT (host); - -#ifndef MONGOC_ENABLE_SSL - if (mongoc_uri_get_tls (uri)) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER, - "SSL is not enabled in this build of mongo-c-driver."); - return NULL; - } -#endif - - connecttimeoutms = mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_CONNECTTIMEOUTMS, MONGOC_DEFAULT_CONNECTTIMEOUTMS); - - switch (host->family) { - case AF_UNSPEC: -#if defined(AF_INET6) - case AF_INET6: -#endif - case AF_INET: - base_stream = mongoc_client_connect_tcp (connecttimeoutms, host, error); - break; - case AF_UNIX: - base_stream = mongoc_client_connect_unix (host, error); - break; - default: - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_INVALID_TYPE, - "Invalid address family: 0x%02x", - host->family); - break; - } - -#ifdef MONGOC_ENABLE_SSL - if (base_stream) { - mechanism = mongoc_uri_get_auth_mechanism (uri); - - if (client->use_ssl || - (mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) { - mongoc_stream_t *original = base_stream; - - base_stream = mongoc_stream_tls_new_with_hostname ( - base_stream, host->host, &client->ssl_opts, true); - - if (!base_stream) { - mongoc_stream_destroy (original); - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed initialize TLS state."); - return NULL; - } - - if (!mongoc_stream_tls_handshake_block ( - base_stream, host->host, connecttimeoutms, error)) { - mongoc_stream_destroy (base_stream); - return NULL; - } - } - } -#endif - - return base_stream ? mongoc_stream_buffered_new (base_stream, 1024) : NULL; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_create_stream -- - * - * INTERNAL API - * - * This function is used by the mongoc_cluster_t to initiate a - * new stream. This is done because cluster is private API and - * those using mongoc_client_t may need to override this process. - * - * This function calls the default initiator for new streams. - * - * Returns: - * A newly allocated mongoc_stream_t if successful; otherwise - * NULL and @error is set. - * - * Side effects: - * @error is set if return value is NULL. - * - *-------------------------------------------------------------------------- - */ - -mongoc_stream_t * -_mongoc_client_create_stream (mongoc_client_t *client, - const mongoc_host_list_t *host, - bson_error_t *error) -{ - BSON_ASSERT (client); - BSON_ASSERT (host); - - return client->initiator (client->uri, host, client->initiator_data, error); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_recv -- - * - * Receives a RPC from a remote MongoDB cluster node. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @error is set if return value is false. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_client_recv (mongoc_client_t *client, - mongoc_rpc_t *rpc, - mongoc_buffer_t *buffer, - mongoc_server_stream_t *server_stream, - bson_error_t *error) -{ - BSON_ASSERT (client); - BSON_ASSERT (rpc); - BSON_ASSERT (buffer); - BSON_ASSERT (server_stream); - - if (!mongoc_cluster_try_recv ( - &client->cluster, rpc, buffer, server_stream, error)) { - mongoc_topology_invalidate_server ( - client->topology, server_stream->sd->id, error); - return false; - } - return true; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_new -- - * - * Create a new mongoc_client_t using the URI provided. - * - * @uri should be a MongoDB URI string such as "mongodb://localhost/" - * More information on the format can be found at - * http://docs.mongodb.org/manual/reference/connection-string/ - * - * Returns: - * A newly allocated mongoc_client_t or NULL if @uri_string is - * invalid. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -mongoc_client_t * -mongoc_client_new (const char *uri_string) -{ - mongoc_topology_t *topology; - mongoc_client_t *client; - mongoc_uri_t *uri; - - - if (!uri_string) { - uri_string = "mongodb://127.0.0.1/"; - } - - if (!(uri = mongoc_uri_new (uri_string))) { - return NULL; - } - - topology = mongoc_topology_new (uri, true); - - client = _mongoc_client_new_from_uri (topology); - if (!client) { - mongoc_topology_destroy (topology); - } - mongoc_uri_destroy (uri); - - return client; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_set_ssl_opts - * - * set ssl opts for a client - * - * Returns: - * Nothing - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -#ifdef MONGOC_ENABLE_SSL -void -mongoc_client_set_ssl_opts (mongoc_client_t *client, - const mongoc_ssl_opt_t *opts) -{ - BSON_ASSERT (client); - BSON_ASSERT (opts); - - _mongoc_ssl_opts_cleanup (&client->ssl_opts); - - client->use_ssl = true; - _mongoc_ssl_opts_copy_to (opts, &client->ssl_opts); - - if (client->topology->single_threaded) { - mongoc_topology_scanner_set_ssl_opts (client->topology->scanner, - &client->ssl_opts); - } -} -#endif - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_new_from_uri -- - * - * Create a new mongoc_client_t for a mongoc_uri_t. - * - * Returns: - * A newly allocated mongoc_client_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_client_t * -mongoc_client_new_from_uri (const mongoc_uri_t *uri) -{ - mongoc_topology_t *topology; - - topology = mongoc_topology_new (uri, true); - - /* topology->uri may be different from uri: if this is a mongodb+srv:// URI - * then mongoc_topology_new has fetched SRV and TXT records and updated its - * uri from them. - */ - return _mongoc_client_new_from_uri (topology); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_new_from_uri -- - * - * Create a new mongoc_client_t for a given topology object. - * - * Returns: - * A newly allocated mongoc_client_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_client_t * -_mongoc_client_new_from_uri (mongoc_topology_t *topology) -{ - mongoc_client_t *client; - const mongoc_read_prefs_t *read_prefs; - const mongoc_read_concern_t *read_concern; - const mongoc_write_concern_t *write_concern; - const char *appname; - - BSON_ASSERT (topology); - -#ifndef MONGOC_ENABLE_SSL - if (mongoc_uri_get_tls (topology->uri)) { - MONGOC_ERROR ("Can't create SSL client, SSL not enabled in this build."); - return NULL; - } -#endif - - client = (mongoc_client_t *) bson_malloc0 (sizeof *client); - client->uri = mongoc_uri_copy (topology->uri); - client->initiator = mongoc_client_default_stream_initiator; - client->initiator_data = client; - client->topology = topology; - client->error_api_version = MONGOC_ERROR_API_VERSION_LEGACY; - client->error_api_set = false; - client->client_sessions = mongoc_set_new (8, NULL, NULL); - client->csid_rand_seed = (unsigned int) bson_get_monotonic_time (); - - write_concern = mongoc_uri_get_write_concern (client->uri); - client->write_concern = mongoc_write_concern_copy (write_concern); - - read_concern = mongoc_uri_get_read_concern (client->uri); - client->read_concern = mongoc_read_concern_copy (read_concern); - - read_prefs = mongoc_uri_get_read_prefs_t (client->uri); - client->read_prefs = mongoc_read_prefs_copy (read_prefs); - - appname = - mongoc_uri_get_option_as_utf8 (client->uri, MONGOC_URI_APPNAME, NULL); - if (appname && client->topology->single_threaded) { - /* the appname should have already been validated */ - BSON_ASSERT (mongoc_client_set_appname (client, appname)); - } - - mongoc_cluster_init (&client->cluster, client->uri, client); - -#ifdef MONGOC_ENABLE_SSL - client->use_ssl = false; - if (mongoc_uri_get_tls (client->uri)) { - mongoc_ssl_opt_t ssl_opt = {0}; - - _mongoc_ssl_opts_from_uri (&ssl_opt, client->uri); - /* sets use_ssl = true */ - mongoc_client_set_ssl_opts (client, &ssl_opt); - } -#endif - - mongoc_counter_clients_active_inc (); - - return client; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_destroy -- - * - * Destroys a mongoc_client_t and cleans up all resources associated - * with the client instance. - * - * Returns: - * None. - * - * Side effects: - * @client is destroyed. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_client_destroy (mongoc_client_t *client) -{ - if (client) { - if (client->topology->single_threaded) { - _mongoc_client_end_sessions (client); - mongoc_topology_destroy (client->topology); - } - - mongoc_write_concern_destroy (client->write_concern); - mongoc_read_concern_destroy (client->read_concern); - mongoc_read_prefs_destroy (client->read_prefs); - mongoc_cluster_destroy (&client->cluster); - mongoc_uri_destroy (client->uri); - mongoc_set_destroy (client->client_sessions); - -#ifdef MONGOC_ENABLE_SSL - _mongoc_ssl_opts_cleanup (&client->ssl_opts); -#endif - -#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION - mongoc_collection_destroy (client->key_vault_coll); - mongoc_client_destroy (client->mongocryptd_client); - mongocrypt_destroy (client->crypt); -#endif - - bson_free (client); - - mongoc_counter_clients_active_dec (); - mongoc_counter_clients_disposed_inc (); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_get_uri -- - * - * Fetch the URI used for @client. - * - * Returns: - * A mongoc_uri_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_uri_t * -mongoc_client_get_uri (const mongoc_client_t *client) -{ - BSON_ASSERT (client); - - return client->uri; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_start_session -- - * - * Creates a structure to communicate in a session over @client. - * - * This structure should be freed when the caller is done with it - * using mongoc_client_session_destroy(). - * - * Returns: - * A newly allocated mongoc_client_session_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_client_session_t * -mongoc_client_start_session (mongoc_client_t *client, - const mongoc_session_opt_t *opts, - bson_error_t *error) -{ - mongoc_server_session_t *ss; - mongoc_client_session_t *cs; - uint32_t csid; - - ENTRY; - - ss = _mongoc_client_pop_server_session (client, error); - if (!ss) { - RETURN (NULL); - } - - /* get a random internal id for the session, retrying on collision */ - do { - csid = (uint32_t) _mongoc_rand_simple (&client->csid_rand_seed); - } while (mongoc_set_get (client->client_sessions, csid)); - - cs = _mongoc_client_session_new (client, ss, opts, csid); - - /* remember session so if we see its client_session_id in a command, we can - * find its lsid and clusterTime */ - mongoc_set_add (client->client_sessions, csid, cs); - - RETURN (cs); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_get_database -- - * - * Fetches a newly allocated database structure to communicate with - * a database over @client. - * - * @database should be a db name such as "test". - * - * This structure should be freed when the caller is done with it - * using mongoc_database_destroy(). - * - * Returns: - * A newly allocated mongoc_database_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_database_t * -mongoc_client_get_database (mongoc_client_t *client, const char *name) -{ - BSON_ASSERT (client); - BSON_ASSERT (name); - - return _mongoc_database_new (client, - name, - client->read_prefs, - client->read_concern, - client->write_concern); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_get_default_database -- - * - * Get the database named in the MongoDB connection URI, or NULL - * if none was specified in the URI. - * - * This structure should be freed when the caller is done with it - * using mongoc_database_destroy(). - * - * Returns: - * A newly allocated mongoc_database_t or NULL. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_database_t * -mongoc_client_get_default_database (mongoc_client_t *client) -{ - const char *db; - - BSON_ASSERT (client); - db = mongoc_uri_get_database (client->uri); - - if (db) { - return mongoc_client_get_database (client, db); - } - - return NULL; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_get_collection -- - * - * This function returns a newly allocated collection structure. - * - * @db should be the name of the database, such as "test". - * @collection should be the name of the collection such as "test". - * - * The above would result in the namespace "test.test". - * - * You should free this structure when you are done with it using - * mongoc_collection_destroy(). - * - * Returns: - * A newly allocated mongoc_collection_t that should be freed with - * mongoc_collection_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_collection_t * -mongoc_client_get_collection (mongoc_client_t *client, - const char *db, - const char *collection) -{ - BSON_ASSERT (client); - BSON_ASSERT (db); - BSON_ASSERT (collection); - - return _mongoc_collection_new (client, - db, - collection, - client->read_prefs, - client->read_concern, - client->write_concern); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_get_gridfs -- - * - * This function returns a newly allocated collection structure. - * - * @db should be the name of the database, such as "test". - * - * @prefix optional prefix for GridFS collection names, or NULL. Default - * is "fs", thus the default collection names for GridFS are "fs.files" - * and "fs.chunks". - * - * Returns: - * A newly allocated mongoc_gridfs_t that should be freed with - * mongoc_gridfs_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_gridfs_t * -mongoc_client_get_gridfs (mongoc_client_t *client, - const char *db, - const char *prefix, - bson_error_t *error) -{ - BSON_ASSERT (client); - BSON_ASSERT (db); - - if (!prefix) { - prefix = "fs"; - } - - return _mongoc_gridfs_new (client, db, prefix, error); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_get_write_concern -- - * - * Fetches the default write concern for @client. - * - * Returns: - * A mongoc_write_concern_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_write_concern_t * -mongoc_client_get_write_concern (const mongoc_client_t *client) -{ - BSON_ASSERT (client); - - return client->write_concern; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_set_write_concern -- - * - * Sets the default write concern for @client. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_client_set_write_concern (mongoc_client_t *client, - const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (client); - - if (write_concern != client->write_concern) { - if (client->write_concern) { - mongoc_write_concern_destroy (client->write_concern); - } - client->write_concern = write_concern - ? mongoc_write_concern_copy (write_concern) - : mongoc_write_concern_new (); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_get_read_concern -- - * - * Fetches the default read concern for @client. - * - * Returns: - * A mongoc_read_concern_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_read_concern_t * -mongoc_client_get_read_concern (const mongoc_client_t *client) -{ - BSON_ASSERT (client); - - return client->read_concern; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_set_read_concern -- - * - * Sets the default read concern for @client. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_client_set_read_concern (mongoc_client_t *client, - const mongoc_read_concern_t *read_concern) -{ - BSON_ASSERT (client); - - if (read_concern != client->read_concern) { - if (client->read_concern) { - mongoc_read_concern_destroy (client->read_concern); - } - client->read_concern = read_concern - ? mongoc_read_concern_copy (read_concern) - : mongoc_read_concern_new (); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_get_read_prefs -- - * - * Fetch the default read preferences for @client. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_read_prefs_t * -mongoc_client_get_read_prefs (const mongoc_client_t *client) -{ - BSON_ASSERT (client); - - return client->read_prefs; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_set_read_prefs -- - * - * Set the default read preferences for @client. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_client_set_read_prefs (mongoc_client_t *client, - const mongoc_read_prefs_t *read_prefs) -{ - BSON_ASSERT (client); - - if (read_prefs != client->read_prefs) { - if (client->read_prefs) { - mongoc_read_prefs_destroy (client->read_prefs); - } - client->read_prefs = read_prefs - ? mongoc_read_prefs_copy (read_prefs) - : mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - } -} - -mongoc_cursor_t * -mongoc_client_command (mongoc_client_t *client, - const char *db_name, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *query, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs) -{ - char ns[MONGOC_NAMESPACE_MAX]; - mongoc_cursor_t *cursor; - - BSON_ASSERT (client); - BSON_ASSERT (db_name); - BSON_ASSERT (query); - - /* - * Allow a caller to provide a fully qualified namespace - */ - if (NULL == strstr (db_name, "$cmd")) { - bson_snprintf (ns, sizeof ns, "%s.$cmd", db_name); - db_name = ns; - } - - cursor = - _mongoc_cursor_cmd_deprecated_new (client, db_name, query, read_prefs); - - return cursor; -} - - -static bool -_mongoc_client_retryable_write_command_with_stream ( - mongoc_client_t *client, - mongoc_cmd_parts_t *parts, - mongoc_server_stream_t *server_stream, - bson_t *reply, - bson_error_t *error) -{ - mongoc_server_stream_t *retry_server_stream = NULL; - bson_iter_t txn_number_iter; - bool is_retryable = true; - bool ret; - - ENTRY; - - BSON_ASSERT (parts->is_retryable_write); - - /* increment the transaction number for the first attempt of each retryable - * write command */ - BSON_ASSERT (bson_iter_init_find ( - &txn_number_iter, parts->assembled.command, "txnNumber")); - bson_iter_overwrite_int64 ( - &txn_number_iter, ++parts->assembled.session->server_session->txn_number); - -retry: - ret = mongoc_cluster_run_command_monitored ( - &client->cluster, &parts->assembled, reply, error); - - if (is_retryable) { - _mongoc_write_error_update_if_unsupported_storage_engine ( - ret, error, reply); - } - - /* If a retryable error is encountered and the write is retryable, select - * a new writable stream and retry. If server selection fails or the selected - * server does not support retryable writes, fall through and allow the - * original error to be reported. */ - if (is_retryable && - _mongoc_write_error_get_type (ret, error, reply) == - MONGOC_WRITE_ERR_RETRY) { - bson_error_t ignored_error; - - /* each write command may be retried at most once */ - is_retryable = false; - - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } - - retry_server_stream = mongoc_cluster_stream_for_writes ( - &client->cluster, parts->assembled.session, NULL, &ignored_error); - - if (retry_server_stream && - retry_server_stream->sd->max_wire_version >= - WIRE_VERSION_RETRY_WRITES) { - parts->assembled.server_stream = retry_server_stream; - bson_destroy (reply); - GOTO (retry); - } - } - - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } - - if (ret && error) { - /* if a retry succeeded, clear the initial error */ - memset (error, 0, sizeof (bson_error_t)); - } - - RETURN (ret); -} - - -static bool -_mongoc_client_retryable_read_command_with_stream ( - mongoc_client_t *client, - mongoc_cmd_parts_t *parts, - mongoc_server_stream_t *server_stream, - bson_t *reply, - bson_error_t *error) -{ - mongoc_server_stream_t *retry_server_stream = NULL; - bool is_retryable = true; - bool ret; - bson_t reply_local; - - if (reply == NULL) { - reply = &reply_local; - } - - ENTRY; - - BSON_ASSERT (parts->is_retryable_read); - -retry: - ret = mongoc_cluster_run_command_monitored ( - &client->cluster, &parts->assembled, reply, error); - - /* If a retryable error is encountered and the read is retryable, select - * a new readable stream and retry. If server selection fails or the selected - * server does not support retryable reads, fall through and allow the - * original error to be reported. */ - if (is_retryable && - _mongoc_read_error_get_type (ret, error, reply) == - MONGOC_READ_ERR_RETRY) { - bson_error_t ignored_error; - - /* each read command may be retried at most once */ - is_retryable = false; - - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } - - retry_server_stream = - mongoc_cluster_stream_for_reads (&client->cluster, - parts->read_prefs, - parts->assembled.session, - NULL, - &ignored_error); - - if (retry_server_stream && - retry_server_stream->sd->max_wire_version >= - WIRE_VERSION_RETRY_READS) { - parts->assembled.server_stream = retry_server_stream; - bson_destroy (reply); - GOTO (retry); - } - } - - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } - - if (ret && error) { - /* if a retry succeeded, clear the initial error */ - memset (error, 0, sizeof (bson_error_t)); - } - - RETURN (ret); -} - - -static bool -_mongoc_client_command_with_stream (mongoc_client_t *client, - mongoc_cmd_parts_t *parts, - const mongoc_read_prefs_t *read_prefs, - mongoc_server_stream_t *server_stream, - bson_t *reply, - bson_error_t *error) -{ - ENTRY; - - parts->assembled.operation_id = ++client->cluster.operation_id; - if (!mongoc_cmd_parts_assemble (parts, server_stream, error)) { - _mongoc_bson_init_if_set (reply); - return false; - }; - - if (parts->is_retryable_write) { - RETURN (_mongoc_client_retryable_write_command_with_stream ( - client, parts, server_stream, reply, error)); - } - - if (parts->is_retryable_read) { - RETURN (_mongoc_client_retryable_read_command_with_stream ( - client, parts, server_stream, reply, error)); - } - - RETURN (mongoc_cluster_run_command_monitored ( - &client->cluster, &parts->assembled, reply, error)); -} - - -bool -mongoc_client_command_simple (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error) -{ - mongoc_cluster_t *cluster; - mongoc_server_stream_t *server_stream = NULL; - mongoc_cmd_parts_t parts; - bool ret; - - ENTRY; - - BSON_ASSERT (client); - BSON_ASSERT (db_name); - BSON_ASSERT (command); - - if (!_mongoc_read_prefs_validate (read_prefs, error)) { - RETURN (false); - } - - cluster = &client->cluster; - mongoc_cmd_parts_init (&parts, client, db_name, MONGOC_QUERY_NONE, command); - parts.read_prefs = read_prefs; - - /* Server Selection Spec: "The generic command method has a default read - * preference of mode 'primary'. The generic command method MUST ignore any - * default read preference from client, database or collection - * configuration. The generic command method SHOULD allow an optional read - * preference argument." - */ - server_stream = - mongoc_cluster_stream_for_reads (cluster, read_prefs, NULL, reply, error); - - if (server_stream) { - ret = _mongoc_client_command_with_stream ( - client, &parts, read_prefs, server_stream, reply, error); - } else { - /* reply initialized by mongoc_cluster_stream_for_reads */ - ret = false; - } - - mongoc_cmd_parts_cleanup (&parts); - mongoc_server_stream_cleanup (server_stream); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_command_with_opts -- - * - * Execute a command on the server. If mode is MONGOC_CMD_READ or - * MONGOC_CMD_RW, then read concern is applied from @opts, or else from - * @default_rc, and read preferences are applied from @user_prefs, or else - * from @default_prefs. If mode is MONGOC_CMD_WRITE or MONGOC_CMD_RW, then - * write concern is applied from @opts if present, or else @default_wc. - * - * If mode is MONGOC_CMD_RAW, then read concern and write concern are - * applied from @opts only. Read preferences are applied from - * @user_prefs. - * - * The mongoc_client_t's read preference, read concern, and write concern - * are *NOT* applied. - * - * Returns: - * Success or failure. - * A write concern timeout or write concern error is considered a failure. - * - * Side effects: - * @reply is always initialized. - * @error is filled out if the command fails. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_client_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - mongoc_command_mode_t mode, - const bson_t *opts, - mongoc_query_flags_t flags, - const mongoc_read_prefs_t *user_prefs, - const mongoc_read_prefs_t *default_prefs, - mongoc_read_concern_t *default_rc, - mongoc_write_concern_t *default_wc, - bson_t *reply, - bson_error_t *error) -{ - mongoc_read_write_opts_t read_write_opts; - mongoc_cmd_parts_t parts; - const char *command_name; - const mongoc_read_prefs_t *prefs = COALESCE (user_prefs, default_prefs); - mongoc_server_stream_t *server_stream = NULL; - mongoc_cluster_t *cluster; - mongoc_client_session_t *cs; - bson_t reply_local; - bson_t *reply_ptr; - int32_t wire_version; - int32_t wc_wire_version; - bool reply_initialized = false; - bool ret = false; - - ENTRY; - - BSON_ASSERT (client); - BSON_ASSERT (db_name); - BSON_ASSERT (command); - - command_name = _mongoc_get_command_name (command); - cluster = &client->cluster; - reply_ptr = reply ? reply : &reply_local; - - mongoc_cmd_parts_init (&parts, client, db_name, flags, command); - parts.is_read_command = (mode & MONGOC_CMD_READ); - parts.is_write_command = (mode & MONGOC_CMD_WRITE); - - if (!_mongoc_read_write_opts_parse (client, opts, &read_write_opts, error)) { - GOTO (done); - } - - cs = read_write_opts.client_session; - - if (!command_name) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Empty command document"); - GOTO (done); - } - - if (_mongoc_client_session_in_txn (read_write_opts.client_session)) { - if ((mode == MONGOC_CMD_READ || mode == MONGOC_CMD_RAW) && - !IS_PREF_PRIMARY (user_prefs)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Read preference in a transaction must be primary"); - GOTO (done); - } - - if (!bson_empty (&read_write_opts.readConcern)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set read concern after starting transaction"); - GOTO (done); - } - - if (read_write_opts.writeConcern && - strcmp (command_name, "commitTransaction") != 0 && - strcmp (command_name, "abortTransaction") != 0) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set write concern after starting transaction"); - GOTO (done); - } - } - - if (mode == MONGOC_CMD_READ || mode == MONGOC_CMD_RAW) { - /* NULL read pref is ok */ - if (!_mongoc_read_prefs_validate (prefs, error)) { - GOTO (done); - } - - parts.read_prefs = prefs; - } else { - /* this is a command that writes */ - prefs = NULL; - } - - if (read_write_opts.serverId) { - /* "serverId" passed in opts */ - server_stream = - mongoc_cluster_stream_for_server (cluster, - read_write_opts.serverId, - true /* reconnect ok */, - cs, - reply_ptr, - error); - - if (server_stream && server_stream->sd->type != MONGOC_SERVER_MONGOS) { - parts.user_query_flags |= MONGOC_QUERY_SLAVE_OK; - } - } else if (parts.is_write_command) { - server_stream = - mongoc_cluster_stream_for_writes (cluster, cs, reply_ptr, error); - } else { - server_stream = - mongoc_cluster_stream_for_reads (cluster, prefs, cs, reply_ptr, error); - } - - if (!server_stream) { - /* stream_for_reads/writes/server has initialized reply */ - reply_initialized = true; - GOTO (done); - } - - wire_version = server_stream->sd->max_wire_version; - if (!mongoc_cmd_parts_append_read_write ( - &parts, &read_write_opts, wire_version, error)) { - GOTO (done); - } - - if (mode & MONGOC_CMD_WRITE) { - wc_wire_version = !strcasecmp (command_name, "findandmodify") - ? WIRE_VERSION_FAM_WRITE_CONCERN - : WIRE_VERSION_CMD_WRITE_CONCERN; - - if (read_write_opts.write_concern_owned && - wire_version < wc_wire_version) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "\"%s\" command does not support writeConcern with " - "wire version %d, wire version %d is required", - command_name, - wire_version, - wc_wire_version); - GOTO (done); - } - - /* use default write concern unless it's in opts */ - if (!mongoc_write_concern_is_default (default_wc) && - !read_write_opts.write_concern_owned && - wire_version >= wc_wire_version) { - if (!mongoc_cmd_parts_set_write_concern ( - &parts, default_wc, wire_version, error)) { - GOTO (done); - } - } - } - - /* use default read concern for read command, unless it's in opts */ - if ((mode & MONGOC_CMD_READ) && bson_empty (&read_write_opts.readConcern)) { - if (!mongoc_cmd_parts_set_read_concern ( - &parts, default_rc, wire_version, error)) { - GOTO (done); - } - } - - ret = _mongoc_client_command_with_stream ( - client, &parts, user_prefs, server_stream, reply_ptr, error); - - reply_initialized = true; - - if (ret && (mode & MONGOC_CMD_WRITE)) { - ret = !_mongoc_parse_wc_err (reply_ptr, error); - } - -done: - if (reply_ptr == &reply_local) { - if (reply_initialized) { - bson_destroy (reply_ptr); - } - } else if (!reply_initialized) { - _mongoc_bson_init_if_set (reply); - } - - if (server_stream) { - mongoc_server_stream_cleanup (server_stream); - } - - mongoc_cmd_parts_cleanup (&parts); - _mongoc_read_write_opts_cleanup (&read_write_opts); - - RETURN (ret); -} - - -bool -mongoc_client_read_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_client_command_with_opts (client, - db_name, - command, - MONGOC_CMD_READ, - opts, - MONGOC_QUERY_NONE, - read_prefs, - client->read_prefs, - client->read_concern, - client->write_concern, - reply, - error); -} - - -bool -mongoc_client_write_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_client_command_with_opts (client, - db_name, - command, - MONGOC_CMD_WRITE, - opts, - MONGOC_QUERY_NONE, - NULL, - client->read_prefs, - client->read_concern, - client->write_concern, - reply, - error); -} - - -bool -mongoc_client_read_write_command_with_opts ( - mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* IGNORED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_client_command_with_opts (client, - db_name, - command, - MONGOC_CMD_RW, - opts, - MONGOC_QUERY_NONE, - read_prefs, - client->read_prefs, - client->read_concern, - client->write_concern, - reply, - error); -} - - -bool -mongoc_client_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_client_command_with_opts (client, - db_name, - command, - MONGOC_CMD_RAW, - opts, - MONGOC_QUERY_NONE, - read_prefs, - NULL, - client->read_concern, - client->write_concern, - reply, - error); -} - - -bool -mongoc_client_command_simple_with_server_id ( - mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - uint32_t server_id, - bson_t *reply, - bson_error_t *error) -{ - mongoc_server_stream_t *server_stream; - mongoc_cmd_parts_t parts; - bool ret; - - ENTRY; - - BSON_ASSERT (client); - BSON_ASSERT (db_name); - BSON_ASSERT (command); - - if (!_mongoc_read_prefs_validate (read_prefs, error)) { - RETURN (false); - } - - server_stream = mongoc_cluster_stream_for_server ( - &client->cluster, server_id, true /* reconnect ok */, NULL, reply, error); - - if (server_stream) { - mongoc_cmd_parts_init ( - &parts, client, db_name, MONGOC_QUERY_NONE, command); - parts.read_prefs = read_prefs; - - ret = _mongoc_client_command_with_stream ( - client, &parts, read_prefs, server_stream, reply, error); - - mongoc_cmd_parts_cleanup (&parts); - mongoc_server_stream_cleanup (server_stream); - RETURN (ret); - } else { - /* stream_for_server initialized reply */ - RETURN (false); - } -} - - -static void -_mongoc_client_prepare_killcursors_command (int64_t cursor_id, - const char *collection, - bson_t *command) -{ - bson_t child; - - bson_append_utf8 (command, "killCursors", 11, collection, -1); - bson_append_array_begin (command, "cursors", 7, &child); - bson_append_int64 (&child, "0", 1, cursor_id); - bson_append_array_end (command, &child); -} - - -void -_mongoc_client_kill_cursor (mongoc_client_t *client, - uint32_t server_id, - int64_t cursor_id, - int64_t operation_id, - const char *db, - const char *collection, - mongoc_client_session_t *cs) -{ - mongoc_server_stream_t *server_stream; - - ENTRY; - - BSON_ASSERT (client); - BSON_ASSERT (cursor_id); - - /* don't attempt reconnect if server unavailable, and ignore errors */ - server_stream = mongoc_cluster_stream_for_server ( - &client->cluster, server_id, false /* reconnect_ok */, NULL, NULL, NULL); - - if (!server_stream) { - return; - } - - if (db && collection && - server_stream->sd->max_wire_version >= WIRE_VERSION_KILLCURSORS_CMD) { - _mongoc_client_killcursors_command ( - &client->cluster, server_stream, cursor_id, db, collection, cs); - } else { - _mongoc_client_op_killcursors (&client->cluster, - server_stream, - cursor_id, - operation_id, - db, - collection); - } - - mongoc_server_stream_cleanup (server_stream); - - EXIT; -} - - -static void -_mongoc_client_monitor_op_killcursors (mongoc_cluster_t *cluster, - mongoc_server_stream_t *server_stream, - int64_t cursor_id, - int64_t operation_id, - const char *db, - const char *collection) -{ - bson_t doc; - mongoc_client_t *client; - mongoc_apm_command_started_t event; - - ENTRY; - - client = cluster->client; - - if (!client->apm_callbacks.started) { - return; - } - - bson_init (&doc); - _mongoc_client_prepare_killcursors_command (cursor_id, collection, &doc); - mongoc_apm_command_started_init (&event, - &doc, - db, - "killCursors", - cluster->request_id, - operation_id, - &server_stream->sd->host, - server_stream->sd->id, - client->apm_context); - - client->apm_callbacks.started (&event); - mongoc_apm_command_started_cleanup (&event); - bson_destroy (&doc); - - EXIT; -} - - -static void -_mongoc_client_monitor_op_killcursors_succeeded ( - mongoc_cluster_t *cluster, - int64_t duration, - mongoc_server_stream_t *server_stream, - int64_t cursor_id, - int64_t operation_id) -{ - mongoc_client_t *client; - bson_t doc; - bson_t cursors_unknown; - mongoc_apm_command_succeeded_t event; - - ENTRY; - - client = cluster->client; - - if (!client->apm_callbacks.succeeded) { - EXIT; - } - - /* fake server reply to killCursors command: {ok: 1, cursorsUnknown: [42]} */ - bson_init (&doc); - bson_append_int32 (&doc, "ok", 2, 1); - bson_append_array_begin (&doc, "cursorsUnknown", 14, &cursors_unknown); - bson_append_int64 (&cursors_unknown, "0", 1, cursor_id); - bson_append_array_end (&doc, &cursors_unknown); - - mongoc_apm_command_succeeded_init (&event, - duration, - &doc, - "killCursors", - cluster->request_id, - operation_id, - &server_stream->sd->host, - server_stream->sd->id, - client->apm_context); - - client->apm_callbacks.succeeded (&event); - - mongoc_apm_command_succeeded_cleanup (&event); - bson_destroy (&doc); -} - - -static void -_mongoc_client_monitor_op_killcursors_failed ( - mongoc_cluster_t *cluster, - int64_t duration, - mongoc_server_stream_t *server_stream, - const bson_error_t *error, - int64_t operation_id) -{ - mongoc_client_t *client; - bson_t doc; - mongoc_apm_command_failed_t event; - - ENTRY; - - client = cluster->client; - - if (!client->apm_callbacks.failed) { - EXIT; - } - - /* fake server reply to killCursors command: {ok: 0} */ - bson_init (&doc); - bson_append_int32 (&doc, "ok", 2, 0); - - mongoc_apm_command_failed_init (&event, - duration, - "killCursors", - error, - &doc, - cluster->request_id, - operation_id, - &server_stream->sd->host, - server_stream->sd->id, - client->apm_context); - - client->apm_callbacks.failed (&event); - - mongoc_apm_command_failed_cleanup (&event); - bson_destroy (&doc); -} - - -static void -_mongoc_client_op_killcursors (mongoc_cluster_t *cluster, - mongoc_server_stream_t *server_stream, - int64_t cursor_id, - int64_t operation_id, - const char *db, - const char *collection) -{ - int64_t started; - mongoc_rpc_t rpc = {{0}}; - bson_error_t error; - bool has_ns; - bool r; - - /* called by old mongoc_client_kill_cursor without db/collection? */ - has_ns = (db && collection); - started = bson_get_monotonic_time (); - - ++cluster->request_id; - - rpc.header.msg_len = 0; - rpc.header.request_id = cluster->request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_KILL_CURSORS; - rpc.kill_cursors.zero = 0; - rpc.kill_cursors.cursors = &cursor_id; - rpc.kill_cursors.n_cursors = 1; - - if (has_ns) { - _mongoc_client_monitor_op_killcursors ( - cluster, server_stream, cursor_id, operation_id, db, collection); - } - - r = mongoc_cluster_legacy_rpc_sendv_to_server ( - cluster, &rpc, server_stream, &error); - - if (has_ns) { - if (r) { - _mongoc_client_monitor_op_killcursors_succeeded ( - cluster, - bson_get_monotonic_time () - started, - server_stream, - cursor_id, - operation_id); - } else { - _mongoc_client_monitor_op_killcursors_failed ( - cluster, - bson_get_monotonic_time () - started, - server_stream, - &error, - operation_id); - } - } -} - - -static void -_mongoc_client_killcursors_command (mongoc_cluster_t *cluster, - mongoc_server_stream_t *server_stream, - int64_t cursor_id, - const char *db, - const char *collection, - mongoc_client_session_t *cs) -{ - bson_t command = BSON_INITIALIZER; - mongoc_cmd_parts_t parts; - - ENTRY; - - _mongoc_client_prepare_killcursors_command (cursor_id, collection, &command); - mongoc_cmd_parts_init ( - &parts, cluster->client, db, MONGOC_QUERY_SLAVE_OK, &command); - parts.assembled.operation_id = ++cluster->operation_id; - mongoc_cmd_parts_set_session (&parts, cs); - - if (mongoc_cmd_parts_assemble (&parts, server_stream, NULL)) { - /* Find, getMore And killCursors Commands Spec: "The result from the - * killCursors command MAY be safely ignored." - */ - (void) mongoc_cluster_run_command_monitored ( - cluster, &parts.assembled, NULL, NULL); - } - - mongoc_cmd_parts_cleanup (&parts); - bson_destroy (&command); - - EXIT; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_kill_cursor -- - * - * Destroy a cursor on the server. - * - * NOTE: this is only reliable when connected to a single mongod or - * mongos. If connected to a replica set, the driver attempts to - * kill the cursor on the primary. If connected to multiple mongoses - * the kill-cursors message is sent to a *random* mongos. - * - * If no primary, mongos, or standalone server is known, return - * without attempting to reconnect. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id) -{ - mongoc_topology_t *topology; - mongoc_server_description_t *selected_server; - mongoc_read_prefs_t *read_prefs; - bson_error_t error; - uint32_t server_id = 0; - - topology = client->topology; - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - bson_mutex_lock (&topology->mutex); - if (!mongoc_topology_compatible (&topology->description, NULL, &error)) { - MONGOC_ERROR ("Could not kill cursor: %s", error.message); - bson_mutex_unlock (&topology->mutex); - mongoc_read_prefs_destroy (read_prefs); - return; - } - - /* see if there's a known writable server - do no I/O or retries */ - selected_server = - mongoc_topology_description_select (&topology->description, - MONGOC_SS_WRITE, - read_prefs, - topology->local_threshold_msec); - - if (selected_server) { - server_id = selected_server->id; - } - - bson_mutex_unlock (&topology->mutex); - - if (server_id) { - _mongoc_client_kill_cursor (client, - server_id, - cursor_id, - 0 /* operation_id */, - NULL /* db */, - NULL /* collection */, - NULL /* session */); - } else { - MONGOC_INFO ("No server available for mongoc_client_kill_cursor"); - } - - mongoc_read_prefs_destroy (read_prefs); -} - - -char ** -mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error) -{ - return mongoc_client_get_database_names_with_opts (client, NULL, error); -} - - -char ** -mongoc_client_get_database_names_with_opts (mongoc_client_t *client, - const bson_t *opts, - bson_error_t *error) -{ - bson_iter_t iter; - const char *name; - char **ret = NULL; - int i = 0; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t cmd = BSON_INITIALIZER; - - BSON_ASSERT (client); - BSON_APPEND_INT32 (&cmd, "listDatabases", 1); - BSON_APPEND_BOOL (&cmd, "nameOnly", true); - - /* ignore client read prefs */ - cursor = _mongoc_cursor_array_new (client, "admin", &cmd, opts, "databases"); - bson_destroy (&cmd); - - while (mongoc_cursor_next (cursor, &doc)) { - if (bson_iter_init (&iter, doc) && bson_iter_find (&iter, "name") && - BSON_ITER_HOLDS_UTF8 (&iter) && - (name = bson_iter_utf8 (&iter, NULL))) { - ret = (char **) bson_realloc (ret, sizeof (char *) * (i + 2)); - ret[i] = bson_strdup (name); - ret[++i] = NULL; - } - } - - if (!ret && !mongoc_cursor_error (cursor, error)) { - ret = (char **) bson_malloc0 (sizeof (void *)); - } - - mongoc_cursor_destroy (cursor); - - return ret; -} - - -mongoc_cursor_t * -mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error) -{ - /* existing bug in this deprecated API: error pointer is unused */ - return mongoc_client_find_databases_with_opts (client, NULL); -} - - -mongoc_cursor_t * -mongoc_client_find_databases_with_opts (mongoc_client_t *client, - const bson_t *opts) -{ - bson_t cmd = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - - BSON_ASSERT (client); - BSON_APPEND_INT32 (&cmd, "listDatabases", 1); - cursor = _mongoc_cursor_array_new (client, "admin", &cmd, opts, "databases"); - bson_destroy (&cmd); - return cursor; -} - - -int32_t -mongoc_client_get_max_message_size (mongoc_client_t *client) /* IN */ -{ - BSON_ASSERT (client); - - return mongoc_cluster_get_max_msg_size (&client->cluster); -} - - -int32_t -mongoc_client_get_max_bson_size (mongoc_client_t *client) /* IN */ -{ - BSON_ASSERT (client); - - return mongoc_cluster_get_max_bson_obj_size (&client->cluster); -} - - -bool -mongoc_client_get_server_status (mongoc_client_t *client, /* IN */ - mongoc_read_prefs_t *read_prefs, /* IN */ - bson_t *reply, /* OUT */ - bson_error_t *error) /* OUT */ -{ - bson_t cmd = BSON_INITIALIZER; - bool ret = false; - - BSON_ASSERT (client); - - BSON_APPEND_INT32 (&cmd, "serverStatus", 1); - ret = mongoc_client_command_simple ( - client, "admin", &cmd, read_prefs, reply, error); - bson_destroy (&cmd); - - return ret; -} - - -void -mongoc_client_set_stream_initiator (mongoc_client_t *client, - mongoc_stream_initiator_t initiator, - void *user_data) -{ - BSON_ASSERT (client); - - if (!initiator) { - initiator = mongoc_client_default_stream_initiator; - user_data = client; - } else { - MONGOC_DEBUG ("Using custom stream initiator."); - } - - client->initiator = initiator; - client->initiator_data = user_data; - - if (client->topology->single_threaded) { - mongoc_topology_scanner_set_stream_initiator ( - client->topology->scanner, initiator, user_data); - } -} - - -bool -_mongoc_client_set_apm_callbacks_private (mongoc_client_t *client, - mongoc_apm_callbacks_t *callbacks, - void *context) -{ - if (callbacks) { - memcpy ( - &client->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t)); - } else { - memset (&client->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t)); - } - - client->apm_context = context; - mongoc_topology_set_apm_callbacks (client->topology, callbacks, context); - - return true; -} - - -bool -mongoc_client_set_apm_callbacks (mongoc_client_t *client, - mongoc_apm_callbacks_t *callbacks, - void *context) -{ - if (!client->topology->single_threaded) { - MONGOC_ERROR ("Cannot set callbacks on a pooled client, use " - "mongoc_client_pool_set_apm_callbacks"); - return false; - } - - return _mongoc_client_set_apm_callbacks_private (client, callbacks, context); -} - - -mongoc_server_description_t * -mongoc_client_get_server_description (mongoc_client_t *client, - uint32_t server_id) -{ - /* the error info isn't useful */ - return mongoc_topology_server_by_id (client->topology, server_id, NULL); -} - - -mongoc_server_description_t ** -mongoc_client_get_server_descriptions (const mongoc_client_t *client, - size_t *n /* OUT */) -{ - mongoc_topology_t *topology; - mongoc_server_description_t **sds; - - BSON_ASSERT (client); - BSON_ASSERT (n); - - topology = client->topology; - - /* in case the client is pooled */ - bson_mutex_lock (&topology->mutex); - - sds = mongoc_topology_description_get_servers (&topology->description, n); - - bson_mutex_unlock (&topology->mutex); - - return sds; -} - - -void -mongoc_server_descriptions_destroy_all (mongoc_server_description_t **sds, - size_t n) -{ - size_t i; - - for (i = 0; i < n; ++i) { - mongoc_server_description_destroy (sds[i]); - } - - bson_free (sds); -} - - -mongoc_server_description_t * -mongoc_client_select_server (mongoc_client_t *client, - bool for_writes, - const mongoc_read_prefs_t *prefs, - bson_error_t *error) -{ - mongoc_ss_optype_t optype = for_writes ? MONGOC_SS_WRITE : MONGOC_SS_READ; - mongoc_server_description_t *sd; - - if (for_writes && prefs) { - bson_set_error (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "Cannot use read preferences with for_writes = true"); - return NULL; - } - - if (!_mongoc_read_prefs_validate (prefs, error)) { - return NULL; - } - - sd = mongoc_topology_select (client->topology, optype, prefs, error); - if (!sd) { - return NULL; - } - - if (mongoc_cluster_check_interval (&client->cluster, sd->id)) { - /* check not required, or it succeeded */ - return sd; - } - - /* check failed, retry once */ - mongoc_server_description_destroy (sd); - sd = mongoc_topology_select (client->topology, optype, prefs, error); - if (sd) { - return sd; - } - - return NULL; -} - -bool -mongoc_client_set_error_api (mongoc_client_t *client, int32_t version) -{ - if (!client->topology->single_threaded) { - MONGOC_ERROR ("Cannot set Error API Version on a pooled client, use " - "mongoc_client_pool_set_error_api"); - return false; - } - - if (version != MONGOC_ERROR_API_VERSION_LEGACY && - version != MONGOC_ERROR_API_VERSION_2) { - MONGOC_ERROR ("Unsupported Error API Version: %" PRId32, version); - return false; - } - - if (client->error_api_set) { - MONGOC_ERROR ("Can only set Error API Version once"); - return false; - } - - client->error_api_version = version; - client->error_api_set = true; - - return true; -} - -bool -mongoc_client_set_appname (mongoc_client_t *client, const char *appname) -{ - if (!client->topology->single_threaded) { - MONGOC_ERROR ("Cannot call set_appname on a client from a pool"); - return false; - } - - return _mongoc_topology_set_appname (client->topology, appname); -} - -mongoc_server_session_t * -_mongoc_client_pop_server_session (mongoc_client_t *client, bson_error_t *error) -{ - return _mongoc_topology_pop_server_session (client->topology, error); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_client_lookup_session -- - * - * Retrieve a mongoc_client_session_t associated with @client_session_id. - * Use this to find the "lsid" and "$clusterTime" to send in the server - * command. - * - * Returns: - * True on success, false on error and @error is set. Will return false - * if the session is from an outdated client generation, a holdover - * from before a call to mongoc_client_reset. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_client_lookup_session (const mongoc_client_t *client, - uint32_t client_session_id, - mongoc_client_session_t **cs /* OUT */, - bson_error_t *error /* OUT */) -{ - ENTRY; - - *cs = mongoc_set_get (client->client_sessions, client_session_id); - - if (*cs) { - RETURN (true); - } - - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid sessionId"); - - RETURN (false); -} - -void -_mongoc_client_unregister_session (mongoc_client_t *client, - mongoc_client_session_t *session) -{ - mongoc_set_rm (client->client_sessions, session->client_session_id); -} - -void -_mongoc_client_push_server_session (mongoc_client_t *client, - mongoc_server_session_t *server_session) -{ - _mongoc_topology_push_server_session (client->topology, server_session); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_client_end_sessions -- - * - * End all server sessions in the topology's server session pool. - * Don't block long: if server selection or connecting fails, quit. - * - * The server session pool becomes invalid, but may not be empty. - * Destroy the topology after this without using any sessions. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_client_end_sessions (mongoc_client_t *client) -{ - mongoc_topology_t *t = client->topology; - mongoc_read_prefs_t *prefs; - bson_error_t error; - uint32_t server_id; - bson_t cmd; - mongoc_server_stream_t *stream; - mongoc_cmd_parts_t parts; - mongoc_cluster_t *cluster = &client->cluster; - bool r; - - if (t->session_pool) { - prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED); - server_id = - mongoc_topology_select_server_id (t, MONGOC_SS_READ, prefs, &error); - - mongoc_read_prefs_destroy (prefs); - if (!server_id) { - MONGOC_WARNING ("Couldn't send \"endSessions\": %s", error.message); - return; - } - - stream = mongoc_cluster_stream_for_server ( - cluster, server_id, false /* reconnect_ok */, NULL, NULL, &error); - - if (!stream) { - MONGOC_WARNING ("Couldn't send \"endSessions\": %s", error.message); - return; - } - - /* end sessions in chunks */ - while (_mongoc_topology_end_sessions_cmd (t, &cmd)) { - mongoc_cmd_parts_init ( - &parts, client, "admin", MONGOC_QUERY_SLAVE_OK, &cmd); - parts.assembled.operation_id = ++cluster->operation_id; - parts.prohibit_lsid = true; - - r = mongoc_cmd_parts_assemble (&parts, stream, &error); - if (!r) { - MONGOC_WARNING ("Couldn't construct \"endSessions\" command: %s", - error.message); - } else { - r = mongoc_cluster_run_command_monitored ( - cluster, &parts.assembled, NULL, &error); - - if (!r) { - MONGOC_WARNING ("Couldn't send \"endSessions\": %s", - error.message); - } - } - - bson_destroy (&cmd); - mongoc_cmd_parts_cleanup (&parts); - } - - bson_destroy (&cmd); - mongoc_server_stream_cleanup (stream); - } -} - -void -mongoc_client_reset (mongoc_client_t *client) -{ - BSON_ASSERT (client); - - client->generation++; - - /* Client sessions are owned and destroyed by the user, but we keep - local pointers to them for reference. On reset, clear our local - set without destroying the sessions or calling endSessions. - client_sessions has no dtor, so it won't destroy its items. - - Destroying the local cache of client sessions here ensures they - cannot be used by future operations--lookup for them will fail. */ - mongoc_set_destroy (client->client_sessions); - client->client_sessions = mongoc_set_new (8, NULL, NULL); - - /* Server sessions are owned by us, so we clear the pool on reset. */ - _mongoc_topology_clear_session_pool (client->topology); -} - -mongoc_change_stream_t * -mongoc_client_watch (mongoc_client_t *client, - const bson_t *pipeline, - const bson_t *opts) -{ - return _mongoc_change_stream_new_from_client (client, pipeline, opts); -} - -bool -mongoc_client_enable_auto_encryption (mongoc_client_t *client, - mongoc_auto_encryption_opts_t *opts, - bson_error_t *error) -{ - if (!client->topology->single_threaded) { - MONGOC_ERROR ("Cannot enable auto encryption on a pooled client, use " - "mongoc_client_pool_enable_auto_encryption"); - return false; - } - return _mongoc_cse_enable_auto_encryption (client, opts, error); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-client.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-client.h deleted file mode 100644 index b545e37c0525a918708feb4c4f0b78479fe9b9c1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-client.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLIENT_H -#define MONGOC_CLIENT_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-apm.h" -#include "mongoc/mongoc-client-side-encryption.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-database.h" -#include "mongoc/mongoc-gridfs.h" -#include "mongoc/mongoc-index.h" -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-read-prefs.h" -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-ssl.h" -#endif -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-uri.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-read-concern.h" -#include "mongoc/mongoc-server-description.h" - -BSON_BEGIN_DECLS - - -#define MONGOC_NAMESPACE_MAX 128 - - -#ifndef MONGOC_DEFAULT_CONNECTTIMEOUTMS -#define MONGOC_DEFAULT_CONNECTTIMEOUTMS (10 * 1000L) -#endif - - -#ifndef MONGOC_DEFAULT_SOCKETTIMEOUTMS -/* - * NOTE: The default socket timeout for connections is 5 minutes. This - * means that if your MongoDB server dies or becomes unavailable - * it will take 5 minutes to detect this. - * - * You can change this by providing sockettimeoutms= in your - * connection URI. - */ -#define MONGOC_DEFAULT_SOCKETTIMEOUTMS (1000L * 60L * 5L) -#endif - - -/** - * mongoc_client_t: - * - * The mongoc_client_t structure maintains information about a connection to - * a MongoDB server. - */ -typedef struct _mongoc_client_t mongoc_client_t; - - -typedef struct _mongoc_client_session_t mongoc_client_session_t; -typedef struct _mongoc_session_opt_t mongoc_session_opt_t; -typedef struct _mongoc_transaction_opt_t mongoc_transaction_opt_t; - -/** - * mongoc_stream_initiator_t: - * @uri: The uri and options for the stream. - * @host: The host and port (or UNIX domain socket path) to connect to. - * @user_data: The pointer passed to mongoc_client_set_stream_initiator. - * @error: A location for an error. - * - * Creates a new mongoc_stream_t for the host and port. Begin a - * non-blocking connect and return immediately. - * - * This can be used by language bindings to create network transports other - * than those built into libmongoc. An example of such would be the streams - * API provided by PHP. - * - * Returns: A newly allocated mongoc_stream_t or NULL on failure. - */ -typedef mongoc_stream_t *(*mongoc_stream_initiator_t) ( - const mongoc_uri_t *uri, - const mongoc_host_list_t *host, - void *user_data, - bson_error_t *error); - - -MONGOC_EXPORT (mongoc_client_t *) -mongoc_client_new (const char *uri_string); -MONGOC_EXPORT (mongoc_client_t *) -mongoc_client_new_from_uri (const mongoc_uri_t *uri); -MONGOC_EXPORT (const mongoc_uri_t *) -mongoc_client_get_uri (const mongoc_client_t *client); -MONGOC_EXPORT (void) -mongoc_client_set_stream_initiator (mongoc_client_t *client, - mongoc_stream_initiator_t initiator, - void *user_data); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_client_command (mongoc_client_t *client, - const char *db_name, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *query, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (void) -mongoc_client_kill_cursor (mongoc_client_t *client, - int64_t cursor_id) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (bool) -mongoc_client_command_simple (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_client_read_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_client_write_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_client_read_write_command_with_opts ( - mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* IGNORED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_client_command_with_opts (mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_client_command_simple_with_server_id ( - mongoc_client_t *client, - const char *db_name, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - uint32_t server_id, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (void) -mongoc_client_destroy (mongoc_client_t *client); -MONGOC_EXPORT (mongoc_client_session_t *) -mongoc_client_start_session (mongoc_client_t *client, - const mongoc_session_opt_t *opts, - bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (mongoc_database_t *) -mongoc_client_get_database (mongoc_client_t *client, const char *name); -MONGOC_EXPORT (mongoc_database_t *) -mongoc_client_get_default_database (mongoc_client_t *client); -MONGOC_EXPORT (mongoc_gridfs_t *) -mongoc_client_get_gridfs (mongoc_client_t *client, - const char *db, - const char *prefix, - bson_error_t *error); -MONGOC_EXPORT (mongoc_collection_t *) -mongoc_client_get_collection (mongoc_client_t *client, - const char *db, - const char *collection); -MONGOC_EXPORT (char **) -mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_client_get_database_names_with_opts); -MONGOC_EXPORT (char **) -mongoc_client_get_database_names_with_opts (mongoc_client_t *client, - const bson_t *opts, - bson_error_t *error); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_client_find_databases_with_opts); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_client_find_databases_with_opts (mongoc_client_t *client, - const bson_t *opts); -MONGOC_EXPORT (bool) -mongoc_client_get_server_status (mongoc_client_t *client, - mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (int32_t) -mongoc_client_get_max_message_size (mongoc_client_t *client) - BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (int32_t) -mongoc_client_get_max_bson_size (mongoc_client_t *client) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (const mongoc_write_concern_t *) -mongoc_client_get_write_concern (const mongoc_client_t *client); -MONGOC_EXPORT (void) -mongoc_client_set_write_concern (mongoc_client_t *client, - const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (const mongoc_read_concern_t *) -mongoc_client_get_read_concern (const mongoc_client_t *client); -MONGOC_EXPORT (void) -mongoc_client_set_read_concern (mongoc_client_t *client, - const mongoc_read_concern_t *read_concern); -MONGOC_EXPORT (const mongoc_read_prefs_t *) -mongoc_client_get_read_prefs (const mongoc_client_t *client); -MONGOC_EXPORT (void) -mongoc_client_set_read_prefs (mongoc_client_t *client, - const mongoc_read_prefs_t *read_prefs); -#ifdef MONGOC_ENABLE_SSL -MONGOC_EXPORT (void) -mongoc_client_set_ssl_opts (mongoc_client_t *client, - const mongoc_ssl_opt_t *opts); -#endif -MONGOC_EXPORT (bool) -mongoc_client_set_apm_callbacks (mongoc_client_t *client, - mongoc_apm_callbacks_t *callbacks, - void *context); -MONGOC_EXPORT (mongoc_server_description_t *) -mongoc_client_get_server_description (mongoc_client_t *client, - uint32_t server_id); -MONGOC_EXPORT (mongoc_server_description_t **) -mongoc_client_get_server_descriptions (const mongoc_client_t *client, - size_t *n); -MONGOC_EXPORT (void) -mongoc_server_descriptions_destroy_all (mongoc_server_description_t **sds, - size_t n); -MONGOC_EXPORT (mongoc_server_description_t *) -mongoc_client_select_server (mongoc_client_t *client, - bool for_writes, - const mongoc_read_prefs_t *prefs, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_client_set_error_api (mongoc_client_t *client, int32_t version); -MONGOC_EXPORT (bool) -mongoc_client_set_appname (mongoc_client_t *client, const char *appname); -MONGOC_EXPORT (mongoc_change_stream_t *) -mongoc_client_watch (mongoc_client_t *client, - const bson_t *pipeline, - const bson_t *opts); -MONGOC_EXPORT (void) -mongoc_client_reset (mongoc_client_t *client); - -MONGOC_EXPORT (bool) -mongoc_client_enable_auto_encryption (mongoc_client_t *client, - mongoc_auto_encryption_opts_t *opts, - bson_error_t *error); - -BSON_END_DECLS - - -#endif /* MONGOC_CLIENT_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h deleted file mode 100644 index 45574a9e47726a616d893a6c350b02e1cea8a178..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLUSTER_CYRUS_PRIVATE_H -#define MONGOC_CLUSTER_CYRUS_PRIVATE_H - -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-cluster-private.h" -#include <bson/bson.h> - -bool -_mongoc_cluster_auth_node_cyrus (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error); -#endif /* MONGOC_CLUSTER_CYRUS_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-cyrus.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-cyrus.c deleted file mode 100644 index d42bbcc4713c8853bd049435b2257dc3c7674cf2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-cyrus.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SASL_CYRUS -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-cyrus-private.h" -#include "mongoc/mongoc-cluster-cyrus-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-trace-private.h" - -bool -_mongoc_cluster_auth_node_cyrus (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error) -{ - mongoc_cmd_parts_t parts; - uint32_t buflen = 0; - mongoc_cyrus_t sasl; - bson_iter_t iter; - bool ret = false; - const char *tmpstr; - uint8_t buf[4096] = {0}; - bson_t cmd; - bson_t reply; - int conv_id = 0; - mongoc_server_stream_t *server_stream; - - BSON_ASSERT (cluster); - BSON_ASSERT (stream); - - if (!_mongoc_cyrus_new_from_cluster ( - &sasl, cluster, stream, sd->host.host, error)) { - return false; - } - - for (;;) { - mongoc_cmd_parts_init ( - &parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &cmd); - - if (!_mongoc_cyrus_step ( - &sasl, buf, buflen, buf, sizeof buf, &buflen, error)) { - goto failure; - } - - bson_init (&cmd); - - if (sasl.step == 1) { - _mongoc_cluster_build_sasl_start ( - &cmd, sasl.credentials.mechanism, (const char *) buf, buflen); - } else { - _mongoc_cluster_build_sasl_continue ( - &cmd, conv_id, (const char *) buf, buflen); - } - - TRACE ("SASL: authenticating (step %d)", sasl.step); - - server_stream = _mongoc_cluster_create_server_stream ( - cluster->client->topology, sd->id, stream, error); - - if (!mongoc_cmd_parts_assemble (&parts, server_stream, error)) { - mongoc_server_stream_cleanup (server_stream); - bson_destroy (&cmd); - goto failure; - } - - if (!mongoc_cluster_run_command_private ( - cluster, &parts.assembled, &reply, error)) { - mongoc_server_stream_cleanup (server_stream); - bson_destroy (&cmd); - bson_destroy (&reply); - goto failure; - } - mongoc_server_stream_cleanup (server_stream); - - bson_destroy (&cmd); - - if (bson_iter_init_find (&iter, &reply, "done") && - bson_iter_as_bool (&iter)) { - bson_destroy (&reply); - break; - } - - conv_id = _mongoc_cluster_get_conversation_id (&reply); - - if (!bson_iter_init_find (&iter, &reply, "payload") || - !BSON_ITER_HOLDS_UTF8 (&iter)) { - MONGOC_DEBUG ("SASL: authentication failed"); - bson_destroy (&reply); - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "Received invalid SASL reply from MongoDB server."); - goto failure; - } - - tmpstr = bson_iter_utf8 (&iter, &buflen); - - if (buflen > sizeof buf) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "SASL reply from MongoDB is too large."); - - bson_destroy (&reply); - goto failure; - } - - memcpy (buf, tmpstr, buflen); - - bson_destroy (&reply); - mongoc_cmd_parts_cleanup (&parts); - } - - TRACE ("%s", "SASL: authenticated"); - - ret = true; - -failure: - _mongoc_cyrus_destroy (&sasl); - mongoc_cmd_parts_cleanup (&parts); - - return ret; -} -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-private.h deleted file mode 100644 index a6483f480e48ce8daaddb7dccc46b1b97226d465..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-private.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLUSTER_PRIVATE_H -#define MONGOC_CLUSTER_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-buffer-private.h" -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-list-private.h" -#include "mongoc/mongoc-opcode.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-server-stream-private.h" -#include "mongoc/mongoc-set-private.h" -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-topology-description-private.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-scram-private.h" -#include "mongoc/mongoc-cmd-private.h" - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_cluster_node_t { - mongoc_stream_t *stream; - char *connection_address; - - int32_t max_wire_version; - int32_t min_wire_version; - int32_t max_write_batch_size; - int32_t max_bson_obj_size; - int32_t max_msg_size; - - int64_t timestamp; -} mongoc_cluster_node_t; - -typedef struct _mongoc_cluster_t { - int64_t operation_id; - uint32_t request_id; - uint32_t sockettimeoutms; - uint32_t socketcheckintervalms; - mongoc_uri_t *uri; - unsigned requires_auth : 1; - - mongoc_client_t *client; - - mongoc_set_t *nodes; - mongoc_array_t iov; - - mongoc_scram_cache_t *scram_cache; -} mongoc_cluster_t; - - -void -mongoc_cluster_init (mongoc_cluster_t *cluster, - const mongoc_uri_t *uri, - void *client); - -void -mongoc_cluster_destroy (mongoc_cluster_t *cluster); - -void -mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster, - uint32_t id, - bool invalidate, - const bson_error_t *why); - -int32_t -mongoc_cluster_get_max_bson_obj_size (mongoc_cluster_t *cluster); - -int32_t -mongoc_cluster_get_max_msg_size (mongoc_cluster_t *cluster); - -size_t -_mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov, - size_t iovcnt, - int skip, - char *buffer); - -bool -mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id); - -bool -mongoc_cluster_legacy_rpc_sendv_to_server ( - mongoc_cluster_t *cluster, - mongoc_rpc_t *rpcs, - mongoc_server_stream_t *server_stream, - bson_error_t *error); - -bool -mongoc_cluster_try_recv (mongoc_cluster_t *cluster, - mongoc_rpc_t *rpc, - mongoc_buffer_t *buffer, - mongoc_server_stream_t *server_stream, - bson_error_t *error); - -mongoc_server_stream_t * -mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster, - const mongoc_read_prefs_t *read_prefs, - mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error); - -mongoc_server_stream_t * -mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster, - mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error); - -mongoc_server_stream_t * -mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, - uint32_t server_id, - bool reconnect_ok, - mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error); - -bool -mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, - mongoc_cmd_t *cmd, - bson_t *reply, - bson_error_t *error); - -bool -mongoc_cluster_run_command_parts (mongoc_cluster_t *cluster, - mongoc_server_stream_t *server_stream, - mongoc_cmd_parts_t *parts, - bson_t *reply, - bson_error_t *error); - -bool -mongoc_cluster_run_command_private (mongoc_cluster_t *cluster, - mongoc_cmd_t *cmd, - bson_t *reply, - bson_error_t *error); - -void -_mongoc_cluster_build_sasl_start (bson_t *cmd, - const char *mechanism, - const char *buf, - uint32_t buflen); - -void -_mongoc_cluster_build_sasl_continue (bson_t *cmd, - int conv_id, - const char *buf, - uint32_t buflen); - -int -_mongoc_cluster_get_conversation_id (const bson_t *reply); - -mongoc_server_stream_t * -_mongoc_cluster_create_server_stream (mongoc_topology_t *topology, - uint32_t server_id, - mongoc_stream_t *stream, - bson_error_t *error /* OUT */); -BSON_END_DECLS - - -#endif /* MONGOC_CLUSTER_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h deleted file mode 100644 index ed217a889d4c36feca7abdf05c5c1ba7cbeb76ca..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLUSTER_SASL_PRIVATE_H -#define MONGOC_CLUSTER_SASL_PRIVATE_H - -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-cluster-private.h" -#include <bson/bson.h> - -bool -_mongoc_cluster_auth_node_sasl (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error); -#endif /* MONGOC_CLUSTER_SASL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sasl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sasl.c deleted file mode 100644 index b5cc75a5fe1de34e433e3c6fc59c355261df96d9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sasl.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/* for size_t */ -#include <bson/bson.h> -#include "mongoc/mongoc-config.h" - -#include "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-socket.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-util-private.h" - -#ifdef MONGOC_ENABLE_SASL - -#ifdef MONGOC_ENABLE_SASL_CYRUS -#include "mongoc/mongoc-cluster-cyrus-private.h" -#endif -#ifdef MONGOC_ENABLE_SASL_SSPI -#include "mongoc/mongoc-cluster-sspi-private.h" -#endif - -void -_mongoc_cluster_build_sasl_start (bson_t *cmd, - const char *mechanism, - const char *buf, - uint32_t buflen) -{ - BSON_APPEND_INT32 (cmd, "saslStart", 1); - BSON_APPEND_UTF8 (cmd, "mechanism", "GSSAPI"); - bson_append_utf8 (cmd, "payload", 7, buf, buflen); - BSON_APPEND_INT32 (cmd, "autoAuthorize", 1); -} -void -_mongoc_cluster_build_sasl_continue (bson_t *cmd, - int conv_id, - const char *buf, - uint32_t buflen) -{ - BSON_APPEND_INT32 (cmd, "saslContinue", 1); - BSON_APPEND_INT32 (cmd, "conversationId", conv_id); - bson_append_utf8 (cmd, "payload", 7, buf, buflen); -} -int -_mongoc_cluster_get_conversation_id (const bson_t *reply) -{ - bson_iter_t iter; - - if (bson_iter_init_find (&iter, reply, "conversationId") && - BSON_ITER_HOLDS_INT32 (&iter)) { - return bson_iter_int32 (&iter); - } - - return 0; -} -#endif - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cluster_auth_node_sasl -- - * - * Perform authentication for a cluster node using SASL. This is - * only supported for GSSAPI at the moment. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * error may be set. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_cluster_auth_node_sasl (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error) -{ -#ifndef MONGOC_ENABLE_SASL - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "The GSSAPI authentication mechanism requires libmongoc " - "built with ENABLE_SASL"); - return false; -#elif defined(MONGOC_ENABLE_SASL_CYRUS) - return _mongoc_cluster_auth_node_cyrus (cluster, stream, sd, error); -#elif defined(MONGOC_ENABLE_SASL_SSPI) - return _mongoc_cluster_auth_node_sspi (cluster, stream, sd, error); -#endif -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h deleted file mode 100644 index 048328a501d1a4083d4b0324cd3b8816114b4c31..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CLUSTER_SSPI_PRIVATE_H -#define MONGOC_CLUSTER_SSPI_PRIVATE_H - -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-cluster-private.h" -#include <bson/bson.h> - -bool -_mongoc_cluster_auth_node_sspi (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error); -#endif /* MONGOC_CLUSTER_SSPI_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sspi.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sspi.c deleted file mode 100644 index e1bef50f60f38a441216caaa7ac989aac2e865ca..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster-sspi.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SASL_SSPI -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-cluster-sspi-private.h" -#include "mongoc/mongoc-cluster-sasl-private.h" -#include "mongoc/mongoc-sasl-private.h" -#include "mongoc/mongoc-sspi-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-util-private.h" - - -static mongoc_sspi_client_state_t * -_mongoc_cluster_sspi_new (mongoc_uri_t *uri, - mongoc_stream_t *stream, - const char *hostname) -{ - WCHAR *service; /* L"serviceName@hostname@REALM" */ - const char *service_name = "mongodb"; - ULONG flags = ISC_REQ_MUTUAL_AUTH; - const char *service_realm = NULL; - char *service_ascii = NULL; - mongoc_sspi_client_state_t *state; - size_t service_ascii_len; - size_t tmp_creds_len; - bson_t properties; - bson_iter_t iter; - char real_name[BSON_HOST_NAME_MAX + 1]; - int service_len; - WCHAR *pass = NULL; - WCHAR *user = NULL; - size_t user_len = 0; - size_t pass_len = 0; - int res; - - state = (mongoc_sspi_client_state_t *) bson_malloc0 (sizeof *state); - _mongoc_sasl_set_properties (&state->sasl, uri); - - if (state->sasl.canonicalize_host_name && - _mongoc_sasl_get_canonicalized_name ( - stream, real_name, sizeof real_name)) { - hostname = real_name; - } - - /* service realm is an SSPI-specific feature */ - if (mongoc_uri_get_mechanism_properties (uri, &properties) && - bson_iter_init_find_case (&iter, &properties, "SERVICE_REALM") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - service_realm = bson_iter_utf8 (&iter, NULL); - service_ascii = - bson_strdup_printf ("%s@%s@%s", service_name, hostname, service_realm); - } else { - service_ascii = bson_strdup_printf ("%s@%s", service_name, hostname); - } - service_ascii_len = strlen (service_ascii); - - /* this is donated to the sspi */ - service = calloc (service_ascii_len + 1, sizeof (WCHAR)); - service_len = MultiByteToWideChar (CP_UTF8, - 0, - service_ascii, - (int) service_ascii_len, - service, - (int) service_ascii_len); - service[service_len] = L'\0'; - bson_free (service_ascii); - - if (state->sasl.pass) { - tmp_creds_len = strlen (state->sasl.pass); - - /* this is donated to the sspi */ - pass = calloc (tmp_creds_len + 1, sizeof (WCHAR)); - pass_len = MultiByteToWideChar (CP_UTF8, - 0, - state->sasl.pass, - (int) tmp_creds_len, - pass, - (int) tmp_creds_len); - pass[pass_len] = L'\0'; - } - - if (state->sasl.user) { - tmp_creds_len = strlen (state->sasl.user); - - /* this is donated to the sspi */ - user = calloc (tmp_creds_len + 1, sizeof (WCHAR)); - user_len = MultiByteToWideChar (CP_UTF8, - 0, - state->sasl.user, - (int) tmp_creds_len, - user, - (int) tmp_creds_len); - user[user_len] = L'\0'; - } - - res = _mongoc_sspi_auth_sspi_client_init (service, - flags, - user, - (ULONG) user_len, - NULL, - 0, - pass, - (ULONG) pass_len, - state); - - if (res != MONGOC_SSPI_AUTH_GSS_ERROR) { - return state; - } - bson_free (state); - return NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cluster_auth_node_sspi -- - * - * Perform authentication for a cluster node using SSPI - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * error may be set. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_cluster_auth_node_sspi (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error) -{ - mongoc_cmd_parts_t parts; - mongoc_sspi_client_state_t *state; - SEC_CHAR buf[4096] = {0}; - bson_iter_t iter; - uint32_t buflen; - bson_t reply; - const char *tmpstr; - int conv_id; - bson_t cmd; - int res = MONGOC_SSPI_AUTH_GSS_CONTINUE; - int step; - mongoc_server_stream_t *server_stream; - bool ret = false; - - state = _mongoc_cluster_sspi_new (cluster->uri, stream, sd->host.host); - - if (!state) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "Couldn't initialize SSPI service."); - goto failure; - } - - for (step = 0;; step++) { - mongoc_cmd_parts_init ( - &parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &cmd); - bson_init (&cmd); - - if (res == MONGOC_SSPI_AUTH_GSS_CONTINUE) { - res = _mongoc_sspi_auth_sspi_client_step (state, buf); - } else if (res == MONGOC_SSPI_AUTH_GSS_COMPLETE) { - char *response; - size_t tmp_creds_len = strlen (state->sasl.user); - - res = _mongoc_sspi_auth_sspi_client_unwrap (state, buf); - response = bson_strdup (state->response); - _mongoc_sspi_auth_sspi_client_wrap (state, - response, - (SEC_CHAR *) state->sasl.user, - (ULONG) tmp_creds_len, - 0); - bson_free (response); - } - - if (res == MONGOC_SSPI_AUTH_GSS_ERROR) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "Received invalid SSPI data."); - - mongoc_cmd_parts_cleanup (&parts); - bson_destroy (&cmd); - goto failure; - } - - if (step == 0) { - _mongoc_cluster_build_sasl_start (&cmd, - "GSSAPI", - state->response, - (uint32_t) strlen (state->response)); - } else { - if (state->response) { - _mongoc_cluster_build_sasl_continue ( - &cmd, - conv_id, - state->response, - (uint32_t) strlen (state->response)); - } else { - _mongoc_cluster_build_sasl_continue (&cmd, conv_id, "", 0); - } - } - - server_stream = _mongoc_cluster_create_server_stream ( - cluster->client->topology, sd->id, stream, error); - - if (!server_stream || - !mongoc_cmd_parts_assemble (&parts, server_stream, error)) { - mongoc_server_stream_cleanup (server_stream); - mongoc_cmd_parts_cleanup (&parts); - bson_destroy (&cmd); - goto failure; - } - - if (!mongoc_cluster_run_command_private ( - cluster, &parts.assembled, &reply, error)) { - mongoc_server_stream_cleanup (server_stream); - mongoc_cmd_parts_cleanup (&parts); - bson_destroy (&cmd); - bson_destroy (&reply); - goto failure; - } - - mongoc_server_stream_cleanup (server_stream); - mongoc_cmd_parts_cleanup (&parts); - bson_destroy (&cmd); - - if (bson_iter_init_find (&iter, &reply, "done") && - bson_iter_as_bool (&iter)) { - bson_destroy (&reply); - break; - } - - conv_id = _mongoc_cluster_get_conversation_id (&reply); - - if (!bson_iter_init_find (&iter, &reply, "payload") || - !BSON_ITER_HOLDS_UTF8 (&iter)) { - bson_destroy (&reply); - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "Received invalid SASL reply from MongoDB server."); - goto failure; - } - - - tmpstr = bson_iter_utf8 (&iter, &buflen); - - if (buflen > sizeof buf) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "SASL reply from MongoDB is too large."); - - bson_destroy (&reply); - goto failure; - } - - memcpy (buf, tmpstr, buflen); - - bson_destroy (&reply); - } - - ret = true; -failure: - bson_free (state); - return ret; -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster.c deleted file mode 100644 index 393e2f2aab6a99ac050d4ca74d53db7804ed9035..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cluster.c +++ /dev/null @@ -1,3016 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-config.h" - -#include <string.h> - -#include "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-client-side-encryption-private.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-cluster-sasl-private.h" -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-ssl-private.h" -#include "mongoc/mongoc-stream-tls.h" -#endif -#include "common-b64-private.h" -#include "mongoc/mongoc-scram-private.h" -#include "mongoc/mongoc-set-private.h" -#include "mongoc/mongoc-socket.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-socket.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-thread-private.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-compression-private.h" -#include "mongoc/mongoc-cmd-private.h" -#include "mongoc/utlist.h" -#include "mongoc/mongoc-handshake-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "cluster" - - -#define CHECK_CLOSED_DURATION_MSEC 1000 - -#define DB_AND_CMD_FROM_COLLECTION(outstr, name) \ - do { \ - const char *dot = strchr (name, '.'); \ - if (!dot || ((dot - name) > (sizeof outstr - 6))) { \ - bson_snprintf (outstr, sizeof outstr, "admin.$cmd"); \ - } else { \ - memcpy (outstr, name, dot - name); \ - memcpy (outstr + (dot - name), ".$cmd", 6); \ - } \ - } while (0) - -#define IS_NOT_COMMAND(_name) (!!strcasecmp (cmd->command_name, _name)) - -/** - * mongoc_op_msg_flags_t: - * @MONGOC_MSG_CHECKSUM_PRESENT: The message ends with 4 bytes containing a - * CRC-32C checksum. - * @MONGOC_MSG_MORE_TO_COME: If set to 0, wait for a server response. If set to - * 1, do not expect a server response. - * @MONGOC_MSG_EXHAUST_ALLOWED: If set, allows multiple replies to this request - * using the moreToCome bit. - */ -typedef enum { - MONGOC_MSG_NONE = 0, - MONGOC_MSG_CHECKSUM_PRESENT = 1 << 0, - MONGOC_MSG_MORE_TO_COME = 1 << 1, - MONGOC_EXHAUST_ALLOWED = 1 << 16, -} mongoc_op_msg_flags_t; - -static mongoc_server_stream_t * -mongoc_cluster_fetch_stream_single (mongoc_cluster_t *cluster, - uint32_t server_id, - bool reconnect_ok, - bson_error_t *error); - -static mongoc_server_stream_t * -mongoc_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster, - uint32_t server_id, - bool reconnect_ok, - bson_error_t *error); - -static bool -mongoc_cluster_run_opmsg (mongoc_cluster_t *cluster, - mongoc_cmd_t *cmd, - bson_t *reply, - bson_error_t *error); - -static void -_bson_error_message_printf (bson_error_t *error, const char *format, ...) - BSON_GNUC_PRINTF (2, 3); - - -size_t -_mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov, - size_t iovcnt, - int skip, - char *buffer) -{ - int n; - size_t buffer_offset = 0; - int total_iov_len = 0; - int difference = 0; - - for (n = 0; n < iovcnt; n++) { - total_iov_len += iov[n].iov_len; - - if (total_iov_len <= skip) { - continue; - } - - /* If this iovec starts before the skip, and takes the total count - * beyond the skip, we need to figure out the portion of the iovec - * we should skip passed */ - if (total_iov_len - iov[n].iov_len < skip) { - difference = skip - (total_iov_len - iov[n].iov_len); - } else { - difference = 0; - } - - memcpy (buffer + buffer_offset, - ((char *) iov[n].iov_base) + difference, - iov[n].iov_len - difference); - buffer_offset += iov[n].iov_len - difference; - } - - return buffer_offset; -} - -/* Allows caller to safely overwrite error->message with a formatted string, - * even if the formatted string includes original error->message. */ -static void -_bson_error_message_printf (bson_error_t *error, const char *format, ...) -{ - va_list args; - char error_message[sizeof error->message]; - - if (error) { - va_start (args, format); - bson_vsnprintf (error_message, sizeof error->message, format, args); - va_end (args); - - bson_strncpy (error->message, error_message, sizeof error->message); - } -} - -#define RUN_CMD_ERR_DECORATE \ - do { \ - _bson_error_message_printf ( \ - error, \ - "Failed to send \"%s\" command with database \"%s\": %s", \ - cmd->command_name, \ - cmd->db_name, \ - error->message); \ - } while (0) - -#define RUN_CMD_ERR(_domain, _code, ...) \ - do { \ - bson_set_error (error, _domain, _code, __VA_ARGS__); \ - RUN_CMD_ERR_DECORATE; \ - } while (0) - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_run_command_opquery -- - * - * Internal function to run a command on a given stream. @error and - * @reply are optional out-pointers. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @reply is set and should ALWAYS be released with bson_destroy(). - * On failure, @error is filled out. If this was a network error - * and server_id is nonzero, the cluster disconnects from the server. - * - *-------------------------------------------------------------------------- - */ - -static bool -mongoc_cluster_run_command_opquery (mongoc_cluster_t *cluster, - mongoc_cmd_t *cmd, - mongoc_stream_t *stream, - int32_t compressor_id, - bson_t *reply, - bson_error_t *error) -{ - const size_t reply_header_size = sizeof (mongoc_rpc_reply_header_t); - uint8_t reply_header_buf[sizeof (mongoc_rpc_reply_header_t)]; - uint8_t *reply_buf; /* reply body */ - mongoc_rpc_t rpc; /* sent to server */ - bson_t reply_local; - bson_t *reply_ptr; - char cmd_ns[MONGOC_NAMESPACE_MAX]; - uint32_t request_id; - int32_t msg_len; - size_t doc_len; - bool ret = false; - char *output = NULL; - uint32_t server_id; - - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (cmd); - BSON_ASSERT (stream); - - /* - * setup - */ - reply_ptr = reply ? reply : &reply_local; - bson_init (reply_ptr); - - error->code = 0; - - /* - * prepare the request - */ - - _mongoc_array_clear (&cluster->iov); - - bson_snprintf (cmd_ns, sizeof cmd_ns, "%s.$cmd", cmd->db_name); - request_id = ++cluster->request_id; - _mongoc_rpc_prep_command (&rpc, cmd_ns, cmd); - rpc.header.request_id = request_id; - server_id = cmd->server_stream->sd->id; - - _mongoc_rpc_gather (&rpc, &cluster->iov); - _mongoc_rpc_swab_to_le (&rpc); - - if (compressor_id != -1 && IS_NOT_COMMAND ("ismaster") && - IS_NOT_COMMAND ("saslstart") && IS_NOT_COMMAND ("saslcontinue") && - IS_NOT_COMMAND ("getnonce") && IS_NOT_COMMAND ("authenticate") && - IS_NOT_COMMAND ("createuser") && IS_NOT_COMMAND ("updateuser")) { - output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error); - if (output == NULL) { - GOTO (done); - } - } - - if (cluster->client->in_exhaust) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_IN_EXHAUST, - "A cursor derived from this client is in exhaust."); - GOTO (done); - } - - /* - * send and receive - */ - if (!_mongoc_stream_writev_full (stream, - cluster->iov.data, - cluster->iov.len, - cluster->sockettimeoutms, - error)) { - mongoc_cluster_disconnect_node (cluster, server_id, true, error); - - /* add info about the command to writev_full's error message */ - RUN_CMD_ERR_DECORATE; - GOTO (done); - } - - if (reply_header_size != mongoc_stream_read (stream, - &reply_header_buf, - reply_header_size, - reply_header_size, - cluster->sockettimeoutms)) { - RUN_CMD_ERR (MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "socket error or timeout"); - - mongoc_cluster_disconnect_node ( - cluster, server_id, !mongoc_stream_timed_out (stream), error); - GOTO (done); - } - - memcpy (&msg_len, reply_header_buf, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - if ((msg_len < reply_header_size) || - (msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE)) { - mongoc_cluster_disconnect_node (cluster, server_id, true, error); - GOTO (done); - } - - if (!_mongoc_rpc_scatter_reply_header_only ( - &rpc, reply_header_buf, reply_header_size)) { - mongoc_cluster_disconnect_node (cluster, server_id, true, error); - GOTO (done); - } - doc_len = (size_t) msg_len - reply_header_size; - - if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) { - bson_t tmp = BSON_INITIALIZER; - uint8_t *buf = NULL; - size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); - - reply_buf = bson_malloc0 (msg_len); - memcpy (reply_buf, reply_header_buf, reply_header_size); - - if (doc_len != mongoc_stream_read (stream, - reply_buf + reply_header_size, - doc_len, - doc_len, - cluster->sockettimeoutms)) { - RUN_CMD_ERR (MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "socket error or timeout"); - mongoc_cluster_disconnect_node (cluster, server_id, true, error); - GOTO (done); - } - if (!_mongoc_rpc_scatter (&rpc, reply_buf, msg_len)) { - GOTO (done); - } - - buf = bson_malloc0 (len); - if (!_mongoc_rpc_decompress (&rpc, buf, len)) { - RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress server reply"); - bson_free (reply_buf); - bson_free (buf); - GOTO (done); - } - - _mongoc_rpc_swab_from_le (&rpc); - - if (!_mongoc_rpc_get_first_document (&rpc, &tmp)) { - RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Corrupt compressed OP_QUERY reply from server"); - bson_free (reply_buf); - bson_free (buf); - GOTO (done); - } - bson_copy_to (&tmp, reply_ptr); - bson_free (reply_buf); - bson_free (buf); - } else if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_REPLY && - BSON_UINT32_FROM_LE (rpc.reply_header.n_returned) == 1) { - reply_buf = bson_reserve_buffer (reply_ptr, (uint32_t) doc_len); - BSON_ASSERT (reply_buf); - - if (doc_len != mongoc_stream_read (stream, - (void *) reply_buf, - doc_len, - doc_len, - cluster->sockettimeoutms)) { - RUN_CMD_ERR (MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "socket error or timeout"); - mongoc_cluster_disconnect_node (cluster, server_id, true, error); - GOTO (done); - } - _mongoc_rpc_swab_from_le (&rpc); - } else { - GOTO (done); - } - - if (!_mongoc_cmd_check_ok ( - reply_ptr, cluster->client->error_api_version, error)) { - GOTO (done); - } - - ret = true; - -done: - - if (!ret && error->code == 0) { - /* generic error */ - RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply from server."); - } - - if (reply_ptr == &reply_local) { - bson_destroy (reply_ptr); - } - bson_free (output); - - RETURN (ret); -} - - -typedef enum { - MONGOC_REPLY_ERR_TYPE_NONE, - MONGOC_REPLY_ERR_TYPE_NOT_MASTER, - MONGOC_REPLY_ERR_TYPE_SHUTDOWN, - MONGOC_REPLY_ERR_TYPE_NODE_IS_RECOVERING -} reply_error_type_t; - - -/*--------------------------------------------------------------------------- - * - * _check_not_master_or_recovering_error -- - * - * Checks @reply for a "not master" or "node is recovering" error and - * sets @error. - * - * Return: - * A reply_error_type_t indicating if @reply contained a "not master" - * or "node is recovering" error. - * - *-------------------------------------------------------------------------- - */ -static reply_error_type_t -_check_not_master_or_recovering_error (const mongoc_client_t *client, - const bson_t *reply, - bson_error_t *error) -{ - if (_mongoc_cmd_check_ok_no_wce (reply, client->error_api_version, error)) { - return MONGOC_REPLY_ERR_TYPE_NONE; - } - - switch (error->code) { - case 11600: /* InterruptedAtShutdown */ - case 91: /* ShutdownInProgress */ - return MONGOC_REPLY_ERR_TYPE_SHUTDOWN; - case 11602: /* InterruptedDueToReplStateChange */ - case 13436: /* NotMasterOrSecondary */ - case 189: /* PrimarySteppedDown */ - return MONGOC_REPLY_ERR_TYPE_NODE_IS_RECOVERING; - case 10107: /* NotMaster */ - case 13435: /* NotMasterNoSlaveOk */ - return MONGOC_REPLY_ERR_TYPE_NOT_MASTER; - default: - if (strstr (error->message, "not master")) { - return MONGOC_REPLY_ERR_TYPE_NOT_MASTER; - } else if (strstr (error->message, "node is recovering")) { - return MONGOC_REPLY_ERR_TYPE_NODE_IS_RECOVERING; - } - return MONGOC_REPLY_ERR_TYPE_NONE; - } -} - - -static void -handle_not_master_error (mongoc_cluster_t *cluster, - uint32_t server_id, - const bson_t *reply) -{ - mongoc_topology_t *topology = cluster->client->topology; - mongoc_server_description_t *sd; - bson_error_t error; - reply_error_type_t error_type = - _check_not_master_or_recovering_error (cluster->client, reply, &error); - - if (error_type != MONGOC_REPLY_ERR_TYPE_NONE) { - /* Server Discovery and Monitoring Spec: "When the client sees a 'not - * master' or 'node is recovering' error it MUST replace the server's - * description with a default ServerDescription of type Unknown." - * - * The client MUST clear its connection pool for the server - * if the server is 4.0 or earlier, and MUST NOT clear its connection - * pool for the server if the server is 4.2 or later. */ - sd = mongoc_topology_server_by_id (topology, server_id, &error); - if (sd->max_wire_version <= WIRE_VERSION_4_0 || - error_type == MONGOC_REPLY_ERR_TYPE_SHUTDOWN) { - mongoc_cluster_disconnect_node (cluster, server_id, false, NULL); - } - mongoc_server_description_destroy (sd); - - mongoc_topology_invalidate_server (topology, server_id, &error); - - if (topology->single_threaded) { - /* SDAM Spec: "For single-threaded clients, in the case of a 'not - * master' error, the client MUST check the server immediately... For a - * 'node is recovering' error, single-threaded clients MUST NOT check - * the server, as an immediate server check is unlikely to find a - * usable server." - * Instead of an immediate check, mark the topology as stale so the - * next command scans all servers (to find the new primary). */ - if (error_type == MONGOC_REPLY_ERR_TYPE_NOT_MASTER) { - cluster->client->topology->stale = true; - } - } else { - /* SDAM Spec: "Multi-threaded and asynchronous clients MUST request an - * immediate check of the server." - * Instead of requesting a check of the one server, request a scan - * to all servers (to find the new primary). */ - _mongoc_topology_request_scan (topology); - } - } -} - -bool -_in_sharded_txn (const mongoc_client_session_t *session) -{ - return session && _mongoc_client_session_in_txn_or_ending (session) && - _mongoc_topology_get_type (session->client->topology) == - MONGOC_TOPOLOGY_SHARDED; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_run_command_monitored -- - * - * Internal function to run a command on a given stream. - * @error and @reply are optional out-pointers. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * If the client's APM callbacks are set, they are executed. - * @reply is set and should ALWAYS be released with bson_destroy(). - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, - mongoc_cmd_t *cmd, - bson_t *reply, - bson_error_t *error) -{ - bool retval; - uint32_t request_id = ++cluster->request_id; - uint32_t server_id; - mongoc_apm_callbacks_t *callbacks; - mongoc_apm_command_started_t started_event; - mongoc_apm_command_succeeded_t succeeded_event; - mongoc_apm_command_failed_t failed_event; - int64_t started = bson_get_monotonic_time (); - const mongoc_server_stream_t *server_stream; - bson_t reply_local; - bson_error_t error_local; - int32_t compressor_id; - bson_iter_t iter; - bson_t encrypted = BSON_INITIALIZER; - bson_t decrypted = BSON_INITIALIZER; - mongoc_cmd_t encrypted_cmd; - - server_stream = cmd->server_stream; - server_id = server_stream->sd->id; - compressor_id = mongoc_server_description_compressor_id (server_stream->sd); - - callbacks = &cluster->client->apm_callbacks; - if (!reply) { - reply = &reply_local; - } - if (!error) { - error = &error_local; - } - - if (cluster->client->cse_enabled) { - bson_destroy (&encrypted); - - retval = _mongoc_cse_auto_encrypt ( - cluster->client, cmd, &encrypted_cmd, &encrypted, error); - cmd = &encrypted_cmd; - if (!retval) { - bson_init (reply); - goto fail_no_events; - } - } - - if (callbacks->started) { - mongoc_apm_command_started_init_with_cmd ( - &started_event, cmd, request_id, cluster->client->apm_context); - - callbacks->started (&started_event); - mongoc_apm_command_started_cleanup (&started_event); - } - - if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) { - retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error); - } else { - retval = mongoc_cluster_run_command_opquery ( - cluster, cmd, server_stream->stream, compressor_id, reply, error); - } - - if (cluster->client->cse_enabled) { - bson_destroy (&decrypted); - retval = _mongoc_cse_auto_decrypt ( - cluster->client, cmd->db_name, reply, &decrypted, error); - bson_destroy (reply); - bson_steal (reply, &decrypted); - bson_init (&decrypted); - if (!retval) { - goto fail_no_events; - } - } - - if (retval && callbacks->succeeded) { - bson_t fake_reply = BSON_INITIALIZER; - /* - * Unacknowledged writes must provide a CommandSucceededEvent with an - * {ok: 1} reply. - * https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#unacknowledged-acknowledged-writes - */ - if (!cmd->is_acknowledged) { - bson_append_int32 (&fake_reply, "ok", 2, 1); - } - mongoc_apm_command_succeeded_init (&succeeded_event, - bson_get_monotonic_time () - started, - cmd->is_acknowledged ? reply - : &fake_reply, - cmd->command_name, - request_id, - cmd->operation_id, - &server_stream->sd->host, - server_id, - cluster->client->apm_context); - - callbacks->succeeded (&succeeded_event); - mongoc_apm_command_succeeded_cleanup (&succeeded_event); - bson_destroy (&fake_reply); - } - if (!retval && callbacks->failed) { - mongoc_apm_command_failed_init (&failed_event, - bson_get_monotonic_time () - started, - cmd->command_name, - error, - reply, - request_id, - cmd->operation_id, - &server_stream->sd->host, - server_id, - cluster->client->apm_context); - - callbacks->failed (&failed_event); - mongoc_apm_command_failed_cleanup (&failed_event); - } - - handle_not_master_error (cluster, server_id, reply); - - if (retval && _in_sharded_txn (cmd->session) && - bson_iter_init_find (&iter, reply, "recoveryToken")) { - bson_destroy (cmd->session->recovery_token); - if (BSON_ITER_HOLDS_DOCUMENT (&iter)) { - cmd->session->recovery_token = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - } else { - MONGOC_ERROR ("Malformed recovery token from server"); - cmd->session->recovery_token = NULL; - } - } - -fail_no_events: - if (reply == &reply_local) { - bson_destroy (&reply_local); - } - - bson_destroy (&encrypted); - bson_destroy (&decrypted); - - _mongoc_topology_update_last_used (cluster->client->topology, server_id); - - return retval; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_run_command_private -- - * - * Internal function to run a command on a given stream. - * @error and @reply are optional out-pointers. - * The client's APM callbacks are not executed. - * Automatic encryption/decryption is not performed. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @reply is set and should ALWAYS be released with bson_destroy(). - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cluster_run_command_private (mongoc_cluster_t *cluster, - mongoc_cmd_t *cmd, - bson_t *reply, - bson_error_t *error) -{ - bool retval; - const mongoc_server_stream_t *server_stream; - bson_t reply_local; - bson_error_t error_local; - - if (!error) { - error = &error_local; - } - - if (!reply) { - reply = &reply_local; - } - server_stream = cmd->server_stream; - if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) { - retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error); - } else { - retval = mongoc_cluster_run_command_opquery ( - cluster, cmd, cmd->server_stream->stream, -1, reply, error); - } - handle_not_master_error (cluster, server_stream->sd->id, reply); - if (reply == &reply_local) { - bson_destroy (&reply_local); - } - - _mongoc_topology_update_last_used (cluster->client->topology, - server_stream->sd->id); - - return retval; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_run_command_parts -- - * - * Internal function to assemble command parts and run a command - * on a given stream. @error and @reply are optional out-pointers. - * The client's APM callbacks are not executed. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @reply is set and should ALWAYS be released with bson_destroy(). - * mongoc_cmd_parts_cleanup will be always be called on parts. The - * caller should *not* call cleanup on the parts. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cluster_run_command_parts (mongoc_cluster_t *cluster, - mongoc_server_stream_t *server_stream, - mongoc_cmd_parts_t *parts, - bson_t *reply, - bson_error_t *error) -{ - bool ret; - - if (!mongoc_cmd_parts_assemble (parts, server_stream, error)) { - _mongoc_bson_init_if_set (reply); - mongoc_cmd_parts_cleanup (parts); - return false; - } - - ret = mongoc_cluster_run_command_private ( - cluster, &parts->assembled, reply, error); - mongoc_cmd_parts_cleanup (parts); - return ret; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_stream_run_ismaster -- - * - * Run an ismaster command on the given stream. If - * @negotiate_sasl_supported_mechs is true, then saslSupportedMechs is - * added to the ismaster command. - * - * Returns: - * A mongoc_server_description_t you must destroy or NULL. If the call - * failed its error is set and its type is MONGOC_SERVER_UNKNOWN. - * - *-------------------------------------------------------------------------- - */ -static mongoc_server_description_t * -_mongoc_stream_run_ismaster (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - const char *address, - uint32_t server_id, - bool negotiate_sasl_supported_mechs, - bson_error_t *error) -{ - const bson_t *command; - mongoc_cmd_parts_t parts; - bson_t reply; - int64_t start; - int64_t rtt_msec; - mongoc_server_description_t *sd; - mongoc_server_stream_t *server_stream; - bson_t *copied_command = NULL; - bool r; - bson_iter_t iter; - - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (stream); - - command = _mongoc_topology_get_ismaster (cluster->client->topology); - - if (negotiate_sasl_supported_mechs) { - copied_command = bson_copy (command); - _mongoc_handshake_append_sasl_supported_mechs (cluster->uri, - copied_command); - command = copied_command; - } - - start = bson_get_monotonic_time (); - server_stream = _mongoc_cluster_create_server_stream ( - cluster->client->topology, server_id, stream, error); - if (!server_stream) { - bson_destroy (copied_command); - RETURN (NULL); - } - - mongoc_cmd_parts_init ( - &parts, cluster->client, "admin", MONGOC_QUERY_SLAVE_OK, command); - parts.prohibit_lsid = true; - if (!mongoc_cluster_run_command_parts ( - cluster, server_stream, &parts, &reply, error)) { - if (negotiate_sasl_supported_mechs) { - if (bson_iter_init_find (&iter, &reply, "ok") && - !bson_iter_as_bool (&iter)) { - /* ismaster response returned ok: 0. According to auth spec: "If the - * isMaster of the MongoDB Handshake fails with an error, drivers - * MUST treat this an authentication error." */ - error->domain = MONGOC_ERROR_CLIENT; - error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - } - } - - bson_destroy (copied_command); - bson_destroy (&reply); - mongoc_server_stream_cleanup (server_stream); - RETURN (NULL); - } - - rtt_msec = (bson_get_monotonic_time () - start) / 1000; - - sd = (mongoc_server_description_t *) bson_malloc0 ( - sizeof (mongoc_server_description_t)); - - mongoc_server_description_init (sd, address, server_id); - /* send the error from run_command IN to handle_ismaster */ - mongoc_server_description_handle_ismaster (sd, &reply, rtt_msec, error); - - bson_destroy (&reply); - - r = _mongoc_topology_update_from_handshake (cluster->client->topology, sd); - if (!r) { - mongoc_server_description_reset (sd); - bson_set_error (&sd->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NOT_ESTABLISHED, - "\"%s\" removed from topology", - address); - } - - mongoc_server_stream_cleanup (server_stream); - - if (copied_command) { - bson_destroy (copied_command); - } - - RETURN (sd); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cluster_run_ismaster -- - * - * Run an initial ismaster command for the given node and handle result. - * - * Returns: - * mongoc_server_description_t on success, NULL otherwise. - * the mongoc_server_description_t MUST BE DESTROYED BY THE CALLER. - * - * Side effects: - * Makes a blocking I/O call, updates cluster->topology->description - * with ismaster result. - * - *-------------------------------------------------------------------------- - */ -static mongoc_server_description_t * -_mongoc_cluster_run_ismaster (mongoc_cluster_t *cluster, - mongoc_cluster_node_t *node, - uint32_t server_id, - bson_error_t *error /* OUT */) -{ - mongoc_server_description_t *sd; - - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (node); - BSON_ASSERT (node->stream); - - sd = _mongoc_stream_run_ismaster ( - cluster, - node->stream, - node->connection_address, - server_id, - _mongoc_uri_requires_auth_negotiation (cluster->uri), - error); - - if (!sd) { - return NULL; - } - - if (sd->type == MONGOC_SERVER_UNKNOWN) { - memcpy (error, &sd->error, sizeof (bson_error_t)); - mongoc_server_description_destroy (sd); - return NULL; - } else { - node->max_write_batch_size = sd->max_write_batch_size; - node->min_wire_version = sd->min_wire_version; - node->max_wire_version = sd->max_wire_version; - node->max_bson_obj_size = sd->max_bson_obj_size; - node->max_msg_size = sd->max_msg_size; - } - - return sd; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cluster_build_basic_auth_digest -- - * - * Computes the Basic Authentication digest using the credentials - * configured for @cluster and the @nonce provided. - * - * The result should be freed by the caller using bson_free() when - * they are finished with it. - * - * Returns: - * A newly allocated string containing the digest. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static char * -_mongoc_cluster_build_basic_auth_digest (mongoc_cluster_t *cluster, - const char *nonce) -{ - const char *username; - const char *password; - char *password_digest; - char *password_md5; - char *digest_in; - char *ret; - - ENTRY; - - /* - * The following generates the digest to be used for basic authentication - * with a MongoDB server. More information on the format can be found - * at the following location: - * - * http://docs.mongodb.org/meta-driver/latest/legacy/ - * implement-authentication-in-driver/ - */ - - BSON_ASSERT (cluster); - BSON_ASSERT (cluster->uri); - - username = mongoc_uri_get_username (cluster->uri); - password = mongoc_uri_get_password (cluster->uri); - password_digest = bson_strdup_printf ("%s:mongo:%s", username, password); - password_md5 = _mongoc_hex_md5 (password_digest); - digest_in = bson_strdup_printf ("%s%s%s", nonce, username, password_md5); - ret = _mongoc_hex_md5 (digest_in); - bson_free (digest_in); - bson_free (password_md5); - bson_free (password_digest); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cluster_auth_node_cr -- - * - * Performs authentication of @node using the credentials provided - * when configuring the @cluster instance. - * - * This is the Challenge-Response mode of authentication. - * - * Returns: - * true if authentication was successful; otherwise false and - * @error is set. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_cluster_auth_node_cr (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error) -{ - mongoc_cmd_parts_t parts; - bson_iter_t iter; - const char *auth_source; - bson_t command; - bson_t reply; - char *digest; - char *nonce; - bool ret; - mongoc_server_stream_t *server_stream; - - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (stream); - - if (!(auth_source = mongoc_uri_get_auth_source (cluster->uri)) || - (*auth_source == '\0')) { - auth_source = "admin"; - } - - /* - * To authenticate a node using basic authentication, we need to first - * get the nonce from the server. We use that to hash our password which - * is sent as a reply to the server. If everything went good we get a - * success notification back from the server. - */ - - /* - * Execute the getnonce command to fetch the nonce used for generating - * md5 digest of our password information. - */ - bson_init (&command); - bson_append_int32 (&command, "getnonce", 8, 1); - mongoc_cmd_parts_init ( - &parts, cluster->client, auth_source, MONGOC_QUERY_SLAVE_OK, &command); - parts.prohibit_lsid = true; - server_stream = _mongoc_cluster_create_server_stream ( - cluster->client->topology, sd->id, stream, error); - - if (!mongoc_cluster_run_command_parts ( - cluster, server_stream, &parts, &reply, error)) { - mongoc_server_stream_cleanup (server_stream); - bson_destroy (&command); - bson_destroy (&reply); - RETURN (false); - } - bson_destroy (&command); - if (!bson_iter_init_find_case (&iter, &reply, "nonce")) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_GETNONCE, - "Invalid reply from getnonce"); - bson_destroy (&reply); - RETURN (false); - } - - /* - * Build our command to perform the authentication. - */ - nonce = bson_iter_dup_utf8 (&iter, NULL); - digest = _mongoc_cluster_build_basic_auth_digest (cluster, nonce); - bson_init (&command); - bson_append_int32 (&command, "authenticate", 12, 1); - bson_append_utf8 ( - &command, "user", 4, mongoc_uri_get_username (cluster->uri), -1); - bson_append_utf8 (&command, "nonce", 5, nonce, -1); - bson_append_utf8 (&command, "key", 3, digest, -1); - bson_destroy (&reply); - bson_free (nonce); - bson_free (digest); - - /* - * Execute the authenticate command. mongoc_cluster_run_command_private - * checks for {ok: 1} in the response. - */ - mongoc_cmd_parts_init ( - &parts, cluster->client, auth_source, MONGOC_QUERY_SLAVE_OK, &command); - parts.prohibit_lsid = true; - ret = mongoc_cluster_run_command_parts ( - cluster, server_stream, &parts, &reply, error); - - if (!ret) { - /* error->message is already set */ - error->domain = MONGOC_ERROR_CLIENT; - error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - } - - mongoc_server_stream_cleanup (server_stream); - bson_destroy (&command); - bson_destroy (&reply); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cluster_auth_node_plain -- - * - * Perform SASL PLAIN authentication for @node. We do this manually - * instead of using the SASL module because its rather simplistic. - * - * Returns: - * true if successful; otherwise false and error is set. - * - * Side effects: - * error may be set. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_cluster_auth_node_plain (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error) -{ - mongoc_cmd_parts_t parts; - char buf[4096]; - int buflen = 0; - const char *username; - const char *password; - bson_t b = BSON_INITIALIZER; - bson_t reply; - size_t len; - char *str; - bool ret; - mongoc_server_stream_t *server_stream; - - BSON_ASSERT (cluster); - BSON_ASSERT (stream); - - username = mongoc_uri_get_username (cluster->uri); - if (!username) { - username = ""; - } - - password = mongoc_uri_get_password (cluster->uri); - if (!password) { - password = ""; - } - - str = bson_strdup_printf ("%c%s%c%s", '\0', username, '\0', password); - len = strlen (username) + strlen (password) + 2; - buflen = bson_b64_ntop ((const uint8_t *) str, len, buf, sizeof buf); - bson_free (str); - - if (buflen == -1) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "failed base64 encoding message"); - return false; - } - - BSON_APPEND_INT32 (&b, "saslStart", 1); - BSON_APPEND_UTF8 (&b, "mechanism", "PLAIN"); - bson_append_utf8 (&b, "payload", 7, (const char *) buf, buflen); - BSON_APPEND_INT32 (&b, "autoAuthorize", 1); - - mongoc_cmd_parts_init ( - &parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &b); - parts.prohibit_lsid = true; - server_stream = _mongoc_cluster_create_server_stream ( - cluster->client->topology, sd->id, stream, error); - ret = mongoc_cluster_run_command_parts ( - cluster, server_stream, &parts, &reply, error); - mongoc_server_stream_cleanup (server_stream); - if (!ret) { - /* error->message is already set */ - error->domain = MONGOC_ERROR_CLIENT; - error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - } - - bson_destroy (&b); - bson_destroy (&reply); - - return ret; -} - - -static bool -_mongoc_cluster_auth_node_x509 (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error) -{ -#ifndef MONGOC_ENABLE_SSL - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "The MONGODB-X509 authentication mechanism requires " - "libmongoc built with ENABLE_SSL"); - return false; -#else - mongoc_cmd_parts_t parts; - const char *username_from_uri = NULL; - char *username_from_subject = NULL; - bson_t cmd; - bson_t reply; - bool ret; - mongoc_server_stream_t *server_stream; - - BSON_ASSERT (cluster); - BSON_ASSERT (stream); - - username_from_uri = mongoc_uri_get_username (cluster->uri); - if (username_from_uri) { - TRACE ("%s", "X509: got username from URI"); - } else { - if (!cluster->client->ssl_opts.pem_file) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "cannot determine username for " - "X-509 authentication."); - return false; - } - - username_from_subject = mongoc_ssl_extract_subject ( - cluster->client->ssl_opts.pem_file, cluster->client->ssl_opts.pem_pwd); - if (!username_from_subject) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "No username provided for X509 authentication."); - return false; - } - - TRACE ("%s", "X509: got username from certificate"); - } - - bson_init (&cmd); - BSON_APPEND_INT32 (&cmd, "authenticate", 1); - BSON_APPEND_UTF8 (&cmd, "mechanism", "MONGODB-X509"); - BSON_APPEND_UTF8 (&cmd, - "user", - username_from_uri ? username_from_uri - : username_from_subject); - - mongoc_cmd_parts_init ( - &parts, cluster->client, "$external", MONGOC_QUERY_SLAVE_OK, &cmd); - parts.prohibit_lsid = true; - server_stream = _mongoc_cluster_create_server_stream ( - cluster->client->topology, sd->id, stream, error); - ret = mongoc_cluster_run_command_parts ( - cluster, server_stream, &parts, &reply, error); - mongoc_server_stream_cleanup (server_stream); - if (!ret) { - /* error->message is already set */ - error->domain = MONGOC_ERROR_CLIENT; - error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - } - - if (username_from_subject) { - bson_free (username_from_subject); - } - - bson_destroy (&cmd); - bson_destroy (&reply); - - return ret; -#endif -} - - -#ifdef MONGOC_ENABLE_CRYPTO -static bool -_mongoc_cluster_auth_node_scram (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - mongoc_crypto_hash_algorithm_t algo, - bson_error_t *error) -{ - mongoc_cmd_parts_t parts; - uint32_t buflen = 0; - mongoc_scram_t scram; - bson_iter_t iter; - bool ret = false; - const char *tmpstr; - const char *auth_source; - uint8_t buf[4096] = {0}; - bson_t cmd; - bson_t reply; - int conv_id = 0; - bson_subtype_t btype; - mongoc_server_stream_t *server_stream; - - BSON_ASSERT (cluster); - BSON_ASSERT (stream); - - if (!(auth_source = mongoc_uri_get_auth_source (cluster->uri)) || - (*auth_source == '\0')) { - auth_source = "admin"; - } - - _mongoc_scram_init (&scram, algo); - - _mongoc_scram_set_pass (&scram, mongoc_uri_get_password (cluster->uri)); - _mongoc_scram_set_user (&scram, mongoc_uri_get_username (cluster->uri)); - - /* Apply previously cached SCRAM secrets if available */ - if (cluster->scram_cache) { - _mongoc_scram_set_cache (&scram, cluster->scram_cache); - } - - for (;;) { - if (!_mongoc_scram_step ( - &scram, buf, buflen, buf, sizeof buf, &buflen, error)) { - goto failure; - } - - bson_init (&cmd); - - if (scram.step == 1) { - BSON_APPEND_INT32 (&cmd, "saslStart", 1); - if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_1) { - BSON_APPEND_UTF8 (&cmd, "mechanism", "SCRAM-SHA-1"); - } else if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_256) { - BSON_APPEND_UTF8 (&cmd, "mechanism", "SCRAM-SHA-256"); - } else { - BSON_ASSERT (false); - } - bson_append_binary ( - &cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen); - BSON_APPEND_INT32 (&cmd, "autoAuthorize", 1); - } else { - BSON_APPEND_INT32 (&cmd, "saslContinue", 1); - BSON_APPEND_INT32 (&cmd, "conversationId", conv_id); - bson_append_binary ( - &cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen); - } - - TRACE ("SCRAM: authenticating (step %d)", scram.step); - - mongoc_cmd_parts_init ( - &parts, cluster->client, auth_source, MONGOC_QUERY_SLAVE_OK, &cmd); - parts.prohibit_lsid = true; - server_stream = _mongoc_cluster_create_server_stream ( - cluster->client->topology, sd->id, stream, error); - if (!mongoc_cluster_run_command_parts ( - cluster, server_stream, &parts, &reply, error)) { - mongoc_server_stream_cleanup (server_stream); - bson_destroy (&cmd); - bson_destroy (&reply); - - /* error->message is already set */ - error->domain = MONGOC_ERROR_CLIENT; - error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - goto failure; - } - mongoc_server_stream_cleanup (server_stream); - - bson_destroy (&cmd); - - if (bson_iter_init_find (&iter, &reply, "done") && - bson_iter_as_bool (&iter)) { - bson_destroy (&reply); - break; - } - - if (!bson_iter_init_find (&iter, &reply, "conversationId") || - !BSON_ITER_HOLDS_INT32 (&iter) || - !(conv_id = bson_iter_int32 (&iter)) || - !bson_iter_init_find (&iter, &reply, "payload") || - !BSON_ITER_HOLDS_BINARY (&iter)) { - const char *errmsg = - "Received invalid SCRAM reply from MongoDB server."; - - MONGOC_DEBUG ("SCRAM: authentication failed"); - - if (bson_iter_init_find (&iter, &reply, "errmsg") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - errmsg = bson_iter_utf8 (&iter, NULL); - } - - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "%s", - errmsg); - bson_destroy (&reply); - goto failure; - } - - bson_iter_binary (&iter, &btype, &buflen, (const uint8_t **) &tmpstr); - - if (buflen > sizeof buf) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "SCRAM reply from MongoDB is too large."); - bson_destroy (&reply); - goto failure; - } - - memcpy (buf, tmpstr, buflen); - - bson_destroy (&reply); - } - - TRACE ("%s", "SCRAM: authenticated"); - - ret = true; - - /* Save cached SCRAM secrets for future use */ - if (cluster->scram_cache) { - _mongoc_scram_cache_destroy (cluster->scram_cache); - } - - cluster->scram_cache = _mongoc_scram_get_cache (&scram); - -failure: - _mongoc_scram_destroy (&scram); - - return ret; -} -#endif - -static bool -_mongoc_cluster_auth_node_scram_sha_1 (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error) -{ -#ifndef MONGOC_ENABLE_CRYPTO - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "The SCRAM_SHA_1 authentication mechanism requires " - "libmongoc built with ENABLE_SSL"); - return false; -#else - return _mongoc_cluster_auth_node_scram ( - cluster, stream, sd, MONGOC_CRYPTO_ALGORITHM_SHA_1, error); -#endif -} - -static bool -_mongoc_cluster_auth_node_scram_sha_256 (mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - bson_error_t *error) -{ -#ifndef MONGOC_ENABLE_CRYPTO - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "The SCRAM_SHA_256 authentication mechanism requires " - "libmongoc built with ENABLE_SSL"); - return false; -#else - return _mongoc_cluster_auth_node_scram ( - cluster, stream, sd, MONGOC_CRYPTO_ALGORITHM_SHA_256, error); -#endif -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cluster_auth_node -- - * - * Authenticate a cluster node depending on the required mechanism. - * - * Returns: - * true if authenticated. false on failure and @error is set. - * - * Side effects: - * @error is set on failure. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_cluster_auth_node ( - mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - mongoc_server_description_t *sd, - const mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs, - bson_error_t *error) -{ - bool ret = false; - const char *mechanism; - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (stream); - - mechanism = mongoc_uri_get_auth_mechanism (cluster->uri); - - if (!mechanism) { - if (sasl_supported_mechs->scram_sha_256) { - /* Auth spec: "If SCRAM-SHA-256 is present in the list of mechanisms, - * then it MUST be used as the default; otherwise, SCRAM-SHA-1 MUST be - * used as the default, regardless of whether SCRAM-SHA-1 is in the - * list. Drivers MUST NOT attempt to use any other mechanism (e.g. - * PLAIN) as the default." [...] "If saslSupportedMechs is not present - * in the isMaster results for mechanism negotiation, then SCRAM-SHA-1 - * MUST be used when talking to servers >= 3.0." */ - mechanism = "SCRAM-SHA-256"; - } else { - mechanism = "SCRAM-SHA-1"; - } - } - - if (0 == strcasecmp (mechanism, "MONGODB-CR")) { - ret = _mongoc_cluster_auth_node_cr (cluster, stream, sd, error); - } else if (0 == strcasecmp (mechanism, "MONGODB-X509")) { - ret = _mongoc_cluster_auth_node_x509 (cluster, stream, sd, error); - } else if (0 == strcasecmp (mechanism, "SCRAM-SHA-1")) { - ret = _mongoc_cluster_auth_node_scram_sha_1 (cluster, stream, sd, error); - } else if (0 == strcasecmp (mechanism, "SCRAM-SHA-256")) { - ret = - _mongoc_cluster_auth_node_scram_sha_256 (cluster, stream, sd, error); - } else if (0 == strcasecmp (mechanism, "GSSAPI")) { - ret = _mongoc_cluster_auth_node_sasl (cluster, stream, sd, error); - } else if (0 == strcasecmp (mechanism, "PLAIN")) { - ret = _mongoc_cluster_auth_node_plain (cluster, stream, sd, error); - } else { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "Unknown authentication mechanism \"%s\".", - mechanism); - } - - if (!ret) { - mongoc_counter_auth_failure_inc (); - MONGOC_DEBUG ("Authentication failed: %s", error->message); - } else { - mongoc_counter_auth_success_inc (); - TRACE ("%s", "Authentication succeeded"); - } - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_disconnect_node -- - * - * Remove a node from the set of nodes. This should be done if - * a stream in the set is found to be invalid. If @invalidate is - * true, also mark the server Unknown in the topology description, - * passing the error information from @why as the reason. - * - * WARNING: pointers to a disconnected mongoc_cluster_node_t or - * its stream are now invalid, be careful of dangling pointers. - * - * Returns: - * None. - * - * Side effects: - * Removes node from cluster's set of nodes, and frees the - * mongoc_cluster_node_t if pooled. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster, - uint32_t server_id, - bool invalidate, - const bson_error_t *why /* IN */) -{ - mongoc_topology_t *topology = cluster->client->topology; - - ENTRY; - - if (topology->single_threaded) { - mongoc_topology_scanner_node_t *scanner_node; - - scanner_node = - mongoc_topology_scanner_get_node (topology->scanner, server_id); - - /* might never actually have connected */ - if (scanner_node && scanner_node->stream) { - mongoc_topology_scanner_node_disconnect (scanner_node, true); - } - } else { - mongoc_set_rm (cluster->nodes, server_id); - } - - if (invalidate) { - mongoc_topology_invalidate_server (topology, server_id, why); - } - - EXIT; -} - -static void -_mongoc_cluster_node_destroy (mongoc_cluster_node_t *node) -{ - /* Failure, or Replica Set reconfigure without this node */ - mongoc_stream_failed (node->stream); - bson_free (node->connection_address); - - bson_free (node); -} - -static void -_mongoc_cluster_node_dtor (void *data_, void *ctx_) -{ - mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) data_; - - _mongoc_cluster_node_destroy (node); -} - -static mongoc_cluster_node_t * -_mongoc_cluster_node_new (mongoc_stream_t *stream, - const char *connection_address) -{ - mongoc_cluster_node_t *node; - - if (!stream) { - return NULL; - } - - node = (mongoc_cluster_node_t *) bson_malloc0 (sizeof *node); - - node->stream = stream; - node->connection_address = bson_strdup (connection_address); - node->timestamp = bson_get_monotonic_time (); - - node->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION; - node->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION; - - node->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE; - node->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE; - node->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE; - - return node; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_add_node -- - * - * Add a new node to this cluster for the given server description. - * - * NOTE: does NOT check if this server is already in the cluster. - * - * Returns: - * A stream connected to the server, or NULL on failure. - * - * Side effects: - * Adds a cluster node, or sets error on failure. - * - *-------------------------------------------------------------------------- - */ -static mongoc_stream_t * -_mongoc_cluster_add_node (mongoc_cluster_t *cluster, - uint32_t server_id, - bson_error_t *error /* OUT */) -{ - mongoc_host_list_t *host = NULL; - mongoc_cluster_node_t *cluster_node = NULL; - mongoc_stream_t *stream; - mongoc_server_description_t *sd; - mongoc_handshake_sasl_supported_mechs_t sasl_supported_mechs; - - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (!cluster->client->topology->single_threaded); - - host = - _mongoc_topology_host_by_id (cluster->client->topology, server_id, error); - - if (!host) { - GOTO (error); - } - - TRACE ("Adding new server to cluster: %s", host->host_and_port); - - stream = _mongoc_client_create_stream (cluster->client, host, error); - - if (!stream) { - MONGOC_WARNING ( - "Failed connection to %s (%s)", host->host_and_port, error->message); - GOTO (error); - } - - /* take critical fields from a fresh ismaster */ - cluster_node = _mongoc_cluster_node_new (stream, host->host_and_port); - - sd = _mongoc_cluster_run_ismaster (cluster, cluster_node, server_id, error); - if (!sd) { - GOTO (error); - } - - _mongoc_handshake_parse_sasl_supported_mechs (&sd->last_is_master, - &sasl_supported_mechs); - - if (cluster->requires_auth) { - if (!_mongoc_cluster_auth_node ( - cluster, cluster_node->stream, sd, &sasl_supported_mechs, error)) { - MONGOC_WARNING ("Failed authentication to %s (%s)", - host->host_and_port, - error->message); - mongoc_server_description_destroy (sd); - GOTO (error); - } - } - mongoc_server_description_destroy (sd); - - mongoc_set_add (cluster->nodes, server_id, cluster_node); - _mongoc_host_list_destroy_all (host); - - RETURN (stream); - -error: - _mongoc_host_list_destroy_all (host); /* null ok */ - - if (cluster_node) { - _mongoc_cluster_node_destroy (cluster_node); /* also destroys stream */ - } - - RETURN (NULL); -} - -static void -node_not_found (mongoc_topology_t *topology, - uint32_t server_id, - bson_error_t *error /* OUT */) -{ - mongoc_server_description_t *sd; - - if (!error) { - return; - } - - sd = mongoc_topology_server_by_id (topology, server_id, error); - - if (!sd) { - return; - } - - if (sd->error.code) { - memcpy (error, &sd->error, sizeof *error); - } else { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NOT_ESTABLISHED, - "Could not find node %s", - sd->host.host_and_port); - } - - mongoc_server_description_destroy (sd); -} - - -static void -stream_not_found (mongoc_topology_t *topology, - uint32_t server_id, - const char *connection_address, - bson_error_t *error /* OUT */) -{ - mongoc_server_description_t *sd; - - sd = mongoc_topology_server_by_id (topology, server_id, error); - - if (error) { - if (sd && sd->error.code) { - memcpy (error, &sd->error, sizeof *error); - } else { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NOT_ESTABLISHED, - "Could not find stream for node %s", - connection_address); - } - } - - if (sd) { - mongoc_server_description_destroy (sd); - } -} - -mongoc_server_stream_t * -_mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, - uint32_t server_id, - bool reconnect_ok, - const mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error /* OUT */) -{ - mongoc_topology_t *topology; - mongoc_server_stream_t *server_stream; - bson_error_t err_local; - /* if fetch_stream fails we need a place to receive error details and pass - * them to mongoc_topology_invalidate_server. */ - bson_error_t *err_ptr = error ? error : &err_local; - - ENTRY; - - topology = cluster->client->topology; - - /* in the single-threaded use case we share topology's streams */ - if (topology->single_threaded) { - server_stream = mongoc_cluster_fetch_stream_single ( - cluster, server_id, reconnect_ok, err_ptr); - } else { - server_stream = mongoc_cluster_fetch_stream_pooled ( - cluster, server_id, reconnect_ok, err_ptr); - } - - if (!server_stream) { - /* Server Discovery And Monitoring Spec: "When an application operation - * fails because of any network error besides a socket timeout, the - * client MUST replace the server's description with a default - * ServerDescription of type Unknown, and fill the ServerDescription's - * error field with useful information." - * - * error was filled by fetch_stream_single/pooled, pass it to disconnect() - */ - mongoc_cluster_disconnect_node (cluster, server_id, true, err_ptr); - _mongoc_bson_init_with_transient_txn_error (cs, reply); - } - - RETURN (server_stream); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_stream_for_server -- - * - * Fetch the stream for @server_id. If @reconnect_ok and there is no - * valid stream, attempts to reconnect; if not @reconnect_ok then only - * an existing stream can be returned, or NULL. - * - * Returns: - * A mongoc_server_stream_t, or NULL - * - * Side effects: - * May add a node or reconnect one, if @reconnect_ok. - * Authenticates the stream if needed. - * Sets @error and initializes @reply on error. - * - *-------------------------------------------------------------------------- - */ - -mongoc_server_stream_t * -mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, - uint32_t server_id, - bool reconnect_ok, - mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error) -{ - mongoc_server_stream_t *server_stream = NULL; - bson_error_t err_local = {0}; - - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (server_id); - - if (cs && cs->server_id && cs->server_id != server_id) { - _mongoc_bson_init_if_set (reply); - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_SERVER_SELECTION_INVALID_ID, - "Requested server id does not matched pinned server id"); - RETURN (NULL); - } - - if (!error) { - error = &err_local; - } - - server_stream = _mongoc_cluster_stream_for_server ( - cluster, server_id, reconnect_ok, cs, reply, error); - - if (!server_stream) { - /* failed */ - mongoc_cluster_disconnect_node (cluster, server_id, true, error); - } - - if (_in_sharded_txn (cs)) { - _mongoc_client_session_pin (cs, server_id); - } else { - /* Transactions Spec: Additionally, any non-transaction operation using - * a pinned ClientSession MUST unpin the session and the operation MUST - * perform normal server selection. */ - if (cs && !_mongoc_client_session_in_txn_or_ending (cs)) { - _mongoc_client_session_unpin (cs); - } - } - - RETURN (server_stream); -} - - -static mongoc_server_stream_t * -mongoc_cluster_fetch_stream_single (mongoc_cluster_t *cluster, - uint32_t server_id, - bool reconnect_ok, - bson_error_t *error /* OUT */) -{ - mongoc_topology_t *topology; - mongoc_server_description_t *sd; - mongoc_topology_scanner_node_t *scanner_node; - char *address; - - topology = cluster->client->topology; - scanner_node = - mongoc_topology_scanner_get_node (topology->scanner, server_id); - BSON_ASSERT (scanner_node && !scanner_node->retired); - - if (scanner_node->stream) { - sd = mongoc_topology_server_by_id (topology, server_id, error); - - if (!sd) { - return NULL; - } - } else { - if (!reconnect_ok) { - stream_not_found ( - topology, server_id, scanner_node->host.host_and_port, error); - return NULL; - } - - /* save the scanner node address in case it is removed during the scan. */ - address = bson_strdup (scanner_node->host.host_and_port); - _mongoc_topology_do_blocking_scan (topology, error); - if (error->code) { - bson_free (address); - return NULL; - } - - scanner_node = - mongoc_topology_scanner_get_node (topology->scanner, server_id); - - if (!scanner_node || !scanner_node->stream) { - stream_not_found (topology, server_id, address, error); - bson_free (address); - return NULL; - } - bson_free (address); - - sd = mongoc_topology_server_by_id (topology, server_id, error); - if (!sd) { - return NULL; - } - } - - if (sd->type == MONGOC_SERVER_UNKNOWN) { - memcpy (error, &sd->error, sizeof *error); - mongoc_server_description_destroy (sd); - return NULL; - } - - /* stream open but not auth'ed: first use since connect or reconnect */ - if (cluster->requires_auth && !scanner_node->has_auth) { - if (!_mongoc_cluster_auth_node (cluster, - scanner_node->stream, - sd, - &scanner_node->sasl_supported_mechs, - &sd->error)) { - memcpy (error, &sd->error, sizeof *error); - mongoc_server_description_destroy (sd); - return NULL; - } - - scanner_node->has_auth = true; - } - - return mongoc_server_stream_new ( - &topology->description, sd, scanner_node->stream); -} - - -mongoc_server_stream_t * -_mongoc_cluster_create_server_stream (mongoc_topology_t *topology, - uint32_t server_id, - mongoc_stream_t *stream, - bson_error_t *error /* OUT */) -{ - mongoc_server_description_t *sd; - mongoc_server_stream_t *server_stream = NULL; - - /* can't just use mongoc_topology_server_by_id(), since we must hold the - * lock while copying topology->description.logical_time below */ - bson_mutex_lock (&topology->mutex); - - sd = mongoc_server_description_new_copy ( - mongoc_topology_description_server_by_id ( - &topology->description, server_id, error)); - - if (sd) { - server_stream = - mongoc_server_stream_new (&topology->description, sd, stream); - } - - bson_mutex_unlock (&topology->mutex); - - return server_stream; -} - - -static mongoc_server_stream_t * -mongoc_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster, - uint32_t server_id, - bool reconnect_ok, - bson_error_t *error /* OUT */) -{ - mongoc_topology_t *topology; - mongoc_stream_t *stream; - mongoc_cluster_node_t *cluster_node; - int64_t timestamp; - - cluster_node = - (mongoc_cluster_node_t *) mongoc_set_get (cluster->nodes, server_id); - - topology = cluster->client->topology; - - if (cluster_node) { - BSON_ASSERT (cluster_node->stream); - - timestamp = mongoc_topology_server_timestamp (topology, server_id); - if (timestamp == -1 || cluster_node->timestamp < timestamp) { - /* topology change or net error during background scan made us remove - * or replace server description since node's birth. destroy node. */ - mongoc_cluster_disconnect_node ( - cluster, server_id, false /* invalidate */, NULL); - } else { - return _mongoc_cluster_create_server_stream ( - topology, server_id, cluster_node->stream, error); - } - } - - /* no node, or out of date */ - if (!reconnect_ok) { - node_not_found (topology, server_id, error); - return NULL; - } - - stream = _mongoc_cluster_add_node (cluster, server_id, error); - if (stream) { - return _mongoc_cluster_create_server_stream ( - topology, server_id, stream, error); - } else { - return NULL; - } -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_init -- - * - * Initializes @cluster using the @uri and @client provided. The - * @uri is used to determine the "mode" of the cluster. Based on the - * uri we can determine if we are connected to a single host, a - * replicaSet, or a shardedCluster. - * - * Returns: - * None. - * - * Side effects: - * @cluster is initialized. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_cluster_init (mongoc_cluster_t *cluster, - const mongoc_uri_t *uri, - void *client) -{ - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (uri); - - memset (cluster, 0, sizeof *cluster); - - cluster->uri = mongoc_uri_copy (uri); - cluster->client = (mongoc_client_t *) client; - cluster->requires_auth = - (mongoc_uri_get_username (uri) || mongoc_uri_get_auth_mechanism (uri)); - - cluster->sockettimeoutms = mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_SOCKETTIMEOUTMS, MONGOC_DEFAULT_SOCKETTIMEOUTMS); - - cluster->socketcheckintervalms = - mongoc_uri_get_option_as_int32 (uri, - MONGOC_URI_SOCKETCHECKINTERVALMS, - MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS); - - /* TODO for single-threaded case we don't need this */ - cluster->nodes = mongoc_set_new (8, _mongoc_cluster_node_dtor, NULL); - - _mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t)); - - cluster->operation_id = rand (); - - EXIT; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_destroy -- - * - * Clean up after @cluster and destroy all active connections. - * All resources for @cluster are released. - * - * Returns: - * None. - * - * Side effects: - * Everything. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_cluster_destroy (mongoc_cluster_t *cluster) /* INOUT */ -{ - ENTRY; - - BSON_ASSERT (cluster); - - mongoc_uri_destroy (cluster->uri); - - mongoc_set_destroy (cluster->nodes); - - _mongoc_array_destroy (&cluster->iov); - -#ifdef MONGOC_ENABLE_CRYPTO - if (cluster->scram_cache) { - _mongoc_scram_cache_destroy (cluster->scram_cache); - } -#endif - - EXIT; -} - -static uint32_t -_mongoc_cluster_select_server_id (mongoc_client_session_t *cs, - mongoc_topology_t *topology, - mongoc_ss_optype_t optype, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) -{ - uint32_t server_id; - - if (_in_sharded_txn (cs)) { - server_id = cs->server_id; - if (!server_id) { - server_id = mongoc_topology_select_server_id ( - topology, optype, read_prefs, error); - if (server_id) { - _mongoc_client_session_pin (cs, server_id); - } - } - } else { - server_id = - mongoc_topology_select_server_id (topology, optype, read_prefs, error); - /* Transactions Spec: Additionally, any non-transaction operation using a - * pinned ClientSession MUST unpin the session and the operation MUST - * perform normal server selection. */ - if (cs && !_mongoc_client_session_in_txn_or_ending (cs)) { - _mongoc_client_session_unpin (cs); - } - } - - return server_id; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_stream_for_optype -- - * - * Internal server selection. - * - * Returns: - * A mongoc_server_stream_t on which you must call - * mongoc_server_stream_cleanup, or NULL on failure (sets @error) - * - * Side effects: - * May add or disconnect nodes in @cluster->nodes. - * Sets @error and initializes @reply on error. - * - *-------------------------------------------------------------------------- - */ - -static mongoc_server_stream_t * -_mongoc_cluster_stream_for_optype (mongoc_cluster_t *cluster, - mongoc_ss_optype_t optype, - const mongoc_read_prefs_t *read_prefs, - mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error) -{ - mongoc_server_stream_t *server_stream; - uint32_t server_id; - mongoc_topology_t *topology = cluster->client->topology; - - ENTRY; - - BSON_ASSERT (cluster); - - server_id = _mongoc_cluster_select_server_id ( - cs, topology, optype, read_prefs, error); - - if (!server_id) { - _mongoc_bson_init_with_transient_txn_error (cs, reply); - RETURN (NULL); - } - - if (!mongoc_cluster_check_interval (cluster, server_id)) { - /* Server Selection Spec: try once more */ - server_id = _mongoc_cluster_select_server_id ( - cs, topology, optype, read_prefs, error); - - if (!server_id) { - _mongoc_bson_init_with_transient_txn_error (cs, reply); - RETURN (NULL); - } - } - - /* connect or reconnect to server if necessary */ - server_stream = _mongoc_cluster_stream_for_server ( - cluster, server_id, true /* reconnect_ok */, cs, reply, error); - - RETURN (server_stream); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_stream_for_reads -- - * - * Internal server selection. - * - * Returns: - * A mongoc_server_stream_t on which you must call - * mongoc_server_stream_cleanup, or NULL on failure (sets @error) - * - * Side effects: - * Sets @error and initializes @reply on error. - * May add new nodes to @cluster->nodes. - * - *-------------------------------------------------------------------------- - */ - -mongoc_server_stream_t * -mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster, - const mongoc_read_prefs_t *read_prefs, - mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error) -{ - const mongoc_read_prefs_t *prefs_override = read_prefs; - - if (_mongoc_client_session_in_txn (cs)) { - prefs_override = cs->txn.opts.read_prefs; - } - - return _mongoc_cluster_stream_for_optype ( - cluster, MONGOC_SS_READ, prefs_override, cs, reply, error); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_stream_for_writes -- - * - * Get a stream for write operations. - * - * Returns: - * A mongoc_server_stream_t on which you must call - * mongoc_server_stream_cleanup, or NULL on failure (sets @error) - * - * Side effects: - * Sets @error and initializes @reply on error. - * May add new nodes to @cluster->nodes. - * - *-------------------------------------------------------------------------- - */ - -mongoc_server_stream_t * -mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster, - mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_cluster_stream_for_optype ( - cluster, MONGOC_SS_WRITE, NULL, cs, reply, error); -} - -static bool -_mongoc_cluster_min_of_max_obj_size_sds (void *item, void *ctx) -{ - mongoc_server_description_t *sd = (mongoc_server_description_t *) item; - int32_t *current_min = (int32_t *) ctx; - - if (sd->max_bson_obj_size < *current_min) { - *current_min = sd->max_bson_obj_size; - } - return true; -} - -static bool -_mongoc_cluster_min_of_max_obj_size_nodes (void *item, void *ctx) -{ - mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) item; - int32_t *current_min = (int32_t *) ctx; - - if (node->max_bson_obj_size < *current_min) { - *current_min = node->max_bson_obj_size; - } - return true; -} - -static bool -_mongoc_cluster_min_of_max_msg_size_sds (void *item, void *ctx) -{ - mongoc_server_description_t *sd = (mongoc_server_description_t *) item; - int32_t *current_min = (int32_t *) ctx; - - if (sd->max_msg_size < *current_min) { - *current_min = sd->max_msg_size; - } - return true; -} - -static bool -_mongoc_cluster_min_of_max_msg_size_nodes (void *item, void *ctx) -{ - mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) item; - int32_t *current_min = (int32_t *) ctx; - - if (node->max_msg_size < *current_min) { - *current_min = node->max_msg_size; - } - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_get_max_bson_obj_size -- - * - * Return the minimum max_bson_obj_size across all servers in cluster. - * - * NOTE: this method uses the topology's mutex. - * - * Returns: - * The minimum max_bson_obj_size. - * - * Side effects: - * None - * - *-------------------------------------------------------------------------- - */ -int32_t -mongoc_cluster_get_max_bson_obj_size (mongoc_cluster_t *cluster) -{ - int32_t max_bson_obj_size = -1; - - max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE; - - if (!cluster->client->topology->single_threaded) { - mongoc_set_for_each (cluster->nodes, - _mongoc_cluster_min_of_max_obj_size_nodes, - &max_bson_obj_size); - } else { - mongoc_set_for_each (cluster->client->topology->description.servers, - _mongoc_cluster_min_of_max_obj_size_sds, - &max_bson_obj_size); - } - - return max_bson_obj_size; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_get_max_msg_size -- - * - * Return the minimum max msg size across all servers in cluster. - * - * NOTE: this method uses the topology's mutex. - * - * Returns: - * The minimum max_msg_size - * - * Side effects: - * None - * - *-------------------------------------------------------------------------- - */ -int32_t -mongoc_cluster_get_max_msg_size (mongoc_cluster_t *cluster) -{ - int32_t max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE; - - if (!cluster->client->topology->single_threaded) { - mongoc_set_for_each (cluster->nodes, - _mongoc_cluster_min_of_max_msg_size_nodes, - &max_msg_size); - } else { - mongoc_set_for_each (cluster->client->topology->description.servers, - _mongoc_cluster_min_of_max_msg_size_sds, - &max_msg_size); - } - - return max_msg_size; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_check_interval -- - * - * Server Selection Spec: - * - * Only for single-threaded drivers. - * - * If a server is selected that has an existing connection that has been - * idle for socketCheckIntervalMS, the driver MUST check the connection - * with the "ping" command. If the ping succeeds, use the selected - * connection. If not, set the server's type to Unknown and update the - * Topology Description according to the Server Discovery and Monitoring - * Spec, and attempt once more to select a server. - * - * Returns: - * True if the check succeeded or no check was required, false if the - * check failed. - * - * Side effects: - * If a check fails, closes stream and may set server type Unknown. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id) -{ - mongoc_cmd_parts_t parts; - mongoc_topology_t *topology; - mongoc_topology_scanner_node_t *scanner_node; - mongoc_stream_t *stream; - int64_t now; - bson_t command; - bson_error_t error; - bool r = true; - mongoc_server_stream_t *server_stream; - - topology = cluster->client->topology; - - if (!topology->single_threaded) { - return true; - } - - scanner_node = - mongoc_topology_scanner_get_node (topology->scanner, server_id); - - if (!scanner_node) { - return false; - } - - BSON_ASSERT (!scanner_node->retired); - - stream = scanner_node->stream; - - if (!stream) { - return false; - } - - now = bson_get_monotonic_time (); - - if (scanner_node->last_used + (1000 * CHECK_CLOSED_DURATION_MSEC) < now) { - if (mongoc_stream_check_closed (stream)) { - bson_set_error (&error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "connection closed"); - mongoc_cluster_disconnect_node (cluster, server_id, true, &error); - return false; - } - } - - if (scanner_node->last_used + (1000 * cluster->socketcheckintervalms) < - now) { - bson_init (&command); - BSON_APPEND_INT32 (&command, "ping", 1); - mongoc_cmd_parts_init ( - &parts, cluster->client, "admin", MONGOC_QUERY_SLAVE_OK, &command); - parts.prohibit_lsid = true; - server_stream = _mongoc_cluster_create_server_stream ( - cluster->client->topology, server_id, stream, &error); - r = mongoc_cluster_run_command_parts ( - cluster, server_stream, &parts, NULL, &error); - - mongoc_server_stream_cleanup (server_stream); - bson_destroy (&command); - - if (!r) { - mongoc_cluster_disconnect_node (cluster, server_id, true, &error); - } - } - - return r; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_legacy_rpc_sendv_to_server -- - * - * Sends the given RPCs to the given server. Used for OP_QUERY cursors, - * OP_KILLCURSORS, and legacy writes with OP_INSERT, OP_UPDATE, and - * OP_DELETE. This function is *not* in the OP_QUERY command path. - * - * Returns: - * True if successful. - * - * Side effects: - * @rpc may be mutated and should be considered invalid after calling - * this method. - * - * @error may be set. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cluster_legacy_rpc_sendv_to_server ( - mongoc_cluster_t *cluster, - mongoc_rpc_t *rpc, - mongoc_server_stream_t *server_stream, - bson_error_t *error) -{ - uint32_t server_id; - int32_t max_msg_size; - bool ret = false; - int32_t compressor_id = 0; - char *output = NULL; - - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (rpc); - BSON_ASSERT (server_stream); - - server_id = server_stream->sd->id; - - if (cluster->client->in_exhaust) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_IN_EXHAUST, - "A cursor derived from this client is in exhaust."); - GOTO (done); - } - - _mongoc_array_clear (&cluster->iov); - compressor_id = mongoc_server_description_compressor_id (server_stream->sd); - - _mongoc_rpc_gather (rpc, &cluster->iov); - _mongoc_rpc_swab_to_le (rpc); - - if (compressor_id != -1) { - output = _mongoc_rpc_compress (cluster, compressor_id, rpc, error); - if (output == NULL) { - GOTO (done); - } - } - - max_msg_size = mongoc_server_stream_max_msg_size (server_stream); - - if (BSON_UINT32_FROM_LE (rpc->header.msg_len) > max_msg_size) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_TOO_BIG, - "Attempted to send an RPC larger than the " - "max allowed message size. Was %u, allowed %u.", - BSON_UINT32_FROM_LE (rpc->header.msg_len), - max_msg_size); - GOTO (done); - } - - if (!_mongoc_stream_writev_full (server_stream->stream, - cluster->iov.data, - cluster->iov.len, - cluster->sockettimeoutms, - error)) { - GOTO (done); - } - - _mongoc_topology_update_last_used (cluster->client->topology, server_id); - - ret = true; - -done: - - if (compressor_id) { - bson_free (output); - } - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cluster_try_recv -- - * - * Tries to receive the next event from the MongoDB server. - * The contents are loaded into @buffer and then - * scattered into the @rpc structure. @rpc is valid as long as - * @buffer contains the contents read into it. - * - * Callers that can optimize a reuse of @buffer should do so. It - * can save many memory allocations. - * - * Returns: - * True if successful. - * - * Side effects: - * @rpc is set on success, @error on failure. - * @buffer will be filled with the input data. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cluster_try_recv (mongoc_cluster_t *cluster, - mongoc_rpc_t *rpc, - mongoc_buffer_t *buffer, - mongoc_server_stream_t *server_stream, - bson_error_t *error) -{ - uint32_t server_id; - bson_error_t err_local; - int32_t msg_len; - int32_t max_msg_size; - off_t pos; - - ENTRY; - - BSON_ASSERT (cluster); - BSON_ASSERT (rpc); - BSON_ASSERT (buffer); - BSON_ASSERT (server_stream); - - server_id = server_stream->sd->id; - - TRACE ("Waiting for reply from server_id \"%u\"", server_id); - - if (!error) { - error = &err_local; - } - - /* - * Buffer the message length to determine how much more to read. - */ - pos = buffer->len; - if (!_mongoc_buffer_append_from_stream ( - buffer, server_stream->stream, 4, cluster->sockettimeoutms, error)) { - MONGOC_DEBUG ( - "Could not read 4 bytes, stream probably closed or timed out"); - mongoc_counter_protocol_ingress_error_inc (); - mongoc_cluster_disconnect_node ( - cluster, - server_id, - !mongoc_stream_timed_out (server_stream->stream), - error); - RETURN (false); - } - - /* - * Read the msg length from the buffer. - */ - memcpy (&msg_len, &buffer->data[pos], 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - max_msg_size = mongoc_server_stream_max_msg_size (server_stream); - if ((msg_len < 16) || (msg_len > max_msg_size)) { - bson_set_error (error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Corrupt or malicious reply received."); - mongoc_cluster_disconnect_node (cluster, server_id, true, error); - mongoc_counter_protocol_ingress_error_inc (); - RETURN (false); - } - - /* - * Read the rest of the message from the stream. - */ - if (!_mongoc_buffer_append_from_stream (buffer, - server_stream->stream, - msg_len - 4, - cluster->sockettimeoutms, - error)) { - mongoc_cluster_disconnect_node ( - cluster, - server_id, - !mongoc_stream_timed_out (server_stream->stream), - error); - mongoc_counter_protocol_ingress_error_inc (); - RETURN (false); - } - - /* - * Scatter the buffer into the rpc structure. - */ - if (!_mongoc_rpc_scatter (rpc, &buffer->data[pos], msg_len)) { - bson_set_error (error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Failed to decode reply from server."); - mongoc_cluster_disconnect_node (cluster, server_id, true, error); - mongoc_counter_protocol_ingress_error_inc (); - RETURN (false); - } - - if (BSON_UINT32_FROM_LE (rpc->header.opcode) == MONGOC_OPCODE_COMPRESSED) { - uint8_t *buf = NULL; - size_t len = BSON_UINT32_FROM_LE (rpc->compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); - - buf = bson_malloc0 (len); - if (!_mongoc_rpc_decompress (rpc, buf, len)) { - bson_free (buf); - bson_set_error (error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress server reply"); - RETURN (false); - } - - _mongoc_buffer_destroy (buffer); - _mongoc_buffer_init (buffer, buf, len, NULL, NULL); - } - _mongoc_rpc_swab_from_le (rpc); - - RETURN (true); -} - - -static void -network_error_reply (bson_t *reply, mongoc_cmd_t *cmd) -{ - bson_t labels; - - if (reply) { - bson_init (reply); - } - /* Transactions Spec defines TransientTransactionError: "Any - * network error or server selection error encountered running any - * command besides commitTransaction in a transaction. In the case - * of command errors, the server adds the label; in the case of - * network errors or server selection errors where the client - * receives no server reply, the client adds the label." */ - if (_mongoc_client_session_in_txn (cmd->session) && !cmd->is_txn_finish) { - /* Transaction Spec: "Drivers MUST unpin a ClientSession when a command - * within a transaction, including commitTransaction and abortTransaction, - * fails with a TransientTransactionError". If we're about to add - * a TransientTransactionError label due to a client side error then we - * unpin. If commitTransaction/abortTransation includes a label in the - * server reply, we unpin in _mongoc_client_session_handle_reply. */ - cmd->session->server_id = 0; - if (!reply) { - return; - } - - BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels); - BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR); - bson_append_array_end (reply, &labels); - } -} - - -static bool -mongoc_cluster_run_opmsg (mongoc_cluster_t *cluster, - mongoc_cmd_t *cmd, - bson_t *reply, - bson_error_t *error) -{ - mongoc_rpc_section_t section[2]; - mongoc_buffer_t buffer; - bson_t reply_local; /* only statically initialized */ - char *output = NULL; - mongoc_rpc_t rpc; - int32_t msg_len; - bool ok; - const mongoc_server_stream_t *server_stream; - - server_stream = cmd->server_stream; - if (!cmd->command_name) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Empty command document"); - _mongoc_bson_init_if_set (reply); - return false; - } - if (cluster->client->in_exhaust) { - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_IN_EXHAUST, - "A cursor derived from this client is in exhaust."); - _mongoc_bson_init_if_set (reply); - return false; - } - - _mongoc_array_clear (&cluster->iov); - _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); - - rpc.header.msg_len = 0; - rpc.header.request_id = ++cluster->request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_MSG; - - if (cmd->is_acknowledged) { - rpc.msg.flags = 0; - } else { - rpc.msg.flags = MONGOC_MSG_MORE_TO_COME; - } - - rpc.msg.n_sections = 1; - - section[0].payload_type = 0; - section[0].payload.bson_document = bson_get_data (cmd->command); - rpc.msg.sections[0] = section[0]; - - if (cmd->payload) { - section[1].payload_type = 1; - section[1].payload.sequence.size = cmd->payload_size + - strlen (cmd->payload_identifier) + 1 + - sizeof (int32_t); - section[1].payload.sequence.identifier = cmd->payload_identifier; - section[1].payload.sequence.bson_documents = cmd->payload; - rpc.msg.sections[1] = section[1]; - rpc.msg.n_sections++; - } - - _mongoc_rpc_gather (&rpc, &cluster->iov); - _mongoc_rpc_swab_to_le (&rpc); - - if (mongoc_cmd_is_compressible (cmd)) { - int32_t compressor_id = - mongoc_server_description_compressor_id (server_stream->sd); - - TRACE ( - "Function '%s' is compressible: %d", cmd->command_name, compressor_id); - if (compressor_id != -1) { - output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error); - if (output == NULL) { - _mongoc_bson_init_if_set (reply); - _mongoc_buffer_destroy (&buffer); - return false; - } - } - } - ok = _mongoc_stream_writev_full (server_stream->stream, - (mongoc_iovec_t *) cluster->iov.data, - cluster->iov.len, - cluster->sockettimeoutms, - error); - if (!ok) { - /* add info about the command to writev_full's error message */ - RUN_CMD_ERR_DECORATE; - mongoc_cluster_disconnect_node ( - cluster, server_stream->sd->id, true, error); - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } - - /* If acknowledged, wait for a server response. Otherwise, exit early */ - if (cmd->is_acknowledged) { - ok = _mongoc_buffer_append_from_stream ( - &buffer, server_stream->stream, 4, cluster->sockettimeoutms, error); - if (!ok) { - RUN_CMD_ERR_DECORATE; - mongoc_cluster_disconnect_node ( - cluster, server_stream->sd->id, true, error); - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } - - BSON_ASSERT (buffer.len == 4); - memcpy (&msg_len, buffer.data, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - if ((msg_len < 16) || (msg_len > server_stream->sd->max_msg_size)) { - RUN_CMD_ERR ( - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Message size %d is not within expected range 16-%d bytes", - msg_len, - server_stream->sd->max_msg_size); - mongoc_cluster_disconnect_node ( - cluster, server_stream->sd->id, true, error); - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } - - ok = _mongoc_buffer_append_from_stream (&buffer, - server_stream->stream, - (size_t) msg_len - 4, - cluster->sockettimeoutms, - error); - if (!ok) { - RUN_CMD_ERR_DECORATE; - mongoc_cluster_disconnect_node ( - cluster, server_stream->sd->id, true, error); - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } - - ok = _mongoc_rpc_scatter (&rpc, buffer.data, buffer.len); - if (!ok) { - RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Malformed message from server"); - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } - if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) { - size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) + - sizeof (mongoc_rpc_header_t); - - output = bson_realloc (output, len); - if (!_mongoc_rpc_decompress (&rpc, (uint8_t *) output, len)) { - RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Could not decompress message from server"); - mongoc_cluster_disconnect_node ( - cluster, server_stream->sd->id, true, error); - bson_free (output); - network_error_reply (reply, cmd); - _mongoc_buffer_destroy (&buffer); - return false; - } - } - _mongoc_rpc_swab_from_le (&rpc); - - memcpy (&msg_len, rpc.msg.sections[0].payload.bson_document, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - bson_init_static ( - &reply_local, rpc.msg.sections[0].payload.bson_document, msg_len); - - _mongoc_topology_update_cluster_time (cluster->client->topology, - &reply_local); - ok = _mongoc_cmd_check_ok ( - &reply_local, cluster->client->error_api_version, error); - - if (cmd->session) { - _mongoc_client_session_handle_reply ( - cmd->session, cmd->is_acknowledged, &reply_local); - } - - if (reply) { - bson_copy_to (&reply_local, reply); - } - } else { - _mongoc_bson_init_if_set (reply); - } - - _mongoc_buffer_destroy (&buffer); - bson_free (output); - - return ok; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cmd-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-cmd-private.h deleted file mode 100644 index 68079c9839d146c18525b60fa5879738f7010fc2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cmd-private.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - - -/* - * Internal struct to represent a command we will send to the server - command - * parameters are collected in a mongoc_cmd_parts_t until we know the server's - * wire version and whether it is mongos, then we collect the parts into a - * mongoc_cmd_t, and gather that into a mongoc_rpc_t. - */ - -#ifndef MONGOC_CMD_PRIVATE_H -#define MONGOC_CMD_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-server-stream-private.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-opts-private.h" - -BSON_BEGIN_DECLS - -#define MONGOC_DEFAULT_RETRYREADS true -/* retryWrites requires sessions, which require crypto */ -#ifdef MONGOC_ENABLE_CRYPTO -#define MONGOC_DEFAULT_RETRYWRITES true -#else -#define MONGOC_DEFAULT_RETRYWRITES false -#endif - -typedef enum { - MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN, - MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES, - MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_NO -} mongoc_cmd_parts_allow_txn_number_t; - -typedef struct _mongoc_cmd_t { - const char *db_name; - mongoc_query_flags_t query_flags; - const bson_t *command; - const char *command_name; - const uint8_t *payload; - int32_t payload_size; - const char *payload_identifier; - const mongoc_server_stream_t *server_stream; - int64_t operation_id; - mongoc_client_session_t *session; - bool is_acknowledged; - bool is_txn_finish; -} mongoc_cmd_t; - - -typedef struct _mongoc_cmd_parts_t { - mongoc_cmd_t assembled; - mongoc_query_flags_t user_query_flags; - const bson_t *body; - bson_t read_concern_document; - bson_t write_concern_document; - bson_t extra; - const mongoc_read_prefs_t *read_prefs; - bson_t assembled_body; - bool is_read_command; - bool is_write_command; - bool prohibit_lsid; - mongoc_cmd_parts_allow_txn_number_t allow_txn_number; - bool is_retryable_read; - bool is_retryable_write; - bool has_temp_session; - mongoc_client_t *client; -} mongoc_cmd_parts_t; - - -void -mongoc_cmd_parts_init (mongoc_cmd_parts_t *op, - mongoc_client_t *client, - const char *db_name, - mongoc_query_flags_t user_query_flags, - const bson_t *command_body); - -void -mongoc_cmd_parts_set_session (mongoc_cmd_parts_t *parts, - mongoc_client_session_t *cs); - -bool -mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, - bson_iter_t *iter, - int max_wire_version, - bson_error_t *error); - -bool -mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts, - const mongoc_read_concern_t *rc, - int max_wire_version, - bson_error_t *error); - -bool -mongoc_cmd_parts_set_write_concern (mongoc_cmd_parts_t *parts, - const mongoc_write_concern_t *wc, - int max_wire_version, - bson_error_t *error); - -bool -mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts, - mongoc_read_write_opts_t *rw_opts, - int max_wire_version, - bson_error_t *error); - -bool -mongoc_cmd_parts_assemble (mongoc_cmd_parts_t *parts, - const mongoc_server_stream_t *server_stream, - bson_error_t *error); - -bool -mongoc_cmd_is_compressible (mongoc_cmd_t *cmd); - -void -mongoc_cmd_parts_cleanup (mongoc_cmd_parts_t *op); - -bool -_is_retryable_read (const mongoc_cmd_parts_t *parts, - const mongoc_server_stream_t *server_stream); - -void -_mongoc_cmd_append_payload_as_array (const mongoc_cmd_t* cmd, bson_t *out); - -BSON_END_DECLS - - -#endif /* MONGOC_CMD_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cmd.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cmd.c deleted file mode 100644 index 864bb0fe76ab3352e1f95218bf92cfb9b77278b9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cmd.c +++ /dev/null @@ -1,1077 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-cmd-private.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-write-concern-private.h" -/* For strcasecmp on Windows */ -#include "mongoc/mongoc-util-private.h" - - -void -mongoc_cmd_parts_init (mongoc_cmd_parts_t *parts, - mongoc_client_t *client, - const char *db_name, - mongoc_query_flags_t user_query_flags, - const bson_t *command_body) -{ - parts->body = command_body; - parts->user_query_flags = user_query_flags; - parts->read_prefs = NULL; - parts->is_read_command = false; - parts->is_write_command = false; - parts->prohibit_lsid = false; - parts->allow_txn_number = MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN; - parts->is_retryable_read = false; - parts->is_retryable_write = false; - parts->has_temp_session = false; - parts->client = client; - bson_init (&parts->read_concern_document); - bson_init (&parts->write_concern_document); - bson_init (&parts->extra); - bson_init (&parts->assembled_body); - - parts->assembled.db_name = db_name; - parts->assembled.command = NULL; - parts->assembled.query_flags = MONGOC_QUERY_NONE; - parts->assembled.payload_identifier = NULL; - parts->assembled.payload = NULL; - parts->assembled.session = NULL; - parts->assembled.is_acknowledged = true; - parts->assembled.is_txn_finish = false; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cmd_parts_set_session -- - * - * Set the client session field. - * - * Side effects: - * Aborts if the command is assembled or if mongoc_cmd_parts_append_opts - * was called before. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_cmd_parts_set_session (mongoc_cmd_parts_t *parts, - mongoc_client_session_t *cs) -{ - BSON_ASSERT (parts); - BSON_ASSERT (!parts->assembled.command); - BSON_ASSERT (!parts->assembled.session); - - parts->assembled.session = cs; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cmd_parts_append_opts -- - * - * Take an iterator over user-supplied options document and append the - * options to @parts->command_extra, taking the selected server's max - * wire version into account. - * - * Return: - * True if the options were successfully applied. If any options are - * invalid, returns false and fills out @error. In that case @parts is - * invalid and must not be used. - * - * Side effects: - * May partly apply options before returning an error. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, - bson_iter_t *iter, - int max_wire_version, - bson_error_t *error) -{ - mongoc_client_session_t *cs = NULL; - mongoc_write_concern_t *wc; - uint32_t len; - const uint8_t *data; - bson_t read_concern; - - ENTRY; - - /* not yet assembled */ - BSON_ASSERT (!parts->assembled.command); - - while (bson_iter_next (iter)) { - if (BSON_ITER_IS_KEY (iter, "collation")) { - if (max_wire_version < WIRE_VERSION_COLLATION) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - RETURN (false); - } - - } else if (BSON_ITER_IS_KEY (iter, "writeConcern")) { - wc = _mongoc_write_concern_new_from_iter (iter, error); - if (!wc) { - RETURN (false); - } - - if (!mongoc_cmd_parts_set_write_concern ( - parts, wc, max_wire_version, error)) { - mongoc_write_concern_destroy (wc); - RETURN (false); - } - - mongoc_write_concern_destroy (wc); - continue; - } else if (BSON_ITER_IS_KEY (iter, "readConcern")) { - if (max_wire_version < WIRE_VERSION_READ_CONCERN) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support readConcern"); - RETURN (false); - } - - if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "Invalid readConcern"); - RETURN (false); - } - - /* add readConcern later, once we know about causal consistency */ - bson_iter_document (iter, &len, &data); - BSON_ASSERT (bson_init_static (&read_concern, data, (size_t) len)); - bson_destroy (&parts->read_concern_document); - bson_copy_to (&read_concern, &parts->read_concern_document); - continue; - } else if (BSON_ITER_IS_KEY (iter, "sessionId")) { - BSON_ASSERT (!parts->assembled.session); - - if (!_mongoc_client_session_from_iter ( - parts->client, iter, &cs, error)) { - RETURN (false); - } - - parts->assembled.session = cs; - continue; - } else if (BSON_ITER_IS_KEY (iter, "serverId") || - BSON_ITER_IS_KEY (iter, "maxAwaitTimeMS")) { - continue; - } - - if (!bson_append_iter (&parts->extra, bson_iter_key (iter), -1, iter)) { - RETURN (false); - } - } - - RETURN (true); -} - - -#define OPTS_ERR(_code, ...) \ - do { \ - bson_set_error ( \ - error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_##_code, __VA_ARGS__); \ - RETURN (false); \ - } while (0) - - -/* set readConcern if allowed, otherwise error */ -bool -mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts, - const mongoc_read_concern_t *rc, - int max_wire_version, - bson_error_t *error) -{ - const char *command_name; - - ENTRY; - - /* In a txn, set read concern in mongoc_cmd_parts_assemble, not here. * - * Transactions Spec: "The readConcern MUST NOT be inherited from the - * collection, database, or client associated with the driver method that - * invokes the first command." */ - if (_mongoc_client_session_in_txn (parts->assembled.session)) { - RETURN (true); - } - - command_name = _mongoc_get_command_name (parts->body); - - if (!command_name) { - OPTS_ERR (COMMAND_INVALID_ARG, "Empty command document"); - } - - if (mongoc_read_concern_is_default (rc)) { - RETURN (true); - } - - if (max_wire_version < WIRE_VERSION_READ_CONCERN) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "\"%s\" command does not support readConcern with " - "wire version %d, wire version %d is required", - command_name, - max_wire_version, - WIRE_VERSION_READ_CONCERN); - RETURN (false); - } - - bson_destroy (&parts->read_concern_document); - bson_copy_to (_mongoc_read_concern_get_bson ((mongoc_read_concern_t *) rc), - &parts->read_concern_document); - - RETURN (true); -} - - -/* set writeConcern if allowed, otherwise ignore - unlike set_read_concern, it's - * the caller's responsibility to check if writeConcern is supported */ -bool -mongoc_cmd_parts_set_write_concern (mongoc_cmd_parts_t *parts, - const mongoc_write_concern_t *wc, - int max_wire_version, - bson_error_t *error) -{ - const char *command_name; - bool is_fam; - bool wc_allowed; - - ENTRY; - - if (!wc) { - RETURN (true); - } - - command_name = _mongoc_get_command_name (parts->body); - - if (!command_name) { - OPTS_ERR (COMMAND_INVALID_ARG, "Empty command document"); - } - - is_fam = !strcasecmp (command_name, "findandmodify"); - - wc_allowed = - parts->is_write_command || - (is_fam && max_wire_version >= WIRE_VERSION_FAM_WRITE_CONCERN) || - (!is_fam && max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN); - - if (wc_allowed) { - parts->assembled.is_acknowledged = - mongoc_write_concern_is_acknowledged (wc); - bson_destroy (&parts->write_concern_document); - bson_copy_to ( - _mongoc_write_concern_get_bson ((mongoc_write_concern_t *) wc), - &parts->write_concern_document); - } - - RETURN (true); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cmd_parts_append_read_write -- - * - * Append user-supplied options to @parts->command_extra, taking the - * selected server's max wire version into account. - * - * Return: - * True if the options were successfully applied. If any options are - * invalid, returns false and fills out @error. In that case @parts is - * invalid and must not be used. - * - * Side effects: - * May partly apply options before returning an error. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts, - mongoc_read_write_opts_t *rw_opts, - int max_wire_version, - bson_error_t *error) -{ - ENTRY; - - /* not yet assembled */ - BSON_ASSERT (!parts->assembled.command); - - if (!bson_empty (&rw_opts->collation)) { - if (max_wire_version < WIRE_VERSION_COLLATION) { - OPTS_ERR (PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } - - if (!bson_append_document ( - &parts->extra, "collation", 9, &rw_opts->collation)) { - OPTS_ERR (COMMAND_INVALID_ARG, "'opts' with 'collation' is too large"); - } - } - - if (!mongoc_cmd_parts_set_write_concern ( - parts, rw_opts->writeConcern, max_wire_version, error)) { - RETURN (false); - } - - /* process explicit read concern */ - if (!bson_empty (&rw_opts->readConcern)) { - if (max_wire_version < WIRE_VERSION_READ_CONCERN) { - OPTS_ERR (PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support readConcern"); - } - - /* save readConcern for later, once we know about causal consistency */ - bson_destroy (&parts->read_concern_document); - bson_copy_to (&rw_opts->readConcern, &parts->read_concern_document); - } - - if (rw_opts->client_session) { - BSON_ASSERT (!parts->assembled.session); - parts->assembled.session = rw_opts->client_session; - } - - if (!bson_concat (&parts->extra, &rw_opts->extra)) { - OPTS_ERR (COMMAND_INVALID_ARG, "'opts' with extra fields is too large"); - } - - RETURN (true); -} - -#undef OPTS_ERR - -static void -_mongoc_cmd_parts_ensure_copied (mongoc_cmd_parts_t *parts) -{ - if (parts->assembled.command == parts->body) { - bson_concat (&parts->assembled_body, parts->body); - bson_concat (&parts->assembled_body, &parts->extra); - parts->assembled.command = &parts->assembled_body; - } -} - - -static void -_mongoc_cmd_parts_add_write_concern (mongoc_cmd_parts_t *parts) -{ - if (!bson_empty (&parts->write_concern_document)) { - _mongoc_cmd_parts_ensure_copied (parts); - bson_append_document (&parts->assembled_body, - "writeConcern", - 12, - &parts->write_concern_document); - } -} - - -/* The server type must be mongos, or message must be OP_MSG. */ -static void -_mongoc_cmd_parts_add_read_prefs (bson_t *query, - const mongoc_read_prefs_t *prefs) -{ - bson_t child; - const char *mode_str; - const bson_t *tags; - int64_t stale; - - mode_str = _mongoc_read_mode_as_str (mongoc_read_prefs_get_mode (prefs)); - tags = mongoc_read_prefs_get_tags (prefs); - stale = mongoc_read_prefs_get_max_staleness_seconds (prefs); - - bson_append_document_begin (query, "$readPreference", 15, &child); - bson_append_utf8 (&child, "mode", 4, mode_str, -1); - if (!bson_empty0 (tags)) { - bson_append_array (&child, "tags", 4, tags); - } - - if (stale != MONGOC_NO_MAX_STALENESS) { - bson_append_int64 (&child, "maxStalenessSeconds", 19, stale); - } - - bson_append_document_end (query, &child); -} - - -static void -_iter_concat (bson_t *dst, bson_iter_t *iter) -{ - uint32_t len; - const uint8_t *data; - bson_t src; - - bson_iter_document (iter, &len, &data); - BSON_ASSERT (bson_init_static (&src, data, len)); - BSON_ASSERT (bson_concat (dst, &src)); -} - - -/* Update result with the read prefs. Server must be mongos. - */ -static void -_mongoc_cmd_parts_assemble_mongos (mongoc_cmd_parts_t *parts, - const mongoc_server_stream_t *server_stream) -{ - mongoc_read_mode_t mode; - const bson_t *tags = NULL; - bool add_read_prefs = false; - bson_t query; - bson_iter_t dollar_query; - bool has_dollar_query = false; - bool requires_read_concern; - bool requires_write_concern; - - ENTRY; - - mode = mongoc_read_prefs_get_mode (parts->read_prefs); - if (parts->read_prefs) { - tags = mongoc_read_prefs_get_tags (parts->read_prefs); - } - - /* Server Selection Spec says: - * - * For mode 'primary', drivers MUST NOT set the slaveOK wire protocol flag - * and MUST NOT use $readPreference - * - * For mode 'secondary', drivers MUST set the slaveOK wire protocol flag and - * MUST also use $readPreference - * - * For mode 'primaryPreferred', drivers MUST set the slaveOK wire protocol - * flag and MUST also use $readPreference - * - * For mode 'secondaryPreferred', drivers MUST set the slaveOK wire protocol - * flag. If the read preference contains a non-empty tag_sets parameter, - * drivers MUST use $readPreference; otherwise, drivers MUST NOT use - * $readPreference - * - * For mode 'nearest', drivers MUST set the slaveOK wire protocol flag and - * MUST also use $readPreference - */ - switch (mode) { - case MONGOC_READ_PRIMARY: - break; - case MONGOC_READ_SECONDARY_PREFERRED: - if (!bson_empty0 (tags)) { - add_read_prefs = true; - } - parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK; - break; - case MONGOC_READ_PRIMARY_PREFERRED: - case MONGOC_READ_SECONDARY: - case MONGOC_READ_NEAREST: - default: - parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK; - add_read_prefs = true; - } - - requires_read_concern = - !bson_empty (&parts->read_concern_document) && - strcmp (parts->assembled.command_name, "getMore") != 0; - - requires_write_concern = !bson_empty (&parts->write_concern_document); - - if (add_read_prefs) { - /* produce {$query: {user query, readConcern}, $readPreference: ... } */ - bson_append_document_begin (&parts->assembled_body, "$query", 6, &query); - - if (bson_iter_init_find (&dollar_query, parts->body, "$query")) { - /* user provided something like {$query: {key: "x"}} */ - has_dollar_query = true; - _iter_concat (&query, &dollar_query); - } else { - bson_concat (&query, parts->body); - } - - bson_concat (&query, &parts->extra); - if (requires_read_concern) { - bson_append_document ( - &query, "readConcern", 11, &parts->read_concern_document); - } - - if (requires_write_concern) { - bson_append_document ( - &query, "writeConcern", 12, &parts->write_concern_document); - } - - bson_append_document_end (&parts->assembled_body, &query); - _mongoc_cmd_parts_add_read_prefs (&parts->assembled_body, - parts->read_prefs); - - if (has_dollar_query) { - /* copy anything that isn't in user's $query */ - bson_copy_to_excluding_noinit ( - parts->body, &parts->assembled_body, "$query", NULL); - } - - parts->assembled.command = &parts->assembled_body; - } else if (bson_iter_init_find (&dollar_query, parts->body, "$query")) { - /* user provided $query, we have no read prefs */ - bson_append_document_begin (&parts->assembled_body, "$query", 6, &query); - _iter_concat (&query, &dollar_query); - bson_concat (&query, &parts->extra); - if (requires_read_concern) { - bson_append_document ( - &query, "readConcern", 11, &parts->read_concern_document); - } - - if (requires_write_concern) { - bson_append_document ( - &query, "writeConcern", 12, &parts->write_concern_document); - } - - bson_append_document_end (&parts->assembled_body, &query); - /* copy anything that isn't in user's $query */ - bson_copy_to_excluding_noinit ( - parts->body, &parts->assembled_body, "$query", NULL); - - parts->assembled.command = &parts->assembled_body; - } else { - if (requires_read_concern) { - _mongoc_cmd_parts_ensure_copied (parts); - bson_append_document (&parts->assembled_body, - "readConcern", - 11, - &parts->read_concern_document); - } - - _mongoc_cmd_parts_add_write_concern (parts); - } - - if (!bson_empty (&parts->extra)) { - /* if none of the above logic has merged "extra", do it now */ - _mongoc_cmd_parts_ensure_copied (parts); - } - - EXIT; -} - - -static void -_mongoc_cmd_parts_assemble_mongod (mongoc_cmd_parts_t *parts, - const mongoc_server_stream_t *server_stream) -{ - ENTRY; - - if (!parts->is_write_command) { - switch (server_stream->topology_type) { - case MONGOC_TOPOLOGY_SINGLE: - /* Server Selection Spec: for topology type single and server types - * besides mongos, "clients MUST always set the slaveOK wire - * protocol flag on reads to ensure that any server type can handle - * the request." - */ - parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK; - break; - - case MONGOC_TOPOLOGY_RS_NO_PRIMARY: - case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: - /* Server Selection Spec: for RS topology types, "For all read - * preferences modes except primary, clients MUST set the slaveOK wire - * protocol flag to ensure that any suitable server can handle the - * request. Clients MUST NOT set the slaveOK wire protocol flag if the - * read preference mode is primary. - */ - if (parts->read_prefs && - parts->read_prefs->mode != MONGOC_READ_PRIMARY) { - parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK; - } - - break; - case MONGOC_TOPOLOGY_SHARDED: - case MONGOC_TOPOLOGY_UNKNOWN: - case MONGOC_TOPOLOGY_DESCRIPTION_TYPES: - default: - /* must not call this function w/ sharded or unknown topology type */ - BSON_ASSERT (false); - } - } /* if (!parts->is_write_command) */ - - if (!bson_empty (&parts->extra)) { - _mongoc_cmd_parts_ensure_copied (parts); - } - - if (!bson_empty (&parts->read_concern_document) && - strcmp (parts->assembled.command_name, "getMore") != 0) { - _mongoc_cmd_parts_ensure_copied (parts); - bson_append_document (&parts->assembled_body, - "readConcern", - 11, - &parts->read_concern_document); - } - - _mongoc_cmd_parts_add_write_concern (parts); - - EXIT; -} - - -static const bson_t * -_largest_cluster_time (const bson_t *a, const bson_t *b) -{ - if (!a) { - return b; - } - - if (!b) { - return a; - } - - if (_mongoc_cluster_time_greater (a, b)) { - return a; - } - - return b; -} - - -/* Check if the command should allow a transaction number if that has not - * already been determined. - * - * This should only return true for write commands that are always retryable for - * the server stream's wire version. - * - * The basic write commands (i.e. insert, update, delete) are intentionally - * excluded here. While insert is always retryable, update and delete are only - * retryable if they include no multi-document writes. Since it would be costly - * to inspect the command document here, the bulk operation API explicitly sets - * allow_txn_number for us. This means that insert, update, and delete are not - * retryable if executed via mongoc_client_write_command_with_opts(); however, - * documentation already instructs users not to use that for basic writes. - */ -static bool -_allow_txn_number (const mongoc_cmd_parts_t *parts, - const mongoc_server_stream_t *server_stream) -{ - /* There is no reason to call this function if allow_txn_number is set */ - BSON_ASSERT (parts->allow_txn_number == - MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN); - - if (!parts->is_write_command) { - return false; - } - - if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_WRITES) { - return false; - } - - if (!parts->assembled.is_acknowledged) { - return false; - } - - if (!strcasecmp (parts->assembled.command_name, "findandmodify")) { - return true; - } - - return false; -} - - -/* Check if the write command should support retryable behavior. */ -static bool -_is_retryable_write (const mongoc_cmd_parts_t *parts, - const mongoc_server_stream_t *server_stream) -{ - if (!parts->assembled.session) { - return false; - } - - if (!parts->is_write_command) { - return false; - } - - if (parts->allow_txn_number != MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES) { - return false; - } - - if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_WRITES) { - return false; - } - - if (server_stream->sd->type == MONGOC_SERVER_STANDALONE) { - return false; - } - - if (_mongoc_client_session_in_txn (parts->assembled.session)) { - return false; - } - - if (!mongoc_uri_get_option_as_bool (parts->client->uri, - MONGOC_URI_RETRYWRITES, - MONGOC_DEFAULT_RETRYWRITES)) { - return false; - } - - return true; -} - - -/* Check if the read command should support retryable behavior. */ -bool -_is_retryable_read (const mongoc_cmd_parts_t *parts, - const mongoc_server_stream_t *server_stream) -{ - if (!parts->is_read_command) { - return false; - } - - /* Commands that go through read_write_command helpers are also write - * commands. Prohibit from read retry. */ - if (parts->is_write_command) { - return false; - } - - if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_READS) { - return false; - } - - if (_mongoc_client_session_in_txn (parts->assembled.session)) { - return false; - } - - if (!mongoc_uri_get_option_as_bool (parts->client->uri, - MONGOC_URI_RETRYREADS, - MONGOC_DEFAULT_RETRYREADS)) { - return false; - } - - return true; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cmd_parts_assemble -- - * - * Assemble the command body, options, and read preference into one - * command. - * - * Return: - * True if the options were successfully applied. If any options are - * invalid, returns false and fills out @error. In that case @parts is - * invalid and must not be used. - * - * Side effects: - * May partly assemble before returning an error. - * mongoc_cmd_parts_cleanup should be called in all cases. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cmd_parts_assemble (mongoc_cmd_parts_t *parts, - const mongoc_server_stream_t *server_stream, - bson_error_t *error) -{ - mongoc_server_description_type_t server_type; - mongoc_client_session_t *cs; - const bson_t *cluster_time = NULL; - mongoc_read_prefs_t *prefs = NULL; - const char *cmd_name; - bool is_get_more; - const mongoc_read_prefs_t *prefs_ptr; - bool ret = false; - - ENTRY; - - BSON_ASSERT (parts); - BSON_ASSERT (server_stream); - - server_type = server_stream->sd->type; - cs = parts->prohibit_lsid ? NULL : parts->assembled.session; - - /* must not be assembled already */ - BSON_ASSERT (!parts->assembled.command); - BSON_ASSERT (bson_empty (&parts->assembled_body)); - - /* begin with raw flags/cmd as assembled flags/cmd, might change below */ - parts->assembled.command = parts->body; - /* unused in OP_MSG: */ - parts->assembled.query_flags = parts->user_query_flags; - parts->assembled.server_stream = server_stream; - cmd_name = parts->assembled.command_name = - _mongoc_get_command_name (parts->assembled.command); - - if (!parts->assembled.command_name) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Empty command document"); - GOTO (done); - } - - TRACE ("Preparing '%s'", cmd_name); - - is_get_more = !strcmp (cmd_name, "getMore"); - parts->assembled.is_txn_finish = !strcmp (cmd_name, "commitTransaction") || - !strcmp (cmd_name, "abortTransaction"); - - if (!parts->is_write_command && IS_PREF_PRIMARY (parts->read_prefs) && - server_stream->topology_type == MONGOC_TOPOLOGY_SINGLE && - server_type != MONGOC_SERVER_MONGOS) { - prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED); - prefs_ptr = prefs; - } else { - prefs_ptr = parts->read_prefs; - } - - if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) { - if (!bson_has_field (parts->body, "$db")) { - BSON_APPEND_UTF8 (&parts->extra, "$db", parts->assembled.db_name); - } - - if (_mongoc_client_session_in_txn (cs)) { - if (!IS_PREF_PRIMARY (cs->txn.opts.read_prefs) && - !parts->is_write_command) { - bson_set_error (error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Read preference in a transaction must be primary"); - GOTO (done); - } - } else if (!IS_PREF_PRIMARY (prefs_ptr) && - server_type != MONGOC_SERVER_STANDALONE) { - /* "Type Standalone: clients MUST NOT send the read preference to the - * server" */ - _mongoc_cmd_parts_add_read_prefs (&parts->extra, prefs_ptr); - } - - if (!bson_empty (&parts->extra)) { - _mongoc_cmd_parts_ensure_copied (parts); - } - - /* If an explicit session was not provided and lsid is not prohibited, - * attempt to create an implicit session (ignoring any errors). */ - if (!cs && !parts->prohibit_lsid && parts->assembled.is_acknowledged) { - cs = mongoc_client_start_session (parts->client, NULL, NULL); - - if (cs) { - parts->assembled.session = cs; - parts->has_temp_session = true; - } - } - - /* Driver Sessions Spec: "For unacknowledged writes with an explicit - * session, drivers SHOULD raise an error.... Without an explicit - * session, drivers SHOULD NOT use an implicit session." We intentionally - * do not restrict this logic to parts->is_write_command, since - * mongoc_client_command_with_opts() does not identify as a write - * command but may still include a write concern. - */ - if (cs) { - if (!parts->assembled.is_acknowledged) { - bson_set_error ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot use client session with unacknowledged command"); - GOTO (done); - } - - _mongoc_cmd_parts_ensure_copied (parts); - bson_append_document (&parts->assembled_body, - "lsid", - 4, - mongoc_client_session_get_lsid (cs)); - - cs->server_session->last_used_usec = bson_get_monotonic_time (); - cluster_time = mongoc_client_session_get_cluster_time (cs); - } - - /* Ensure we know if the write command allows a transaction number */ - if (!_mongoc_client_session_txn_in_progress (cs) && - parts->is_write_command && - parts->allow_txn_number == - MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN) { - parts->allow_txn_number = _allow_txn_number (parts, server_stream) - ? MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES - : MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_NO; - } - - /* Determine if the command is retryable. If so, append txnNumber now - * for future use and mark the command as such. */ - if (_is_retryable_write (parts, server_stream)) { - _mongoc_cmd_parts_ensure_copied (parts); - bson_append_int64 (&parts->assembled_body, "txnNumber", 9, 0); - parts->is_retryable_write = true; - } - - /* Conversely, check if the command is retryable if it is a read. */ - if (_is_retryable_read (parts, server_stream) && !is_get_more) { - parts->is_retryable_read = true; - } - - if (!bson_empty (&server_stream->cluster_time)) { - cluster_time = - _largest_cluster_time (&server_stream->cluster_time, cluster_time); - } - - if (cluster_time && server_type != MONGOC_SERVER_STANDALONE) { - _mongoc_cmd_parts_ensure_copied (parts); - bson_append_document ( - &parts->assembled_body, "$clusterTime", 12, cluster_time); - } - - if (!is_get_more) { - if (cs) { - _mongoc_client_session_append_read_concern ( - cs, - &parts->read_concern_document, - parts->is_read_command, - &parts->assembled_body); - } else if (!bson_empty (&parts->read_concern_document)) { - bson_append_document (&parts->assembled_body, - "readConcern", - 11, - &parts->read_concern_document); - } - } - - if (parts->assembled.is_txn_finish || - !_mongoc_client_session_in_txn (cs)) { - _mongoc_cmd_parts_add_write_concern (parts); - } - - if (!_mongoc_client_session_append_txn ( - cs, &parts->assembled_body, error)) { - GOTO (done); - } - - ret = true; - } else if (server_type == MONGOC_SERVER_MONGOS) { - _mongoc_cmd_parts_assemble_mongos (parts, server_stream); - ret = true; - } else { - _mongoc_cmd_parts_assemble_mongod (parts, server_stream); - ret = true; - } - -done: - mongoc_read_prefs_destroy (prefs); - RETURN (ret); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cmd_parts_cleanup -- - * - * Free memory associated with a stack-allocated mongoc_cmd_parts_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_cmd_parts_cleanup (mongoc_cmd_parts_t *parts) -{ - bson_destroy (&parts->read_concern_document); - bson_destroy (&parts->write_concern_document); - bson_destroy (&parts->extra); - bson_destroy (&parts->assembled_body); - - if (parts->has_temp_session) { - /* client session returns its server session to server session pool */ - mongoc_client_session_destroy (parts->assembled.session); - } -} - -bool -mongoc_cmd_is_compressible (mongoc_cmd_t *cmd) -{ - BSON_ASSERT (cmd); - BSON_ASSERT (cmd->command_name); - - return !!strcasecmp (cmd->command_name, "ismaster") && - !!strcasecmp (cmd->command_name, "authenticate") && - !!strcasecmp (cmd->command_name, "getnonce") && - !!strcasecmp (cmd->command_name, "saslstart") && - !!strcasecmp (cmd->command_name, "saslcontinue") && - !!strcasecmp (cmd->command_name, "createuser") && - !!strcasecmp (cmd->command_name, "updateuser"); -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_cmd_append_payload_as_array -- - * Append a write command payload as an array in a BSON document. - * Used by APM and Client-Side Encryption - * - * Arguments: - * cmd The mongoc_cmd_t, which may contain a payload to be appended. - * out A bson_t, which will be appended to if @cmd->payload is set. - * - * Pre-conditions: - * - @out is initialized. - * - cmd has a payload (i.e. is a write command). - * - * Post-conditions: - * - If @cmd->payload is set, then @out is appended to with the payload - * field's name ("documents" if insert, "updates" if update, - * "deletes" if delete) an the payload as a BSON array. - * - *-------------------------------------------------------------------------- - */ -void -_mongoc_cmd_append_payload_as_array (const mongoc_cmd_t *cmd, bson_t *out) -{ - int32_t doc_len; - bson_t doc; - const uint8_t *pos; - const char *field_name; - bson_t bson; - char str[16]; - const char *key; - uint32_t i; - - BSON_ASSERT (cmd->payload && cmd->payload_size); - - /* make array from outgoing OP_MSG payload type 1 on an "insert", - * "update", or "delete" command. */ - field_name = _mongoc_get_documents_field_name (cmd->command_name); - BSON_ASSERT (field_name); - BSON_ASSERT (BSON_APPEND_ARRAY_BEGIN (out, field_name, &bson)); - - pos = cmd->payload; - i = 0; - while (pos < cmd->payload + cmd->payload_size) { - memcpy (&doc_len, pos, sizeof (doc_len)); - doc_len = BSON_UINT32_FROM_LE (doc_len); - BSON_ASSERT (bson_init_static (&doc, pos, (size_t) doc_len)); - bson_uint32_to_string (i, &key, str, sizeof (str)); - BSON_APPEND_DOCUMENT (&bson, key, &doc); - - pos += doc_len; - i++; - } - - bson_append_array_end (out, &bson); -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-collection-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-collection-private.h deleted file mode 100644 index 9a10a43c85d860560b4074873f0a1330473d28b1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-collection-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_COLLECTION_PRIVATE_H -#define MONGOC_COLLECTION_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-client.h" - -BSON_BEGIN_DECLS - - -struct _mongoc_collection_t { - mongoc_client_t *client; - char ns[128]; - uint32_t nslen; - char db[128]; - char collection[128]; - uint32_t collectionlen; - mongoc_read_prefs_t *read_prefs; - mongoc_read_concern_t *read_concern; - mongoc_write_concern_t *write_concern; - bson_t *gle; -}; - - -mongoc_collection_t * -_mongoc_collection_new (mongoc_client_t *client, - const char *db, - const char *collection, - const mongoc_read_prefs_t *read_prefs, - const mongoc_read_concern_t *read_concern, - const mongoc_write_concern_t *write_concern); - -BSON_END_DECLS - - -#endif /* MONGOC_COLLECTION_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-collection.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-collection.c deleted file mode 100644 index 4ed22f17b901cafe9557b281db3b385ad4557a50..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-collection.c +++ /dev/null @@ -1,3305 +0,0 @@ -/* - * Copyright 2013 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 <stdio.h> - -#include "mongoc/mongoc-aggregate-private.h" -#include "mongoc/mongoc-bulk-operation.h" -#include "mongoc/mongoc-bulk-operation-private.h" -#include "mongoc/mongoc-change-stream-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-find-and-modify-private.h" -#include "mongoc/mongoc-find-and-modify.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-index.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-command-private.h" -#include "mongoc/mongoc-opts-private.h" -#include "mongoc-write-command-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "collection" - -static void -_mongoc_collection_write_command_execute ( - mongoc_write_command_t *command, - const mongoc_collection_t *collection, - const mongoc_write_concern_t *write_concern, - mongoc_client_session_t *cs, - mongoc_write_result_t *result) -{ - mongoc_server_stream_t *server_stream; - - ENTRY; - - server_stream = mongoc_cluster_stream_for_writes ( - &collection->client->cluster, cs, NULL, &result->error); - - if (!server_stream) { - /* result->error has been filled out */ - EXIT; - } - - _mongoc_write_command_execute (command, - collection->client, - server_stream, - collection->db, - collection->collection, - write_concern, - 0 /* offset */, - cs, - result); - - mongoc_server_stream_cleanup (server_stream); - - EXIT; -} - - -static void -_mongoc_collection_write_command_execute_idl ( - mongoc_write_command_t *command, - const mongoc_collection_t *collection, - mongoc_crud_opts_t *crud, - mongoc_write_result_t *result) -{ - mongoc_server_stream_t *server_stream; - bson_t reply; - - ENTRY; - - server_stream = - mongoc_cluster_stream_for_writes (&collection->client->cluster, - crud->client_session, - &reply, - &result->error); - - if (!server_stream) { - /* result->error and reply have been filled out */ - _mongoc_bson_array_copy_labels_to (&reply, &result->errorLabels); - bson_destroy (&reply); - EXIT; - } - - if (_mongoc_client_session_in_txn (crud->client_session) && - crud->writeConcern) { - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set write concern after starting transaction"); - mongoc_server_stream_cleanup (server_stream); - EXIT; - } - - if (!crud->writeConcern && - !_mongoc_client_session_in_txn (crud->client_session)) { - crud->writeConcern = collection->write_concern; - crud->write_concern_owned = false; - } - - _mongoc_write_command_execute_idl (command, - collection->client, - server_stream, - collection->db, - collection->collection, - 0 /* offset */, - crud, - result); - - mongoc_server_stream_cleanup (server_stream); - - EXIT; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_collection_new -- - * - * INTERNAL API - * - * Create a new mongoc_collection_t structure for the given client. - * - * @client must remain valid during the lifetime of this structure. - * @db is the db name of the collection. - * @collection is the name of the collection. - * @read_prefs is the default read preferences to apply or NULL. - * @read_concern is the default read concern to apply or NULL. - * @write_concern is the default write concern to apply or NULL. - * - * Returns: - * A newly allocated mongoc_collection_t that should be freed with - * mongoc_collection_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_collection_t * -_mongoc_collection_new (mongoc_client_t *client, - const char *db, - const char *collection, - const mongoc_read_prefs_t *read_prefs, - const mongoc_read_concern_t *read_concern, - const mongoc_write_concern_t *write_concern) -{ - mongoc_collection_t *col; - - ENTRY; - - BSON_ASSERT (client); - BSON_ASSERT (db); - BSON_ASSERT (collection); - - col = (mongoc_collection_t *) bson_malloc0 (sizeof *col); - col->client = client; - col->write_concern = write_concern - ? mongoc_write_concern_copy (write_concern) - : mongoc_write_concern_new (); - col->read_concern = read_concern ? mongoc_read_concern_copy (read_concern) - : mongoc_read_concern_new (); - col->read_prefs = read_prefs ? mongoc_read_prefs_copy (read_prefs) - : mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - bson_snprintf (col->ns, sizeof col->ns, "%s.%s", db, collection); - bson_snprintf (col->db, sizeof col->db, "%s", db); - bson_snprintf (col->collection, sizeof col->collection, "%s", collection); - - col->collectionlen = (uint32_t) strlen (col->collection); - col->nslen = (uint32_t) strlen (col->ns); - - col->gle = NULL; - - RETURN (col); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_destroy -- - * - * Release resources associated with @collection and frees the - * structure. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_collection_destroy (mongoc_collection_t *collection) /* IN */ -{ - ENTRY; - - if (!collection) { - EXIT; - } - - bson_clear (&collection->gle); - - if (collection->read_prefs) { - mongoc_read_prefs_destroy (collection->read_prefs); - collection->read_prefs = NULL; - } - - if (collection->read_concern) { - mongoc_read_concern_destroy (collection->read_concern); - collection->read_concern = NULL; - } - - if (collection->write_concern) { - mongoc_write_concern_destroy (collection->write_concern); - collection->write_concern = NULL; - } - - bson_free (collection); - - EXIT; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_copy -- - * - * Returns a copy of @collection that needs to be freed by calling - * mongoc_collection_destroy. - * - * Returns: - * A copy of this collection. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_collection_t * -mongoc_collection_copy (mongoc_collection_t *collection) /* IN */ -{ - ENTRY; - - BSON_ASSERT (collection); - - RETURN (_mongoc_collection_new (collection->client, - collection->db, - collection->collection, - collection->read_prefs, - collection->read_concern, - collection->write_concern)); -} - - -mongoc_cursor_t * -mongoc_collection_aggregate (mongoc_collection_t *collection, /* IN */ - mongoc_query_flags_t flags, /* IN */ - const bson_t *pipeline, /* IN */ - const bson_t *opts, /* IN */ - const mongoc_read_prefs_t *read_prefs) /* IN */ -{ - return _mongoc_aggregate (collection->client, - collection->ns, - flags, - pipeline, - opts, - read_prefs, - collection->read_prefs, - collection->read_concern, - collection->write_concern); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_find -- - * - * DEPRECATED: use mongoc_collection_find_with_opts. - * - * Performs a query against the configured MongoDB server. If @read_prefs - * is provided, it will be used to locate a MongoDB node in the cluster - * to deliver the query to. - * - * @flags may be bitwise-or'd flags or MONGOC_QUERY_NONE. - * - * @skip may contain the number of documents to skip before returning the - * matching document. - * - * @limit may contain the maximum number of documents that may be - * returned. - * - * This function will always return a cursor, with the exception of - * invalid API use. - * - * Parameters: - * @collection: A mongoc_collection_t. - * @flags: A bitwise or of mongoc_query_flags_t. - * @skip: The number of documents to skip. - * @limit: The maximum number of items. - * @batch_size: The batch size - * @query: The query to locate matching documents. - * @fields: The fields to return, or NULL for all fields. - * @read_prefs: Read preferences to choose cluster node. - * - * Returns: - * A newly allocated mongoc_cursor_t that should be freed with - * mongoc_cursor_destroy(). - * - * The client used by mongoc_collection_t must be valid for the - * lifetime of the resulting mongoc_cursor_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_cursor_t * -mongoc_collection_find (mongoc_collection_t *collection, /* IN */ - mongoc_query_flags_t flags, /* IN */ - uint32_t skip, /* IN */ - uint32_t limit, /* IN */ - uint32_t batch_size, /* IN */ - const bson_t *query, /* IN */ - const bson_t *fields, /* IN */ - const mongoc_read_prefs_t *read_prefs) /* IN */ -{ - bool has_unwrapped; - bson_t unwrapped; - bson_error_t error = {0}; - bson_t opts; - bool slave_ok; - mongoc_cursor_t *cursor; - BSON_ASSERT (collection); - BSON_ASSERT (query); - - bson_clear (&collection->gle); - - bson_init (&opts); - _mongoc_cursor_flags_to_opts (flags, &opts, &slave_ok); - /* check if the query is wrapped in $query */ - has_unwrapped = _mongoc_cursor_translate_dollar_query_opts ( - query, &opts, &unwrapped, &error); - if (!bson_empty0 (fields)) { - bson_append_document ( - &opts, MONGOC_CURSOR_PROJECTION, MONGOC_CURSOR_PROJECTION_LEN, fields); - } - cursor = _mongoc_cursor_find_new (collection->client, - collection->ns, - has_unwrapped ? &unwrapped : query, - &opts, - read_prefs, - collection->read_prefs, - collection->read_concern); - if (skip) { - _mongoc_cursor_set_opt_int64 (cursor, MONGOC_CURSOR_SKIP, skip); - } - if (limit) { - /* limit must be cast to int32_t. Although the argument is a uint32_t, - * callers can specify a negative limit by casting to a signed int32_t - * value to uint32_t. E.g. to set a limit of -4, the caller passes - * UINT32_MAX - 3 */ - (void) mongoc_cursor_set_limit (cursor, (int32_t) limit); - } - if (batch_size) { - mongoc_cursor_set_batch_size (cursor, batch_size); - } - bson_destroy (&unwrapped); - bson_destroy (&opts); - - if (error.domain) { - memcpy (&cursor->error, &error, sizeof (error)); - } - - return cursor; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_find_with_opts -- - * - * Create a cursor with a query filter. All other options are - * specified in a free-form BSON document. - * - * Parameters: - * @collection: A mongoc_collection_t. - * @filter: The query to locate matching documents. - * @opts: Other options. - * @read_prefs: Optional read preferences to choose cluster node. - * - * Returns: - * A newly allocated mongoc_cursor_t that should be freed with - * mongoc_cursor_destroy(). - * - * The client used by mongoc_collection_t must be valid for the - * lifetime of the resulting mongoc_cursor_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_cursor_t * -mongoc_collection_find_with_opts (mongoc_collection_t *collection, - const bson_t *filter, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs) -{ - BSON_ASSERT (collection); - BSON_ASSERT (filter); - - bson_clear (&collection->gle); - - return _mongoc_cursor_find_new (collection->client, - collection->ns, - filter, - opts, - read_prefs, - collection->read_prefs, - collection->read_concern); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_command -- - * - * Executes a command on a cluster node matching @read_prefs. If - * @read_prefs is not provided, it will be run on the primary node. - * - * This function will always return a mongoc_cursor_t. - * - * Parameters: - * @collection: A mongoc_collection_t. - * @flags: Bitwise-or'd flags for command. - * @skip: Number of documents to skip, typically 0. - * @limit : Number of documents to return - * @batch_size : Batch size - * @query: The command to execute. - * @fields: The fields to return, or NULL. - * @read_prefs: Command read preferences or NULL. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_cursor_t * -mongoc_collection_command (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *query, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs) -{ - char ns[MONGOC_NAMESPACE_MAX]; - mongoc_cursor_t *cursor; - - BSON_ASSERT (collection); - BSON_ASSERT (query); - - if (!read_prefs) { - read_prefs = collection->read_prefs; - } - - bson_clear (&collection->gle); - - if (NULL == strstr (collection->collection, "$cmd")) { - bson_snprintf (ns, sizeof ns, "%s.$cmd", collection->db); - } else { - bson_snprintf (ns, sizeof ns, "%s", collection->db); - } - - /* Server Selection Spec: "The generic command method has a default read - * preference of mode 'primary'. The generic command method MUST ignore any - * default read preference from client, database or collection - * configuration. The generic command method SHOULD allow an optional read - * preference argument." - */ - - /* flags, skip, limit, batch_size, fields are unused */ - cursor = _mongoc_cursor_cmd_deprecated_new ( - collection->client, ns, query, read_prefs); - return cursor; -} - - -bool -mongoc_collection_read_command_with_opts (mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - BSON_ASSERT (collection); - - return _mongoc_client_command_with_opts (collection->client, - collection->db, - command, - MONGOC_CMD_READ, - opts, - MONGOC_QUERY_NONE, - read_prefs, - collection->read_prefs, - collection->read_concern, - collection->write_concern, - reply, - error); -} - - -bool -mongoc_collection_write_command_with_opts (mongoc_collection_t *collection, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - BSON_ASSERT (collection); - - return _mongoc_client_command_with_opts (collection->client, - collection->db, - command, - MONGOC_CMD_WRITE, - opts, - MONGOC_QUERY_NONE, - NULL, - collection->read_prefs, - collection->read_concern, - collection->write_concern, - reply, - error); -} - - -bool -mongoc_collection_read_write_command_with_opts ( - mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* IGNORED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - BSON_ASSERT (collection); - - return _mongoc_client_command_with_opts (collection->client, - collection->db, - command, - MONGOC_CMD_RW, - opts, - MONGOC_QUERY_NONE, - read_prefs, - collection->read_prefs, - collection->read_concern, - collection->write_concern, - reply, - error); -} - - -bool -mongoc_collection_command_with_opts (mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - BSON_ASSERT (collection); - - /* Server Selection Spec: "The generic command method has a default read - * preference of mode 'primary'. The generic command method MUST ignore any - * default read preference from client, database or collection - * configuration. The generic command method SHOULD allow an optional read - * preference argument." */ - - return _mongoc_client_command_with_opts (collection->client, - collection->db, - command, - MONGOC_CMD_RAW, - opts, - MONGOC_QUERY_NONE, - read_prefs, - NULL /* default prefs */, - collection->read_concern, - collection->write_concern, - reply, - error); -} - - -bool -mongoc_collection_command_simple (mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error) -{ - BSON_ASSERT (collection); - BSON_ASSERT (command); - - bson_clear (&collection->gle); - - /* Server Selection Spec: "The generic command method has a default read - * preference of mode 'primary'. The generic command method MUST ignore any - * default read preference from client, database or collection - * configuration. The generic command method SHOULD allow an optional read - * preference argument." - */ - - return _mongoc_client_command_with_opts (collection->client, - collection->db, - command, - MONGOC_CMD_RAW, - NULL /* opts */, - MONGOC_QUERY_NONE, - read_prefs, - NULL /* default prefs */, - NULL /* read concern */, - NULL /* write concern */, - reply, - error); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_count -- - * - * Count the number of documents matching @query. - * - * Parameters: - * @flags: A mongoc_query_flags_t describing the query flags or 0. - * @query: The query to perform or NULL for {}. - * @skip: The $skip to perform within the query or 0. - * @limit: The $limit to perform within the query or 0. - * @read_prefs: desired read preferences or NULL. - * @error: A location for an error or NULL. - * - * Returns: - * -1 on failure; otherwise the number of matching documents. - * - * Side effects: - * @error is set upon failure if non-NULL. - * - *-------------------------------------------------------------------------- - */ - -int64_t -mongoc_collection_count (mongoc_collection_t *collection, /* IN */ - mongoc_query_flags_t flags, /* IN */ - const bson_t *query, /* IN */ - int64_t skip, /* IN */ - int64_t limit, /* IN */ - const mongoc_read_prefs_t *read_prefs, /* IN */ - bson_error_t *error) /* OUT */ -{ - int64_t ret; - bson_t opts = BSON_INITIALIZER; - - /* Complex types must be parts of `opts`, otherwise we can't - * follow various specs that require validation etc */ - if (collection->read_concern->level != NULL) { - const bson_t *read_concern_bson; - - read_concern_bson = - _mongoc_read_concern_get_bson (collection->read_concern); - BSON_APPEND_DOCUMENT (&opts, "readConcern", read_concern_bson); - } - - /* Server Selection Spec: "may-use-secondary" commands SHOULD take a read - * preference argument and otherwise MUST use the default read preference - * from client, database or collection configuration. */ - BEGIN_IGNORE_DEPRECATIONS - ret = mongoc_collection_count_with_opts ( - collection, flags, query, skip, limit, &opts, read_prefs, error); - END_IGNORE_DEPRECATIONS - - bson_destroy (&opts); - return ret; -} - - -int64_t -mongoc_collection_count_with_opts ( - mongoc_collection_t *collection, /* IN */ - mongoc_query_flags_t flags, /* IN */ - const bson_t *query, /* IN */ - int64_t skip, /* IN */ - int64_t limit, /* IN */ - const bson_t *opts, /* IN */ - const mongoc_read_prefs_t *read_prefs, /* IN */ - bson_error_t *error) /* OUT */ -{ - bson_iter_t iter; - int64_t ret = -1; - bool success; - bson_t reply; - bson_t cmd = BSON_INITIALIZER; - bson_t q; - - ENTRY; - - BSON_ASSERT (collection); - - bson_append_utf8 ( - &cmd, "count", 5, collection->collection, collection->collectionlen); - if (query) { - bson_append_document (&cmd, "query", 5, query); - } else { - bson_init (&q); - bson_append_document (&cmd, "query", 5, &q); - bson_destroy (&q); - } - if (limit) { - bson_append_int64 (&cmd, "limit", 5, limit); - } - if (skip) { - bson_append_int64 (&cmd, "skip", 4, skip); - } - - success = _mongoc_client_command_with_opts (collection->client, - collection->db, - &cmd, - MONGOC_CMD_READ, - opts, - flags, - read_prefs, - collection->read_prefs, - collection->read_concern, - collection->write_concern, - &reply, - error); - - if (success) { - if (bson_iter_init_find (&iter, &reply, "n")) { - ret = bson_iter_as_int64 (&iter); - } - } - - bson_destroy (&reply); - bson_destroy (&cmd); - - RETURN (ret); -} - - -int64_t -mongoc_collection_estimated_document_count ( - mongoc_collection_t *coll, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error) -{ - bson_iter_t iter; - int64_t count = -1; - bool ret; - bson_t reply_local; - bson_t *reply_ptr; - bson_t cmd = BSON_INITIALIZER; - - ENTRY; - - BSON_ASSERT (coll); - - reply_ptr = reply ? reply : &reply_local; - bson_append_utf8 (&cmd, "count", 5, coll->collection, coll->collectionlen); - - ret = _mongoc_client_command_with_opts (coll->client, - coll->db, - &cmd, - MONGOC_CMD_READ, - opts, - MONGOC_QUERY_NONE, - read_prefs, - coll->read_prefs, - coll->read_concern, - coll->write_concern, - reply_ptr, - error); - - if (ret) { - if (bson_iter_init_find (&iter, reply_ptr, "n")) { - count = bson_iter_as_int64 (&iter); - } - } - - if (!reply) { - bson_destroy (&reply_local); - } - bson_destroy (&cmd); - - RETURN (count); -} - - -/* -------------------------------------------------------------------------- - * - * _make_aggregate_for_count -- - * - * Construct an aggregate pipeline with the following form: - * { pipeline: [ - * { $match: {...} }, - * { $group: { _id: 1, n: { sum: 1 } } }, - * { $skip: ... }, - * { $limit: ... } - * ] - * } - * - *-------------------------------------------------------------------------- - */ -static void -_make_aggregate_for_count (const mongoc_collection_t *coll, - const bson_t *filter, - const bson_t *opts, - bson_t *out) -{ - bson_iter_t iter; - bson_t pipeline; - bson_t match_stage; - bson_t group_stage; - bson_t group_stage_doc; - bson_t sum; - bson_t empty; - const char *keys[] = {"0", "1", "2", "3"}; - int key = 0; - - bson_init (out); - bson_append_utf8 ( - out, "aggregate", 9, coll->collection, coll->collectionlen); - bson_append_document_begin (out, "cursor", 6, &empty); - bson_append_document_end (out, &empty); - bson_append_array_begin (out, "pipeline", 8, &pipeline); - - bson_append_document_begin (&pipeline, keys[key++], 1, &match_stage); - bson_append_document (&match_stage, "$match", 6, filter); - bson_append_document_end (&pipeline, &match_stage); - /* if @opts includes "skip", or "count", append $skip and $count stages to - * the aggregate pipeline. */ - if (opts && bson_iter_init_find (&iter, opts, "skip")) { - bson_t skip_stage; - bson_append_document_begin (&pipeline, keys[key++], 1, &skip_stage); - bson_append_value (&skip_stage, "$skip", 5, bson_iter_value (&iter)); - bson_append_document_end (&pipeline, &skip_stage); - } - if (opts && bson_iter_init_find (&iter, opts, "limit")) { - bson_t limit_stage; - bson_append_document_begin (&pipeline, keys[key++], 1, &limit_stage); - bson_append_value (&limit_stage, "$limit", 6, bson_iter_value (&iter)); - bson_append_document_end (&pipeline, &limit_stage); - } - bson_append_document_begin (&pipeline, keys[key], 1, &group_stage); - bson_append_document_begin (&group_stage, "$group", 6, &group_stage_doc); - bson_append_int32 (&group_stage_doc, "_id", 3, 1); - bson_append_document_begin (&group_stage_doc, "n", 1, &sum); - bson_append_int32 (&sum, "$sum", 4, 1); - bson_append_document_end (&group_stage_doc, &sum); - bson_append_document_end (&group_stage, &group_stage_doc); - bson_append_document_end (&pipeline, &group_stage); - bson_append_array_end (out, &pipeline); -} - - -int64_t -mongoc_collection_count_documents (mongoc_collection_t *coll, - const bson_t *filter, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error) -{ - bson_t aggregate_cmd; - bson_t aggregate_opts; - bool ret; - const bson_t *result; - mongoc_cursor_t *cursor = NULL; - int64_t count = -1; - bson_t cmd_reply; - bson_iter_t iter; - - ENTRY; - - BSON_ASSERT (coll); - BSON_ASSERT (filter); - - _make_aggregate_for_count (coll, filter, opts, &aggregate_cmd); - bson_init (&aggregate_opts); - if (opts) { - bson_copy_to_excluding_noinit ( - opts, &aggregate_opts, "skip", "limit", NULL); - } - - ret = mongoc_collection_read_command_with_opts ( - coll, &aggregate_cmd, read_prefs, &aggregate_opts, &cmd_reply, error); - bson_destroy (&aggregate_cmd); - bson_destroy (&aggregate_opts); - if (reply) { - bson_copy_to (&cmd_reply, reply); - } - - if (!ret) { - bson_destroy (&cmd_reply); - GOTO (done); - } - - /* steals reply */ - cursor = mongoc_cursor_new_from_command_reply_with_opts ( - coll->client, &cmd_reply, NULL); - BSON_ASSERT (mongoc_cursor_get_id (cursor) == 0); - ret = mongoc_cursor_next (cursor, &result); - if (!ret) { - if (mongoc_cursor_error (cursor, error)) { - GOTO (done); - } else { - count = 0; - GOTO (done); - } - } - - if (bson_iter_init_find (&iter, result, "n") && - BSON_ITER_HOLDS_INT (&iter)) { - count = bson_iter_as_int64 (&iter); - } - -done: - if (cursor) { - mongoc_cursor_destroy (cursor); - } - RETURN (count); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_drop -- - * - * Request the MongoDB server drop the collection. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @error is set upon failure. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_drop (mongoc_collection_t *collection, /* IN */ - bson_error_t *error) /* OUT */ -{ - return mongoc_collection_drop_with_opts (collection, NULL, error); -} - - -bool -mongoc_collection_drop_with_opts (mongoc_collection_t *collection, - const bson_t *opts, - bson_error_t *error) -{ - bool ret; - bson_t cmd; - - BSON_ASSERT (collection); - - bson_init (&cmd); - bson_append_utf8 ( - &cmd, "drop", 4, collection->collection, collection->collectionlen); - - ret = _mongoc_client_command_with_opts (collection->client, - collection->db, - &cmd, - MONGOC_CMD_WRITE, - opts, - MONGOC_QUERY_NONE, - NULL, /* user prefs */ - collection->read_prefs, - collection->read_concern, - collection->write_concern, - NULL, /* reply */ - error); - bson_destroy (&cmd); - - return ret; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_drop_index -- - * - * Request the MongoDB server drop the named index. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @error is setup upon failure if non-NULL. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_drop_index (mongoc_collection_t *collection, /* IN */ - const char *index_name, /* IN */ - bson_error_t *error) /* OUT */ -{ - return mongoc_collection_drop_index_with_opts ( - collection, index_name, NULL, error); -} - - -bool -mongoc_collection_drop_index_with_opts (mongoc_collection_t *collection, - const char *index_name, - const bson_t *opts, - bson_error_t *error) -{ - bool ret; - bson_t cmd; - - BSON_ASSERT (collection); - BSON_ASSERT (index_name); - - bson_init (&cmd); - bson_append_utf8 (&cmd, - "dropIndexes", - -1, - collection->collection, - collection->collectionlen); - bson_append_utf8 (&cmd, "index", -1, index_name, -1); - - ret = _mongoc_client_command_with_opts (collection->client, - collection->db, - &cmd, - MONGOC_CMD_WRITE, - opts, - MONGOC_QUERY_NONE, - NULL, /* user prefs */ - collection->read_prefs, - collection->read_concern, - collection->write_concern, - NULL, /* reply */ - error); - bson_destroy (&cmd); - - return ret; -} - - -char * -mongoc_collection_keys_to_index_string (const bson_t *keys) -{ - bson_string_t *s; - bson_iter_t iter; - bson_type_t type; - int i = 0; - - BSON_ASSERT (keys); - - if (!bson_iter_init (&iter, keys)) { - return NULL; - } - - s = bson_string_new (NULL); - - while (bson_iter_next (&iter)) { - /* Index type can be specified as a string ("2d") or as an integer - * representing direction */ - type = bson_iter_type (&iter); - if (type == BSON_TYPE_UTF8) { - bson_string_append_printf (s, - (i++ ? "_%s_%s" : "%s_%s"), - bson_iter_key (&iter), - bson_iter_utf8 (&iter, NULL)); - } else if (type == BSON_TYPE_INT32) { - bson_string_append_printf (s, - (i++ ? "_%s_%d" : "%s_%d"), - bson_iter_key (&iter), - bson_iter_int32 (&iter)); - } else if (type == BSON_TYPE_INT64) { - bson_string_append_printf (s, - (i++ ? "_%s_%" PRId64 : "%s_%" PRId64), - bson_iter_key (&iter), - bson_iter_int64 (&iter)); - } else { - bson_string_free (s, true); - return NULL; - } - } - return bson_string_free (s, false); -} - - -bool -mongoc_collection_create_index (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *opt, - bson_error_t *error) -{ - bson_t reply; - bool ret; - - BEGIN_IGNORE_DEPRECATIONS - - ret = mongoc_collection_create_index_with_opts ( - collection, keys, opt, NULL, &reply, error); - - END_IGNORE_DEPRECATIONS - - bson_destroy (&reply); - return ret; -} - -bool -mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *opt, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_create_index_opts_t parsed; - mongoc_cmd_parts_t parts; - const mongoc_index_opt_t *def_opt; - const mongoc_index_opt_geo_t *def_geo; - const char *name; - bson_t cmd = BSON_INITIALIZER; - bson_t ar; - bson_t doc; - bson_t storage_doc; - bson_t wt_doc; - const mongoc_index_opt_geo_t *geo_opt; - const mongoc_index_opt_storage_t *storage_opt; - const mongoc_index_opt_wt_t *wt_opt; - char *alloc_name = NULL; - bool ret = false; - bool reply_initialized = false; - bool has_collation = false; - mongoc_server_stream_t *server_stream = NULL; - mongoc_cluster_t *cluster; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (keys); - - def_opt = mongoc_index_opt_get_default (); - opt = opt ? opt : def_opt; - - mongoc_cmd_parts_init ( - &parts, collection->client, collection->db, MONGOC_QUERY_NONE, &cmd); - parts.is_write_command = true; - - if (!_mongoc_create_index_opts_parse ( - collection->client, opts, &parsed, error)) { - GOTO (done); - } - - if (!parsed.writeConcern) { - parsed.writeConcern = collection->write_concern; - parsed.write_concern_owned = false; - } - - /* - * Generate the key name if it was not provided. - */ - name = (opt->name != def_opt->name) ? opt->name : NULL; - if (!name) { - alloc_name = mongoc_collection_keys_to_index_string (keys); - if (alloc_name) { - name = alloc_name; - } else { - bson_set_error ( - error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Cannot generate index name from invalid `keys` argument"); - GOTO (done); - } - } - - /* - * Build our createIndexes command to send to the server. - */ - BSON_ASSERT ( - BSON_APPEND_UTF8 (&cmd, "createIndexes", collection->collection)); - bson_append_array_begin (&cmd, "indexes", 7, &ar); - bson_append_document_begin (&ar, "0", 1, &doc); - BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "key", keys)); - BSON_ASSERT (BSON_APPEND_UTF8 (&doc, "name", name)); - if (opt->background) { - BSON_ASSERT (BSON_APPEND_BOOL (&doc, "background", true)); - } - if (opt->unique) { - BSON_ASSERT (BSON_APPEND_BOOL (&doc, "unique", true)); - } - if (opt->drop_dups) { - BSON_ASSERT (BSON_APPEND_BOOL (&doc, "dropDups", true)); - } - if (opt->sparse) { - BSON_ASSERT (BSON_APPEND_BOOL (&doc, "sparse", true)); - } - if (opt->expire_after_seconds != def_opt->expire_after_seconds) { - BSON_ASSERT (BSON_APPEND_INT32 ( - &doc, "expireAfterSeconds", opt->expire_after_seconds)); - } - if (opt->v != def_opt->v) { - BSON_ASSERT (BSON_APPEND_INT32 (&doc, "v", opt->v)); - } - if (opt->weights && (opt->weights != def_opt->weights)) { - BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "weights", opt->weights)); - } - if (opt->default_language != def_opt->default_language) { - BSON_ASSERT ( - BSON_APPEND_UTF8 (&doc, "default_language", opt->default_language)); - } - if (opt->language_override != def_opt->language_override) { - BSON_ASSERT ( - BSON_APPEND_UTF8 (&doc, "language_override", opt->language_override)); - } - if (opt->partial_filter_expression) { - BSON_ASSERT (BSON_APPEND_DOCUMENT ( - &doc, "partialFilterExpression", opt->partial_filter_expression)); - } - if (opt->collation) { - BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "collation", opt->collation)); - has_collation = true; - } - if (opt->geo_options) { - geo_opt = opt->geo_options; - def_geo = mongoc_index_opt_geo_get_default (); - if (geo_opt->twod_sphere_version != def_geo->twod_sphere_version) { - BSON_ASSERT (BSON_APPEND_INT32 ( - &doc, "2dsphereIndexVersion", geo_opt->twod_sphere_version)); - } - if (geo_opt->twod_bits_precision != def_geo->twod_bits_precision) { - BSON_ASSERT ( - BSON_APPEND_INT32 (&doc, "bits", geo_opt->twod_bits_precision)); - } - if (geo_opt->twod_location_min != def_geo->twod_location_min) { - BSON_ASSERT ( - BSON_APPEND_DOUBLE (&doc, "min", geo_opt->twod_location_min)); - } - if (geo_opt->twod_location_max != def_geo->twod_location_max) { - BSON_ASSERT ( - BSON_APPEND_DOUBLE (&doc, "max", geo_opt->twod_location_max)); - } - if (geo_opt->haystack_bucket_size != def_geo->haystack_bucket_size) { - BSON_ASSERT (BSON_APPEND_DOUBLE ( - &doc, "bucketSize", geo_opt->haystack_bucket_size)); - } - } - - if (opt->storage_options) { - storage_opt = opt->storage_options; - switch (storage_opt->type) { - case MONGOC_INDEX_STORAGE_OPT_WIREDTIGER: - wt_opt = (mongoc_index_opt_wt_t *) storage_opt; - BSON_APPEND_DOCUMENT_BEGIN (&doc, "storageEngine", &storage_doc); - BSON_APPEND_DOCUMENT_BEGIN (&storage_doc, "wiredTiger", &wt_doc); - BSON_ASSERT ( - BSON_APPEND_UTF8 (&wt_doc, "configString", wt_opt->config_str)); - bson_append_document_end (&storage_doc, &wt_doc); - bson_append_document_end (&doc, &storage_doc); - break; - default: - break; - } - } - - bson_append_document_end (&ar, &doc); - bson_append_array_end (&cmd, &ar); - - server_stream = mongoc_cluster_stream_for_writes ( - &collection->client->cluster, parsed.client_session, reply, error); - - if (!server_stream) { - reply_initialized = true; - GOTO (done); - } - - if (!mongoc_cmd_parts_set_write_concern (&parts, - parsed.writeConcern, - server_stream->sd->max_wire_version, - error)) { - GOTO (done); - } - - if (has_collation && - server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - GOTO (done); - } - - parts.assembled.session = parsed.client_session; - if (!bson_concat (&parts.extra, &parsed.extra)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "'opts' is too large"); - GOTO (done); - } - - cluster = &collection->client->cluster; - if (mongoc_cmd_parts_assemble (&parts, server_stream, error)) { - ret = mongoc_cluster_run_command_monitored ( - cluster, &parts.assembled, reply, error); - } else { - _mongoc_bson_init_if_set (reply); - } - - reply_initialized = true; - - if (ret) { - if (reply) { - ret = !_mongoc_parse_wc_err (reply, error); - } - } - -done: - bson_destroy (&cmd); - bson_free (alloc_name); - _mongoc_create_index_opts_cleanup (&parsed); - mongoc_server_stream_cleanup (server_stream); - mongoc_cmd_parts_cleanup (&parts); - if (!reply_initialized && reply) { - bson_init (reply); - } - - RETURN (ret); -} - - -bool -mongoc_collection_ensure_index (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *opt, - bson_error_t *error) -{ - BEGIN_IGNORE_DEPRECATIONS - return mongoc_collection_create_index (collection, keys, opt, error); - END_IGNORE_DEPRECATIONS -} - - -mongoc_cursor_t * -mongoc_collection_find_indexes (mongoc_collection_t *collection, - bson_error_t *error) -{ - mongoc_cursor_t *cursor; - - cursor = mongoc_collection_find_indexes_with_opts (collection, NULL); - - (void) mongoc_cursor_error (cursor, error); - - return cursor; -} - - -mongoc_cursor_t * -mongoc_collection_find_indexes_with_opts (mongoc_collection_t *collection, - const bson_t *opts) -{ - mongoc_cursor_t *cursor; - bson_t cmd = BSON_INITIALIZER; - bson_t child; - bson_error_t error; - - BSON_ASSERT (collection); - - bson_append_utf8 (&cmd, - "listIndexes", - -1, - collection->collection, - collection->collectionlen); - - BSON_APPEND_DOCUMENT_BEGIN (&cmd, "cursor", &child); - bson_append_document_end (&cmd, &child); - - /* No read preference. Index Enumeration Spec: "run listIndexes on the - * primary node in replicaSet mode". */ - cursor = _mongoc_cursor_cmd_new ( - collection->client, collection->ns, &cmd, opts, NULL, NULL, NULL); - - if (!mongoc_cursor_error (cursor, &error)) { - _mongoc_cursor_prime (cursor); - } - - if (mongoc_cursor_error (cursor, &error) && - error.code == MONGOC_ERROR_COLLECTION_DOES_NOT_EXIST) { - /* collection does not exist. from spec: return no documents but no err: - * https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst#enumeration-getting-index-information - */ - _mongoc_cursor_set_empty (cursor); - } - - bson_destroy (&cmd); - - return cursor; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_insert_bulk -- - * - * Bulk insert documents into a MongoDB collection. - * - * Parameters: - * @collection: A mongoc_collection_t. - * @flags: flags for the insert or 0. - * @documents: The documents to insert. - * @n_documents: The number of documents to insert. - * @write_concern: A write concern or NULL. - * @error: a location for an error or NULL. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * If the write concern does not dictate checking the result of the - * insert, then true may be returned even though the document was - * not actually inserted on the MongoDB server or cluster. - * - * Side effects: - * @collection->gle is setup, depending on write_concern->w value. - * @error may be set upon failure if non-NULL. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_insert_bulk (mongoc_collection_t *collection, - mongoc_insert_flags_t flags, - const bson_t **documents, - uint32_t n_documents, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) -{ - mongoc_write_command_t command; - mongoc_write_result_t result; - mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; - uint32_t i; - bool ret; - - BSON_ASSERT (collection); - BSON_ASSERT (documents); - - if (!write_concern) { - write_concern = collection->write_concern; - } - - if (!(flags & MONGOC_INSERT_NO_VALIDATE)) { - for (i = 0; i < n_documents; i++) { - if (!_mongoc_validate_new_document ( - documents[i], _mongoc_default_insert_vflags, error)) { - RETURN (false); - } - } - } - - bson_clear (&collection->gle); - - _mongoc_write_result_init (&result); - - write_flags.ordered = !(flags & MONGOC_INSERT_CONTINUE_ON_ERROR); - - _mongoc_write_command_init_insert ( - &command, - NULL, - NULL, - write_flags, - ++collection->client->cluster.operation_id); - - for (i = 0; i < n_documents; i++) { - _mongoc_write_command_insert_append (&command, documents[i]); - } - - _mongoc_collection_write_command_execute ( - &command, collection, write_concern, NULL, &result); - - collection->gle = bson_new (); - ret = MONGOC_WRITE_RESULT_COMPLETE (&result, - collection->client->error_api_version, - write_concern, - /* no error domain override */ - (mongoc_error_domain_t) 0, - collection->gle, - error); - - _mongoc_write_result_destroy (&result); - _mongoc_write_command_destroy (&command); - - return ret; -} - - -bool -mongoc_collection_insert (mongoc_collection_t *collection, - mongoc_insert_flags_t flags, - const bson_t *document, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) -{ - bson_t opts = BSON_INITIALIZER; - bson_t reply; - bool r; - - bson_clear (&collection->gle); - - if (flags & MONGOC_INSERT_NO_VALIDATE) { - bson_append_bool (&opts, "validate", 8, false); - } - - if (write_concern) { - mongoc_write_concern_append ((mongoc_write_concern_t *) write_concern, - &opts); - } - - r = - mongoc_collection_insert_one (collection, document, &opts, &reply, error); - - collection->gle = bson_copy (&reply); - bson_destroy (&reply); - bson_destroy (&opts); - - return r; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_insert_one -- - * - * Insert a document into a MongoDB collection. - * - * Parameters: - * @collection: A mongoc_collection_t. - * @document: The document to insert. - * @opts: Standard command options. - * @reply: Optional. Uninitialized doc to receive the update result. - * @error: A location for an error or NULL. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * If the write concern does not dictate checking the result of the - * insert, then true may be returned even though the document was - * not actually inserted on the MongoDB server or cluster. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_insert_one (mongoc_collection_t *collection, - const bson_t *document, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_insert_one_opts_t insert_one_opts; - mongoc_write_command_t command; - mongoc_write_result_t result; - bool ret = false; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (document); - - _mongoc_bson_init_if_set (reply); - - if (!_mongoc_insert_one_opts_parse ( - collection->client, opts, &insert_one_opts, error)) { - GOTO (done); - } - - if (!_mongoc_validate_new_document ( - document, insert_one_opts.crud.validate, error)) { - GOTO (done); - } - - _mongoc_write_result_init (&result); - _mongoc_write_command_init_insert_idl ( - &command, - document, - &insert_one_opts.extra, - ++collection->client->cluster.operation_id); - - command.flags.bypass_document_validation = insert_one_opts.bypass; - _mongoc_collection_write_command_execute_idl ( - &command, collection, &insert_one_opts.crud, &result); - - ret = MONGOC_WRITE_RESULT_COMPLETE (&result, - collection->client->error_api_version, - insert_one_opts.crud.writeConcern, - /* no error domain override */ - (mongoc_error_domain_t) 0, - reply, - error, - "insertedCount"); - - _mongoc_write_result_destroy (&result); - _mongoc_write_command_destroy (&command); - -done: - _mongoc_insert_one_opts_cleanup (&insert_one_opts); - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_insert_many -- - * - * Insert documents into a MongoDB collection. Replaces - * mongoc_collection_insert_bulk. - * - * Parameters: - * @collection: A mongoc_collection_t. - * @documents: The documents to insert. - * @n_documents: Length of @documents array. - * @opts: Standard command options. - * @reply: Optional. Uninitialized doc to receive the update result. - * @error: A location for an error or NULL. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * If the write concern does not dictate checking the result of the - * insert, then true may be returned even though the document was - * not actually inserted on the MongoDB server or cluster. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_insert_many (mongoc_collection_t *collection, - const bson_t **documents, - size_t n_documents, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_insert_many_opts_t insert_many_opts; - mongoc_write_command_t command; - mongoc_write_result_t result; - size_t i; - bool ret; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (documents); - - _mongoc_bson_init_if_set (reply); - - if (!_mongoc_insert_many_opts_parse ( - collection->client, opts, &insert_many_opts, error)) { - _mongoc_insert_many_opts_cleanup (&insert_many_opts); - return false; - } - - _mongoc_write_result_init (&result); - _mongoc_write_command_init_insert_idl ( - &command, - NULL, - &insert_many_opts.extra, - ++collection->client->cluster.operation_id); - - command.flags.ordered = insert_many_opts.ordered; - command.flags.bypass_document_validation = insert_many_opts.bypass; - - for (i = 0; i < n_documents; i++) { - if (!_mongoc_validate_new_document ( - documents[i], insert_many_opts.crud.validate, error)) { - ret = false; - GOTO (done); - } - - _mongoc_write_command_insert_append (&command, documents[i]); - } - - _mongoc_collection_write_command_execute_idl ( - &command, collection, &insert_many_opts.crud, &result); - - ret = MONGOC_WRITE_RESULT_COMPLETE (&result, - collection->client->error_api_version, - insert_many_opts.crud.writeConcern, - /* no error domain override */ - (mongoc_error_domain_t) 0, - reply, - error, - "insertedCount"); - -done: - _mongoc_write_result_destroy (&result); - _mongoc_write_command_destroy (&command); - _mongoc_insert_many_opts_cleanup (&insert_many_opts); - - RETURN (ret); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_update -- - * - * Updates one or more documents matching @selector with @update. - * - * Parameters: - * @collection: A mongoc_collection_t. - * @flags: The flags for the update. - * @selector: A bson_t containing your selector. - * @update: A bson_t containing your update document. - * @write_concern: The write concern or NULL. - * @error: A location for an error or NULL. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @collection->gle is setup, depending on write_concern->w value. - * @error is setup upon failure. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_update (mongoc_collection_t *collection, - mongoc_update_flags_t uflags, - const bson_t *selector, - const bson_t *update, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) -{ - mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; - mongoc_write_command_t command; - mongoc_write_result_t result; - bson_iter_t iter; - bool ret; - int flags = uflags; - bson_t opts; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (selector); - BSON_ASSERT (update); - - bson_clear (&collection->gle); - - if (!write_concern) { - write_concern = collection->write_concern; - } - - if (!((uint32_t) flags & MONGOC_UPDATE_NO_VALIDATE) && - bson_iter_init (&iter, update) && bson_iter_next (&iter)) { - if (bson_iter_key (&iter)[0] == '$') { - /* update document, all keys must be $-operators */ - if (!_mongoc_validate_update ( - update, _mongoc_default_update_vflags, error)) { - return false; - } - } else { - if (!_mongoc_validate_replace ( - update, _mongoc_default_replace_vflags, error)) { - return false; - } - } - } - - bson_init (&opts); - BSON_APPEND_BOOL (&opts, "upsert", !!(flags & MONGOC_UPDATE_UPSERT)); - BSON_APPEND_BOOL (&opts, "multi", !!(flags & MONGOC_UPDATE_MULTI_UPDATE)); - - _mongoc_write_result_init (&result); - _mongoc_write_command_init_update ( - &command, - selector, - update, - &opts, - write_flags, - ++collection->client->cluster.operation_id); - bson_destroy (&opts); - - command.flags.has_multi_write = !!(flags & MONGOC_UPDATE_MULTI_UPDATE); - - _mongoc_collection_write_command_execute ( - &command, collection, write_concern, NULL, &result); - - collection->gle = bson_new (); - ret = MONGOC_WRITE_RESULT_COMPLETE (&result, - collection->client->error_api_version, - write_concern, - /* no error domain override */ - (mongoc_error_domain_t) 0, - collection->gle, - error); - - _mongoc_write_result_destroy (&result); - _mongoc_write_command_destroy (&command); - - RETURN (ret); -} - -static bool -_mongoc_collection_update_or_replace (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *update, - mongoc_update_opts_t *update_opts, - bool multi, - bool bypass, - const bson_t *array_filters, - bson_t *extra, - bson_t *reply, - bson_error_t *error) -{ - mongoc_write_command_t command; - mongoc_write_result_t result; - mongoc_server_stream_t *server_stream = NULL; - bool reply_initialized = false; - bool ret = false; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (selector); - BSON_ASSERT (update); - - if (update_opts->upsert) { - bson_append_bool (extra, "upsert", 6, true); - } - - if (!bson_empty (&update_opts->collation)) { - bson_append_document (extra, "collation", 9, &update_opts->collation); - } - - if (!bson_empty0 (array_filters)) { - bson_append_array (extra, "arrayFilters", 12, array_filters); - } - - if (multi) { - bson_append_bool (extra, "multi", 5, true); - } - - _mongoc_write_result_init (&result); - _mongoc_write_command_init_update_idl ( - &command, - selector, - update, - extra, - ++collection->client->cluster.operation_id); - - command.flags.has_multi_write = multi; - command.flags.bypass_document_validation = bypass; - if (!bson_empty (&update_opts->collation)) { - command.flags.has_collation = true; - } - - server_stream = - mongoc_cluster_stream_for_writes (&collection->client->cluster, - update_opts->crud.client_session, - reply, - error); - - if (!server_stream) { - /* mongoc_cluster_stream_for_writes inits reply on error */ - reply_initialized = true; - GOTO (done); - } - - if (!bson_empty0 (array_filters)) { - if (server_stream->sd->max_wire_version < WIRE_VERSION_ARRAY_FILTERS) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support array filters"); - GOTO (done); - } - - if (!mongoc_write_concern_is_acknowledged ( - update_opts->crud.writeConcern)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "Cannot use array filters with unacknowledged writes"); - GOTO (done); - } - } - - if (_mongoc_client_session_in_txn (update_opts->crud.client_session) && - update_opts->crud.writeConcern) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set write concern after starting transaction"); - GOTO (done); - } - - if (!update_opts->crud.writeConcern && - !_mongoc_client_session_in_txn (update_opts->crud.client_session)) { - update_opts->crud.writeConcern = collection->write_concern; - update_opts->crud.write_concern_owned = false; - } - - _mongoc_write_command_execute_idl (&command, - collection->client, - server_stream, - collection->db, - collection->collection, - 0 /* offset */, - &update_opts->crud, - &result); - - _mongoc_bson_init_if_set (reply); - reply_initialized = true; - - /* set fields described in CRUD spec for the UpdateResult */ - ret = MONGOC_WRITE_RESULT_COMPLETE (&result, - collection->client->error_api_version, - update_opts->crud.writeConcern, - /* no error domain override */ - (mongoc_error_domain_t) 0, - reply, - error, - "modifiedCount", - "matchedCount", - "upsertedCount", - "upsertedId"); - -done: - _mongoc_write_result_destroy (&result); - mongoc_server_stream_cleanup (server_stream); - _mongoc_write_command_destroy (&command); - - if (!reply_initialized) { - _mongoc_bson_init_if_set (reply); - } - - RETURN (ret); -} - -bool -mongoc_collection_update_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_update_one_opts_t update_one_opts; - bool ret; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (update); - - if (!_mongoc_update_one_opts_parse ( - collection->client, opts, &update_one_opts, error)) { - _mongoc_update_one_opts_cleanup (&update_one_opts); - _mongoc_bson_init_if_set (reply); - return false; - } - - if (!_mongoc_validate_update ( - update, update_one_opts.update.crud.validate, error)) { - _mongoc_update_one_opts_cleanup (&update_one_opts); - _mongoc_bson_init_if_set (reply); - return false; - } - - ret = _mongoc_collection_update_or_replace (collection, - selector, - update, - &update_one_opts.update, - false /* multi */, - update_one_opts.update.bypass, - &update_one_opts.arrayFilters, - &update_one_opts.extra, - reply, - error); - - _mongoc_update_one_opts_cleanup (&update_one_opts); - - RETURN (ret); -} - -bool -mongoc_collection_update_many (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_update_many_opts_t update_many_opts; - bool ret; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (update); - - if (!_mongoc_update_many_opts_parse ( - collection->client, opts, &update_many_opts, error)) { - _mongoc_update_many_opts_cleanup (&update_many_opts); - _mongoc_bson_init_if_set (reply); - return false; - } - - if (!_mongoc_validate_update ( - update, update_many_opts.update.crud.validate, error)) { - _mongoc_update_many_opts_cleanup (&update_many_opts); - _mongoc_bson_init_if_set (reply); - return false; - } - - ret = _mongoc_collection_update_or_replace (collection, - selector, - update, - &update_many_opts.update, - true /* multi */, - update_many_opts.update.bypass, - &update_many_opts.arrayFilters, - &update_many_opts.extra, - reply, - error); - - _mongoc_update_many_opts_cleanup (&update_many_opts); - - RETURN (ret); -} - -bool -mongoc_collection_replace_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *replacement, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_replace_one_opts_t replace_one_opts; - bool ret; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (replacement); - - if (!_mongoc_replace_one_opts_parse ( - collection->client, opts, &replace_one_opts, error)) { - _mongoc_replace_one_opts_cleanup (&replace_one_opts); - _mongoc_bson_init_if_set (reply); - return false; - } - - if (!_mongoc_validate_replace ( - replacement, replace_one_opts.update.crud.validate, error)) { - _mongoc_replace_one_opts_cleanup (&replace_one_opts); - _mongoc_bson_init_if_set (reply); - return false; - } - - ret = _mongoc_collection_update_or_replace (collection, - selector, - replacement, - &replace_one_opts.update, - false /* multi */, - replace_one_opts.update.bypass, - NULL, - &replace_one_opts.extra, - reply, - error); - - _mongoc_replace_one_opts_cleanup (&replace_one_opts); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_save -- - * - * Save @document to @collection. - * - * If the document has an _id field, it will be updated. Otherwise, - * the document will be inserted into the collection. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @error is set upon failure if non-NULL. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_save (mongoc_collection_t *collection, - const bson_t *document, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) -{ - bson_iter_t iter; - bool ret; - bson_t selector; - - BSON_ASSERT (collection); - BSON_ASSERT (document); - - BEGIN_IGNORE_DEPRECATIONS - if (!bson_iter_init_find (&iter, document, "_id")) { - return mongoc_collection_insert ( - collection, MONGOC_INSERT_NONE, document, write_concern, error); - } - - bson_init (&selector); - if (!bson_append_iter (&selector, NULL, 0, &iter)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Failed to append bson to create update."); - bson_destroy (&selector); - return false; - } - - /* this document will be inserted, validate same as for inserts */ - if (!_mongoc_validate_new_document ( - document, _mongoc_default_insert_vflags, error)) { - return false; - } - - ret = mongoc_collection_update (collection, - MONGOC_UPDATE_UPSERT | - MONGOC_UPDATE_NO_VALIDATE, - &selector, - document, - write_concern, - error); - END_IGNORE_DEPRECATIONS - - bson_destroy (&selector); - - return ret; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_remove -- - * - * Delete one or more items from a collection. If you want to - * limit to a single delete, provided MONGOC_REMOVE_SINGLE_REMOVE - * for @flags. - * - * Superseded by mongoc_collection_delete_one/many. - * - * Parameters: - * @collection: A mongoc_collection_t. - * @flags: the delete flags or 0. - * @selector: A selector of documents to delete. - * @write_concern: A write concern or NULL. If NULL, the default - * write concern for the collection will be used. - * @error: A location for an error or NULL. - * - * Returns: - * true if successful; otherwise false and error is set. - * - * If the write concern does not dictate checking the result, this - * function may return true even if it failed. - * - * Side effects: - * @collection->gle is setup, depending on write_concern->w value. - * @error is setup upon failure. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_remove (mongoc_collection_t *collection, - mongoc_remove_flags_t flags, - const bson_t *selector, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) -{ - mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; - mongoc_write_command_t command; - mongoc_write_result_t result; - bson_t opts; - bool ret; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (selector); - - bson_clear (&collection->gle); - - if (!write_concern) { - write_concern = collection->write_concern; - } - - bson_init (&opts); - BSON_APPEND_INT32 ( - &opts, "limit", flags & MONGOC_REMOVE_SINGLE_REMOVE ? 1 : 0); - _mongoc_write_result_init (&result); - ++collection->client->cluster.operation_id; - _mongoc_write_command_init_delete (&command, - selector, - NULL, - &opts, - write_flags, - collection->client->cluster.operation_id); - bson_destroy (&opts); - - command.flags.has_multi_write = !(flags & MONGOC_REMOVE_SINGLE_REMOVE); - - _mongoc_collection_write_command_execute ( - &command, collection, write_concern, NULL, &result); - - collection->gle = bson_new (); - ret = MONGOC_WRITE_RESULT_COMPLETE (&result, - collection->client->error_api_version, - write_concern, - 0 /* no error domain override */, - collection->gle, - error); - - _mongoc_write_result_destroy (&result); - _mongoc_write_command_destroy (&command); - - RETURN (ret); -} - - -bool -mongoc_collection_delete (mongoc_collection_t *collection, - mongoc_delete_flags_t flags, - const bson_t *selector, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) -{ - return mongoc_collection_remove (collection, - (mongoc_remove_flags_t) flags, - selector, - write_concern, - error); -} - - -static bool -_mongoc_delete_one_or_many (mongoc_collection_t *collection, - bool multi, - const bson_t *selector, - mongoc_crud_opts_t *crud, - const bson_t *cmd_opts, - const bson_t *collation, - bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_write_command_t command; - mongoc_write_result_t result; - bool ret; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (selector); - BSON_ASSERT (bson_empty0 (reply)); - - _mongoc_write_result_init (&result); - bson_append_int32 (opts, "limit", 5, multi ? 0 : 1); - - if (!bson_empty (collation)) { - bson_append_document (opts, "collation", 9, collation); - } - - _mongoc_write_command_init_delete_idl ( - &command, - selector, - cmd_opts, - opts, - ++collection->client->cluster.operation_id); - - command.flags.has_multi_write = multi; - if (!bson_empty (collation)) { - command.flags.has_collation = true; - } - - _mongoc_collection_write_command_execute_idl ( - &command, collection, crud, &result); - - /* set field described in CRUD spec for the DeleteResult */ - ret = MONGOC_WRITE_RESULT_COMPLETE (&result, - collection->client->error_api_version, - crud->writeConcern, - /* no error domain override */ - (mongoc_error_domain_t) 0, - reply, - error, - "deletedCount"); - - _mongoc_write_result_destroy (&result); - _mongoc_write_command_destroy (&command); - - RETURN (ret); -} - - -bool -mongoc_collection_delete_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_delete_one_opts_t delete_one_opts; - bson_t limit = BSON_INITIALIZER; - bool ret = false; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (selector); - - _mongoc_bson_init_if_set (reply); - if (!_mongoc_delete_one_opts_parse ( - collection->client, opts, &delete_one_opts, error)) { - GOTO (done); - } - - ret = _mongoc_delete_one_or_many (collection, - false /* multi */, - selector, - &delete_one_opts.crud, - &delete_one_opts.extra, - &delete_one_opts.collation, - &limit, - reply, - error); - -done: - _mongoc_delete_one_opts_cleanup (&delete_one_opts); - bson_destroy (&limit); - - RETURN (ret); -} - -bool -mongoc_collection_delete_many (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_delete_many_opts_t delete_many_opts; - bson_t limit = BSON_INITIALIZER; - bool ret = false; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (selector); - - _mongoc_bson_init_if_set (reply); - if (!_mongoc_delete_many_opts_parse ( - collection->client, opts, &delete_many_opts, error)) { - GOTO (done); - } - - ret = _mongoc_delete_one_or_many (collection, - true /* multi */, - selector, - &delete_many_opts.crud, - &delete_many_opts.extra, - &delete_many_opts.collation, - &limit, - reply, - error); - -done: - _mongoc_delete_many_opts_cleanup (&delete_many_opts); - bson_destroy (&limit); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_get_read_prefs -- - * - * Fetch the default read preferences for the collection. - * - * Returns: - * A mongoc_read_prefs_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_read_prefs_t * -mongoc_collection_get_read_prefs (const mongoc_collection_t *collection) -{ - BSON_ASSERT (collection); - return collection->read_prefs; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_set_read_prefs -- - * - * Sets the default read preferences for the collection instance. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_collection_set_read_prefs (mongoc_collection_t *collection, - const mongoc_read_prefs_t *read_prefs) -{ - BSON_ASSERT (collection); - - if (collection->read_prefs) { - mongoc_read_prefs_destroy (collection->read_prefs); - collection->read_prefs = NULL; - } - - if (read_prefs) { - collection->read_prefs = mongoc_read_prefs_copy (read_prefs); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_get_read_concern -- - * - * Fetches the default read concern for the collection instance. - * - * Returns: - * A mongoc_read_concern_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_read_concern_t * -mongoc_collection_get_read_concern (const mongoc_collection_t *collection) -{ - BSON_ASSERT (collection); - - return collection->read_concern; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_set_read_concern -- - * - * Sets the default read concern for the collection instance. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_collection_set_read_concern (mongoc_collection_t *collection, - const mongoc_read_concern_t *read_concern) -{ - BSON_ASSERT (collection); - - if (collection->read_concern) { - mongoc_read_concern_destroy (collection->read_concern); - collection->read_concern = NULL; - } - - if (read_concern) { - collection->read_concern = mongoc_read_concern_copy (read_concern); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_get_write_concern -- - * - * Fetches the default write concern for the collection instance. - * - * Returns: - * A mongoc_write_concern_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_write_concern_t * -mongoc_collection_get_write_concern (const mongoc_collection_t *collection) -{ - BSON_ASSERT (collection); - - return collection->write_concern; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_set_write_concern -- - * - * Sets the default write concern for the collection instance. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_collection_set_write_concern ( - mongoc_collection_t *collection, const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (collection); - - if (collection->write_concern) { - mongoc_write_concern_destroy (collection->write_concern); - collection->write_concern = NULL; - } - - if (write_concern) { - collection->write_concern = mongoc_write_concern_copy (write_concern); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_get_name -- - * - * Returns the name of the collection, excluding the database name. - * - * Returns: - * A string which should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const char * -mongoc_collection_get_name (mongoc_collection_t *collection) -{ - BSON_ASSERT (collection); - - return collection->collection; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_get_last_error -- - * - * Returns a bulk result. - * - * Returns: - * NULL or a bson_t that should not be modified or freed. This value - * is not guaranteed to be persistent between calls into the - * mongoc_collection_t instance, and therefore must be copied if - * you would like to keep it around. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const bson_t * -mongoc_collection_get_last_error ( - const mongoc_collection_t *collection) /* IN */ -{ - BSON_ASSERT (collection); - - return collection->gle; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_validate -- - * - * Helper to call the validate command on the MongoDB server to - * validate the collection. - * - * Options may be additional options, or NULL. - * Currently supported options are: - * - * "full": Boolean - * - * If full is true, then perform a more resource intensive - * validation. - * - * The result is stored in reply. - * - * Returns: - * true if successful; otherwise false and @error is set. - * - * Side effects: - * @reply is set if successful. - * @error may be set. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_validate (mongoc_collection_t *collection, /* IN */ - const bson_t *options, /* IN */ - bson_t *reply, /* OUT */ - bson_error_t *error) /* IN */ -{ - bson_iter_t iter; - bson_t cmd = BSON_INITIALIZER; - bool ret = false; - bool reply_initialized = false; - - BSON_ASSERT (collection); - - if (options && bson_iter_init_find (&iter, options, "full") && - !BSON_ITER_HOLDS_BOOL (&iter)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "'full' must be a boolean value."); - goto cleanup; - } - - bson_append_utf8 ( - &cmd, "validate", 8, collection->collection, collection->collectionlen); - - if (options) { - bson_concat (&cmd, options); - } - - ret = - mongoc_collection_command_simple (collection, &cmd, NULL, reply, error); - reply_initialized = true; - -cleanup: - bson_destroy (&cmd); - - if (reply && !reply_initialized) { - bson_init (reply); - } - - return ret; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_rename -- - * - * Rename the collection to @new_name. - * - * If @new_db is NULL, the same db will be used. - * - * If @drop_target_before_rename is true, then a collection named - * @new_name will be dropped before renaming @collection to - * @new_name. - * - * Returns: - * true on success; false on failure and @error is set. - * - * Side effects: - * @error is set on failure. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_rename (mongoc_collection_t *collection, - const char *new_db, - const char *new_name, - bool drop_target_before_rename, - bson_error_t *error) -{ - return mongoc_collection_rename_with_opts ( - collection, new_db, new_name, drop_target_before_rename, NULL, error); -} - - -bool -mongoc_collection_rename_with_opts (mongoc_collection_t *collection, - const char *new_db, - const char *new_name, - bool drop_target_before_rename, - const bson_t *opts, - bson_error_t *error) -{ - bson_t cmd = BSON_INITIALIZER; - char newns[MONGOC_NAMESPACE_MAX + 1]; - bool ret; - - BSON_ASSERT (collection); - BSON_ASSERT (new_name); - - if (strchr (new_name, '$')) { - bson_set_error (error, - MONGOC_ERROR_NAMESPACE, - MONGOC_ERROR_NAMESPACE_INVALID, - "\"%s\" is an invalid collection name.", - new_name); - return false; - } - - bson_snprintf ( - newns, sizeof newns, "%s.%s", new_db ? new_db : collection->db, new_name); - - BSON_APPEND_UTF8 (&cmd, "renameCollection", collection->ns); - BSON_APPEND_UTF8 (&cmd, "to", newns); - - if (drop_target_before_rename) { - BSON_APPEND_BOOL (&cmd, "dropTarget", true); - } - - ret = _mongoc_client_command_with_opts (collection->client, - "admin", - &cmd, - MONGOC_CMD_WRITE, - opts, - MONGOC_QUERY_NONE, - NULL, /* user prefs */ - collection->read_prefs, - collection->read_concern, - collection->write_concern, - NULL, /* reply */ - error); - - if (ret) { - if (new_db) { - bson_snprintf (collection->db, sizeof collection->db, "%s", new_db); - } - - bson_snprintf ( - collection->collection, sizeof collection->collection, "%s", new_name); - collection->collectionlen = (int) strlen (collection->collection); - - bson_snprintf (collection->ns, - sizeof collection->ns, - "%s.%s", - collection->db, - new_name); - collection->nslen = (int) strlen (collection->ns); - } - - bson_destroy (&cmd); - - return ret; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_stats -- - * - * Fetches statistics about the collection. - * - * The result is stored in @stats, which should NOT be an initialized - * bson_t or a leak will occur. - * - * @stats, @options, and @error are optional. - * - * Returns: - * true on success and @stats is set. - * false on failure and @error is set. - * - * Side effects: - * @stats and @error. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_stats (mongoc_collection_t *collection, - const bson_t *options, - bson_t *stats, - bson_error_t *error) -{ - bson_iter_t iter; - bson_t cmd = BSON_INITIALIZER; - bool ret; - - BSON_ASSERT (collection); - - if (options && bson_iter_init_find (&iter, options, "scale") && - !BSON_ITER_HOLDS_INT32 (&iter)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "'scale' must be an int32 value."); - return false; - } - - BSON_APPEND_UTF8 (&cmd, "collStats", collection->collection); - - if (options) { - bson_concat (&cmd, options); - } - - /* Server Selection Spec: "may-use-secondary" commands SHOULD take a read - * preference argument and otherwise MUST use the default read preference - * from client, database or collection configuration. */ - ret = mongoc_collection_command_simple ( - collection, &cmd, collection->read_prefs, stats, error); - - bson_destroy (&cmd); - - return ret; -} - - -mongoc_bulk_operation_t * -mongoc_collection_create_bulk_operation ( - mongoc_collection_t *collection, - bool ordered, - const mongoc_write_concern_t *write_concern) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bool wc_ok = true; - - bson_append_bool (&opts, "ordered", 7, ordered); - if (write_concern) { - wc_ok = mongoc_write_concern_append ( - (mongoc_write_concern_t *) write_concern, &opts); - } - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - - bson_destroy (&opts); - - if (!wc_ok) { - bson_set_error (&bulk->result.error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid writeConcern"); - } - - return bulk; -} - - -mongoc_bulk_operation_t * -mongoc_collection_create_bulk_operation_with_opts ( - mongoc_collection_t *collection, const bson_t *opts) -{ - mongoc_bulk_opts_t bulk_opts; - mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; - mongoc_write_concern_t *wc = NULL; - mongoc_bulk_operation_t *bulk; - bson_error_t err = {0}; - - BSON_ASSERT (collection); - - (void) _mongoc_bulk_opts_parse (collection->client, opts, &bulk_opts, &err); - if (!_mongoc_client_session_in_txn (bulk_opts.client_session)) { - wc = COALESCE (bulk_opts.writeConcern, collection->write_concern); - } - write_flags.ordered = bulk_opts.ordered; - bulk = _mongoc_bulk_operation_new (collection->client, - collection->db, - collection->collection, - write_flags, - wc); - - bulk->session = bulk_opts.client_session; - if (err.domain) { - /* _mongoc_bulk_opts_parse failed, above */ - memcpy (&bulk->result.error, &err, sizeof (bson_error_t)); - } else if (_mongoc_client_session_in_txn (bulk_opts.client_session) && - !mongoc_write_concern_is_default (bulk_opts.writeConcern)) { - bson_set_error (&bulk->result.error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set write concern after starting transaction"); - } - - _mongoc_bulk_opts_cleanup (&bulk_opts); - - return bulk; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_find_and_modify_with_opts -- - * - * Find a document in @collection matching @query, applying @opts. - * - * If @reply is not NULL, then the result document will be placed - * in reply and should be released with bson_destroy(). - * - * See http://docs.mongodb.org/manual/reference/command/findAndModify/ - * for more information. - * - * Returns: - * true on success; false on failure. - * - * Side effects: - * reply is initialized. - * error is set if false is returned. - * - *-------------------------------------------------------------------------- - */ -bool -mongoc_collection_find_and_modify_with_opts ( - mongoc_collection_t *collection, - const bson_t *query, - const mongoc_find_and_modify_opts_t *opts, - bson_t *reply, - bson_error_t *error) -{ - mongoc_cluster_t *cluster; - mongoc_client_session_t *cs = NULL; - mongoc_cmd_parts_t parts; - bool is_retryable; - bson_iter_t iter; - bson_iter_t inner; - const char *name; - bson_t reply_local; - bson_t *reply_ptr; - bool ret = false; - bson_t command = BSON_INITIALIZER; - mongoc_server_stream_t *server_stream = NULL; - mongoc_server_stream_t *retry_server_stream = NULL; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (query); - BSON_ASSERT (opts); - - reply_ptr = reply ? reply : &reply_local; - cluster = &collection->client->cluster; - - mongoc_cmd_parts_init ( - &parts, collection->client, collection->db, MONGOC_QUERY_NONE, &command); - parts.is_read_command = true; - parts.is_write_command = true; - - /* we need a session to fetch a stream to call cmd_parts_append_opts - * below, which parses the session from opts->extra *again* - */ - if (bson_iter_init_find (&iter, &opts->extra, "sessionId")) { - if (!_mongoc_client_session_from_iter ( - collection->client, &iter, &cs, error)) { - bson_init (reply_ptr); - GOTO (done); - } - } - - server_stream = - mongoc_cluster_stream_for_writes (cluster, cs, reply_ptr, error); - - if (!server_stream) { - GOTO (done); - } - - bson_init (reply_ptr); - name = mongoc_collection_get_name (collection); - BSON_APPEND_UTF8 (&command, "findAndModify", name); - BSON_APPEND_DOCUMENT (&command, "query", query); - - if (opts->sort) { - BSON_APPEND_DOCUMENT (&command, "sort", opts->sort); - } - - if (opts->update) { - if (_mongoc_document_is_pipeline (opts->update)) { - BSON_APPEND_ARRAY (&command, "update", opts->update); - } else { - BSON_APPEND_DOCUMENT (&command, "update", opts->update); - } - } - - if (opts->fields) { - BSON_APPEND_DOCUMENT (&command, "fields", opts->fields); - } - - if (opts->flags & MONGOC_FIND_AND_MODIFY_REMOVE) { - BSON_APPEND_BOOL (&command, "remove", true); - } - - if (opts->flags & MONGOC_FIND_AND_MODIFY_UPSERT) { - BSON_APPEND_BOOL (&command, "upsert", true); - } - - if (opts->flags & MONGOC_FIND_AND_MODIFY_RETURN_NEW) { - BSON_APPEND_BOOL (&command, "new", true); - } - - if (opts->bypass_document_validation) { - BSON_APPEND_BOOL (&command, - "bypassDocumentValidation", - opts->bypass_document_validation); - } - - if (opts->max_time_ms > 0) { - BSON_APPEND_INT32 (&command, "maxTimeMS", opts->max_time_ms); - } - - if (bson_iter_init (&iter, &opts->extra)) { - bool ok = mongoc_cmd_parts_append_opts ( - &parts, &iter, server_stream->sd->max_wire_version, error); - if (!ok) { - GOTO (done); - } - } - - if (_mongoc_client_session_in_txn (parts.assembled.session) && - !bson_empty (&parts.write_concern_document)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set write concern after starting transaction"); - GOTO (done); - } - - if (!bson_has_field (&opts->extra, "writeConcern")) { - if (server_stream->sd->max_wire_version >= - WIRE_VERSION_FAM_WRITE_CONCERN) { - if (!mongoc_write_concern_is_valid (collection->write_concern)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The write concern is invalid."); - GOTO (done); - } - - if (mongoc_write_concern_is_acknowledged (collection->write_concern)) { - if (!mongoc_cmd_parts_set_write_concern ( - &parts, - collection->write_concern, - server_stream->sd->max_wire_version, - error)) { - GOTO (done); - } - } - } - } - - parts.assembled.operation_id = ++cluster->operation_id; - if (!mongoc_cmd_parts_assemble (&parts, server_stream, error)) { - GOTO (done); - } - - is_retryable = parts.is_retryable_write; - - /* increment the transaction number for the first attempt of each retryable - * write command */ - if (is_retryable) { - bson_iter_t txn_number_iter; - BSON_ASSERT (bson_iter_init_find ( - &txn_number_iter, parts.assembled.command, "txnNumber")); - bson_iter_overwrite_int64 ( - &txn_number_iter, - ++parts.assembled.session->server_session->txn_number); - } -retry: - bson_destroy (reply_ptr); - ret = mongoc_cluster_run_command_monitored ( - cluster, &parts.assembled, reply_ptr, error); - - if (is_retryable) { - _mongoc_write_error_update_if_unsupported_storage_engine ( - ret, error, reply_ptr); - } - - /* If a retryable error is encountered and the write is retryable, select - * a new writable stream and retry. If server selection fails or the selected - * server does not support retryable writes, fall through and allow the - * original error to be reported. */ - if (is_retryable && - _mongoc_write_error_get_type (ret, error, reply_ptr) == - MONGOC_WRITE_ERR_RETRY) { - bson_error_t ignored_error; - - /* each write command may be retried at most once */ - is_retryable = false; - retry_server_stream = mongoc_cluster_stream_for_writes ( - cluster, parts.assembled.session, NULL /* reply */, &ignored_error); - - if (retry_server_stream && - retry_server_stream->sd->max_wire_version >= - WIRE_VERSION_RETRY_WRITES) { - parts.assembled.server_stream = retry_server_stream; - GOTO (retry); - } - } - - if (bson_iter_init_find (&iter, reply_ptr, "writeConcernError") && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - const char *errmsg = NULL; - int32_t code = 0; - - BSON_ASSERT (bson_iter_recurse (&iter, &inner)); - while (bson_iter_next (&inner)) { - if (BSON_ITER_IS_KEY (&inner, "code")) { - code = bson_iter_int32 (&inner); - } else if (BSON_ITER_IS_KEY (&inner, "errmsg")) { - errmsg = bson_iter_utf8 (&inner, NULL); - } - } - bson_set_error (error, - MONGOC_ERROR_WRITE_CONCERN, - code, - "Write Concern error: %s", - errmsg); - ret = false; - } - - -done: - mongoc_server_stream_cleanup (server_stream); - mongoc_server_stream_cleanup (retry_server_stream); - mongoc_cmd_parts_cleanup (&parts); - bson_destroy (&command); - if (&reply_local == reply_ptr) { - bson_destroy (&reply_local); - } - RETURN (ret); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_collection_find_and_modify -- - * - * Find a document in @collection matching @query and update it with - * the update document @update. - * - * If @reply is not NULL, then the result document will be placed - * in reply and should be released with bson_destroy(). - * - * If @remove is true, then the matching documents will be removed. - * - * If @fields is not NULL, it will be used to select the desired - * resulting fields. - * - * If @_new is true, then the new version of the document is returned - * instead of the old document. - * - * See http://docs.mongodb.org/manual/reference/command/findAndModify/ - * for more information. - * - * Returns: - * true on success; false on failure. - * - * Side effects: - * reply is initialized. - * error is set if false is returned. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_collection_find_and_modify (mongoc_collection_t *collection, - const bson_t *query, - const bson_t *sort, - const bson_t *update, - const bson_t *fields, - bool _remove, - bool upsert, - bool _new, - bson_t *reply, - bson_error_t *error) -{ - mongoc_find_and_modify_opts_t *opts; - int flags = 0; - bool ret; - - ENTRY; - - BSON_ASSERT (collection); - BSON_ASSERT (query); - BSON_ASSERT (update || _remove); - - - if (_remove) { - flags |= MONGOC_FIND_AND_MODIFY_REMOVE; - } - if (upsert) { - flags |= MONGOC_FIND_AND_MODIFY_UPSERT; - } - if (_new) { - flags |= MONGOC_FIND_AND_MODIFY_RETURN_NEW; - } - - opts = mongoc_find_and_modify_opts_new (); - - mongoc_find_and_modify_opts_set_sort (opts, sort); - mongoc_find_and_modify_opts_set_update (opts, update); - mongoc_find_and_modify_opts_set_fields (opts, fields); - mongoc_find_and_modify_opts_set_flags (opts, flags); - - ret = mongoc_collection_find_and_modify_with_opts ( - collection, query, opts, reply, error); - mongoc_find_and_modify_opts_destroy (opts); - - return ret; -} - -mongoc_change_stream_t * -mongoc_collection_watch (const mongoc_collection_t *coll, - const bson_t *pipeline, - const bson_t *opts) -{ - return _mongoc_change_stream_new_from_collection (coll, pipeline, opts); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-collection.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-collection.h deleted file mode 100644 index babae4e03847cd0f3ae739545db9c84ec781d9a4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-collection.h +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright 2013-2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_COLLECTION_H -#define MONGOC_COLLECTION_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-change-stream.h" -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-bulk-operation.h" -#include "mongoc/mongoc-flags.h" -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-index.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-read-concern.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-find-and-modify.h" - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_collection_t mongoc_collection_t; - -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_collection_aggregate (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - const bson_t *pipeline, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (void) -mongoc_collection_destroy (mongoc_collection_t *collection); -MONGOC_EXPORT (mongoc_collection_t *) -mongoc_collection_copy (mongoc_collection_t *collection); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_collection_command (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *command, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (bool) -mongoc_collection_read_command_with_opts (mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_write_command_with_opts (mongoc_collection_t *collection, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_read_write_command_with_opts ( - mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* IGNORED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_command_with_opts (mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_command_simple (mongoc_collection_t *collection, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (int64_t) -mongoc_collection_count (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - const bson_t *query, - int64_t skip, - int64_t limit, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_count_documents or - mongoc_collection_estimated_document_count); -MONGOC_EXPORT (int64_t) -mongoc_collection_count_with_opts (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - const bson_t *query, - int64_t skip, - int64_t limit, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_count_documents or - mongoc_collection_estimated_document_count); -MONGOC_EXPORT (bool) -mongoc_collection_drop (mongoc_collection_t *collection, bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_drop_with_opts (mongoc_collection_t *collection, - const bson_t *opts, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_drop_index (mongoc_collection_t *collection, - const char *index_name, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_drop_index_with_opts (mongoc_collection_t *collection, - const char *index_name, - const bson_t *opts, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_create_index (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *opt, - bson_error_t *error) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (bool) -mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *opt, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) - BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (bool) -mongoc_collection_ensure_index (mongoc_collection_t *collection, - const bson_t *keys, - const mongoc_index_opt_t *opt, - bson_error_t *error) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_collection_find_indexes (mongoc_collection_t *collection, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_find_indexes_with_opts); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_collection_find_indexes_with_opts (mongoc_collection_t *collection, - const bson_t *opts); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_collection_find (mongoc_collection_t *collection, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *query, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_find_with_opts) - BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_collection_find_with_opts (mongoc_collection_t *collection, - const bson_t *filter, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs) - BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (bool) -mongoc_collection_insert (mongoc_collection_t *collection, - mongoc_insert_flags_t flags, - const bson_t *document, - const mongoc_write_concern_t *write_concern, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_insert_one (mongoc_collection_t *collection, - const bson_t *document, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_insert_many (mongoc_collection_t *collection, - const bson_t **documents, - size_t n_documents, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_insert_bulk (mongoc_collection_t *collection, - mongoc_insert_flags_t flags, - const bson_t **documents, - uint32_t n_documents, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_insert_many); -MONGOC_EXPORT (bool) -mongoc_collection_update (mongoc_collection_t *collection, - mongoc_update_flags_t flags, - const bson_t *selector, - const bson_t *update, - const mongoc_write_concern_t *write_concern, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_update_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_update_many (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_replace_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *replacement, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_delete (mongoc_collection_t *collection, - mongoc_delete_flags_t flags, - const bson_t *selector, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_delete_one or - mongoc_collection_delete_many); -MONGOC_EXPORT (bool) -mongoc_collection_save (mongoc_collection_t *collection, - const bson_t *document, - const mongoc_write_concern_t *write_concern, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_insert_one or - mongoc_collection_replace_one); -MONGOC_EXPORT (bool) -mongoc_collection_remove (mongoc_collection_t *collection, - mongoc_remove_flags_t flags, - const bson_t *selector, - const mongoc_write_concern_t *write_concern, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_delete_one (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_delete_many (mongoc_collection_t *collection, - const bson_t *selector, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_rename (mongoc_collection_t *collection, - const char *new_db, - const char *new_name, - bool drop_target_before_rename, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_rename_with_opts (mongoc_collection_t *collection, - const char *new_db, - const char *new_name, - bool drop_target_before_rename, - const bson_t *opts, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_find_and_modify_with_opts ( - mongoc_collection_t *collection, - const bson_t *query, - const mongoc_find_and_modify_opts_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_find_and_modify (mongoc_collection_t *collection, - const bson_t *query, - const bson_t *sort, - const bson_t *update, - const bson_t *fields, - bool _remove, - bool upsert, - bool _new, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_collection_stats (mongoc_collection_t *collection, - const bson_t *options, - bson_t *reply, - bson_error_t *error) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (mongoc_bulk_operation_t *) -mongoc_collection_create_bulk_operation ( - mongoc_collection_t *collection, - bool ordered, - const mongoc_write_concern_t *write_concern) BSON_GNUC_WARN_UNUSED_RESULT - BSON_GNUC_DEPRECATED_FOR (mongoc_collection_create_bulk_operation_with_opts); -MONGOC_EXPORT (mongoc_bulk_operation_t *) -mongoc_collection_create_bulk_operation_with_opts ( - mongoc_collection_t *collection, - const bson_t *opts) BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (const mongoc_read_prefs_t *) -mongoc_collection_get_read_prefs (const mongoc_collection_t *collection); -MONGOC_EXPORT (void) -mongoc_collection_set_read_prefs (mongoc_collection_t *collection, - const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (const mongoc_read_concern_t *) -mongoc_collection_get_read_concern (const mongoc_collection_t *collection); -MONGOC_EXPORT (void) -mongoc_collection_set_read_concern (mongoc_collection_t *collection, - const mongoc_read_concern_t *read_concern); -MONGOC_EXPORT (const mongoc_write_concern_t *) -mongoc_collection_get_write_concern (const mongoc_collection_t *collection); -MONGOC_EXPORT (void) -mongoc_collection_set_write_concern ( - mongoc_collection_t *collection, - const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (const char *) -mongoc_collection_get_name (mongoc_collection_t *collection); -MONGOC_EXPORT (const bson_t *) -mongoc_collection_get_last_error (const mongoc_collection_t *collection) - BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (char *) -mongoc_collection_keys_to_index_string (const bson_t *keys); -MONGOC_EXPORT (bool) -mongoc_collection_validate (mongoc_collection_t *collection, - const bson_t *options, - bson_t *reply, - bson_error_t *error) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (mongoc_change_stream_t *) -mongoc_collection_watch (const mongoc_collection_t *coll, - const bson_t *pipeline, - const bson_t *opts); -MONGOC_EXPORT (int64_t) -mongoc_collection_count_documents (mongoc_collection_t *coll, - const bson_t *filter, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (int64_t) -mongoc_collection_estimated_document_count ( - mongoc_collection_t *coll, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); - -BSON_END_DECLS - - -#endif /* MONGOC_COLLECTION_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-compression-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-compression-private.h deleted file mode 100644 index f1ccaae14de213ba1e1b58d0abe7b357f51eb044..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-compression-private.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_COMPRESSION_PRIVATE_H -#define MONGOC_COMPRESSION_PRIVATE_H - -#include "bson/bson.h" - -/* Compressor IDs */ -#define MONGOC_COMPRESSOR_NOOP_ID 0 -#define MONGOC_COMPRESSOR_NOOP_STR "noop" - -#define MONGOC_COMPRESSOR_SNAPPY_ID 1 -#define MONGOC_COMPRESSOR_SNAPPY_STR "snappy" - -#define MONGOC_COMPRESSOR_ZLIB_ID 2 -#define MONGOC_COMPRESSOR_ZLIB_STR "zlib" - -#define MONGOC_COMPRESSOR_ZSTD_ID 3 -#define MONGOC_COMPRESSOR_ZSTD_STR "zstd" - - -BSON_BEGIN_DECLS - - -size_t -mongoc_compressor_max_compressed_length (int32_t compressor_id, size_t size); - -bool -mongoc_compressor_supported (const char *compressor); - -const char * -mongoc_compressor_id_to_name (int32_t compressor_id); - -int -mongoc_compressor_name_to_id (const char *compressor); - -bool -mongoc_uncompress (int32_t compressor_id, - const uint8_t *compressed, - size_t compressed_len, - uint8_t *uncompressed, - size_t *uncompressed_size); - -bool -mongoc_compress (int32_t compressor_id, - int32_t compression_level, - char *uncompressed, - size_t uncompressed_len, - char *compressed, - size_t *compressed_len); - -BSON_END_DECLS - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-compression.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-compression.c deleted file mode 100644 index 3c041df2793bd1abb3c42e94c385e6a12faef858..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-compression.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-config.h" - -#include "mongoc/mongoc-compression-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" - -#ifdef MONGOC_ENABLE_COMPRESSION -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB -#include <zlib.h> -#endif -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY -#include <snappy-c.h> -#endif -#ifdef MONGOC_ENABLE_COMPRESSION_ZSTD -#include <zstd.h> -#endif -#endif - -size_t -mongoc_compressor_max_compressed_length (int32_t compressor_id, size_t len) -{ - TRACE ("Getting compression length for '%s' (%d)", - mongoc_compressor_id_to_name (compressor_id), - compressor_id); - switch (compressor_id) { -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - case MONGOC_COMPRESSOR_SNAPPY_ID: - return snappy_max_compressed_length (len); - break; -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - case MONGOC_COMPRESSOR_ZLIB_ID: - return compressBound (len); - break; -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_ZSTD - case MONGOC_COMPRESSOR_ZSTD_ID: - return ZSTD_compressBound (len); - break; -#endif - case MONGOC_COMPRESSOR_NOOP_ID: - return len; - break; - default: - return 0; - } -} - -bool -mongoc_compressor_supported (const char *compressor) -{ -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - if (!strcasecmp (compressor, MONGOC_COMPRESSOR_SNAPPY_STR)) { - return true; - } -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - if (!strcasecmp (compressor, MONGOC_COMPRESSOR_ZLIB_STR)) { - return true; - } -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_ZSTD - if (!strcasecmp (compressor, MONGOC_COMPRESSOR_ZSTD_STR)) { - return true; - } -#endif - - if (!strcasecmp (compressor, MONGOC_COMPRESSOR_NOOP_STR)) { - return true; - } - - return false; -} - -const char * -mongoc_compressor_id_to_name (int32_t compressor_id) -{ - switch (compressor_id) { - case MONGOC_COMPRESSOR_SNAPPY_ID: - return MONGOC_COMPRESSOR_SNAPPY_STR; - - case MONGOC_COMPRESSOR_ZLIB_ID: - return MONGOC_COMPRESSOR_ZLIB_STR; - - case MONGOC_COMPRESSOR_ZSTD_ID: - return MONGOC_COMPRESSOR_ZSTD_STR; - - case MONGOC_COMPRESSOR_NOOP_ID: - return MONGOC_COMPRESSOR_NOOP_STR; - - default: - return "unknown"; - } -} - -int -mongoc_compressor_name_to_id (const char *compressor) -{ -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - if (strcasecmp (MONGOC_COMPRESSOR_SNAPPY_STR, compressor) == 0) { - return MONGOC_COMPRESSOR_SNAPPY_ID; - } -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - if (strcasecmp (MONGOC_COMPRESSOR_ZLIB_STR, compressor) == 0) { - return MONGOC_COMPRESSOR_ZLIB_ID; - } -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_ZSTD - if (strcasecmp (MONGOC_COMPRESSOR_ZSTD_STR, compressor) == 0) { - return MONGOC_COMPRESSOR_ZSTD_ID; - } -#endif - - if (strcasecmp (MONGOC_COMPRESSOR_NOOP_STR, compressor) == 0) { - return MONGOC_COMPRESSOR_NOOP_ID; - } - - return -1; -} - -bool -mongoc_uncompress (int32_t compressor_id, - const uint8_t *compressed, - size_t compressed_len, - uint8_t *uncompressed, - size_t *uncompressed_len) -{ - TRACE ("Uncompressing with '%s' (%d)", - mongoc_compressor_id_to_name (compressor_id), - compressor_id); - - switch (compressor_id) { - case MONGOC_COMPRESSOR_SNAPPY_ID: { -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - snappy_status status; - status = snappy_uncompress ((const char *) compressed, - compressed_len, - (char *) uncompressed, - uncompressed_len); - - return status == SNAPPY_OK; -#else - MONGOC_WARNING ("Received snappy compressed opcode, but snappy " - "compression is not compiled in"); - return false; -#endif - break; - } - - case MONGOC_COMPRESSOR_ZLIB_ID: { -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - int ok; - - ok = uncompress (uncompressed, - (unsigned long *) uncompressed_len, - compressed, - compressed_len); - - return ok == Z_OK; -#else - MONGOC_WARNING ("Received zlib compressed opcode, but zlib " - "compression is not compiled in"); - return false; -#endif - break; - } - - case MONGOC_COMPRESSOR_ZSTD_ID: { -#ifdef MONGOC_ENABLE_COMPRESSION_ZSTD - int ok; - - ok = - ZSTD_decompress ((void *) uncompressed, - *uncompressed_len, - (const void *) compressed, - compressed_len); - - if (!ZSTD_isError (ok)) { - *uncompressed_len = ok; - } - - return !ZSTD_isError (ok); -#else - MONGOC_WARNING ("Received zstd compressed opcode, but zstd " - "compression is not compiled in"); - return false; -#endif - break; - } - case MONGOC_COMPRESSOR_NOOP_ID: - memcpy (uncompressed, compressed, compressed_len); - *uncompressed_len = compressed_len; - return true; - - default: - MONGOC_WARNING ("Unknown compressor ID %d", compressor_id); - } - - return false; -} - -bool -mongoc_compress (int32_t compressor_id, - int32_t compression_level, - char *uncompressed, - size_t uncompressed_len, - char *compressed, - size_t *compressed_len) -{ - TRACE ("Compressing with '%s' (%d)", - mongoc_compressor_id_to_name (compressor_id), - compressor_id); - switch (compressor_id) { - case MONGOC_COMPRESSOR_SNAPPY_ID: -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - /* No compression_level option for snappy */ - return snappy_compress ( - uncompressed, uncompressed_len, compressed, compressed_len) == - SNAPPY_OK; -#else - MONGOC_ERROR ("Client attempting to use compress with snappy, but snappy " - "compression is not compiled in"); - return false; -#endif - - case MONGOC_COMPRESSOR_ZLIB_ID: -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - return compress2 ((unsigned char *) compressed, - (unsigned long *) compressed_len, - (unsigned char *) uncompressed, - uncompressed_len, - compression_level) == Z_OK; -#else - MONGOC_ERROR ("Client attempting to use compress with zlib, but zlib " - "compression is not compiled in"); - return false; -#endif - - case MONGOC_COMPRESSOR_ZSTD_ID: { -#ifdef MONGOC_ENABLE_COMPRESSION_ZSTD - int ok; - - ok = ZSTD_compress ((void *) compressed, - *compressed_len, - (const void *) uncompressed, - uncompressed_len, - 0); - - if (!ZSTD_isError (ok)) { - *compressed_len = ok; - } - return !ZSTD_isError (ok); -#else - MONGOC_ERROR ("Client attempting to use compress with zstd, but zstd " - "compression is not compiled in"); - return false; -#endif - } - case MONGOC_COMPRESSOR_NOOP_ID: - memcpy (compressed, uncompressed, uncompressed_len); - *compressed_len = uncompressed_len; - return true; - - default: - return false; - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-config.h.in b/lib/mongoc/libmongoc/src/mongoc/mongoc-config.h.in deleted file mode 100644 index 560db6d3c0aa4636eafc1124c8919a0128743035..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-config.h.in +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2013 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. - */ - -#if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) -#error "Only <mongoc/mongoc.h> can be included directly." -#endif - - -#ifndef MONGOC_CONFIG_H -#define MONGOC_CONFIG_H - -/* MONGOC_USER_SET_CFLAGS is set from config based on what compiler flags were - * used to compile mongoc */ -#define MONGOC_USER_SET_CFLAGS "@MONGOC_USER_SET_CFLAGS@" - -#define MONGOC_USER_SET_LDFLAGS "@MONGOC_USER_SET_LDFLAGS@" - -/* MONGOC_CC is used to determine what C compiler was used to compile mongoc */ -#define MONGOC_CC "@MONGOC_CC@" - -/* - * MONGOC_ENABLE_SSL_SECURE_CHANNEL is set from configure to determine if we are - * compiled with Native SSL support on Windows - */ -#define MONGOC_ENABLE_SSL_SECURE_CHANNEL @MONGOC_ENABLE_SSL_SECURE_CHANNEL@ - -#if MONGOC_ENABLE_SSL_SECURE_CHANNEL != 1 -# undef MONGOC_ENABLE_SSL_SECURE_CHANNEL -#endif - - -/* - * MONGOC_ENABLE_CRYPTO_CNG is set from configure to determine if we are - * compiled with Native Crypto support on Windows - */ -#define MONGOC_ENABLE_CRYPTO_CNG @MONGOC_ENABLE_CRYPTO_CNG@ - -#if MONGOC_ENABLE_CRYPTO_CNG != 1 -# undef MONGOC_ENABLE_CRYPTO_CNG -#endif - - -/* - * MONGOC_ENABLE_SSL_SECURE_TRANSPORT is set from configure to determine if we are - * compiled with Native SSL support on Darwin - */ -#define MONGOC_ENABLE_SSL_SECURE_TRANSPORT @MONGOC_ENABLE_SSL_SECURE_TRANSPORT@ - -#if MONGOC_ENABLE_SSL_SECURE_TRANSPORT != 1 -# undef MONGOC_ENABLE_SSL_SECURE_TRANSPORT -#endif - - -/* - * MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO is set from configure to determine if we are - * compiled with Native Crypto support on Darwin - */ -#define MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO @MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO@ - -#if MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO != 1 -# undef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO -#endif - - -/* - * MONGOC_ENABLE_SSL_LIBRESSL is set from configure to determine if we are - * compiled with LibreSSL support. - */ -#define MONGOC_ENABLE_SSL_LIBRESSL @MONGOC_ENABLE_SSL_LIBRESSL@ - -#if MONGOC_ENABLE_SSL_LIBRESSL != 1 -# undef MONGOC_ENABLE_SSL_LIBRESSL -#endif - - -/* - * MONGOC_ENABLE_SSL_OPENSSL is set from configure to determine if we are - * compiled with OpenSSL support. - */ -#define MONGOC_ENABLE_SSL_OPENSSL @MONGOC_ENABLE_SSL_OPENSSL@ - -#if MONGOC_ENABLE_SSL_OPENSSL != 1 -# undef MONGOC_ENABLE_SSL_OPENSSL -#endif - - -/* - * MONGOC_ENABLE_CRYPTO_LIBCRYPTO is set from configure to determine if we are - * compiled with OpenSSL support. - */ -#define MONGOC_ENABLE_CRYPTO_LIBCRYPTO @MONGOC_ENABLE_CRYPTO_LIBCRYPTO@ - -#if MONGOC_ENABLE_CRYPTO_LIBCRYPTO != 1 -# undef MONGOC_ENABLE_CRYPTO_LIBCRYPTO -#endif - - -/* - * MONGOC_ENABLE_SSL is set from configure to determine if we are - * compiled with any SSL support. - */ -#define MONGOC_ENABLE_SSL @MONGOC_ENABLE_SSL@ - -#if MONGOC_ENABLE_SSL != 1 -# undef MONGOC_ENABLE_SSL -#endif - - -/* - * MONGOC_ENABLE_CRYPTO is set from configure to determine if we are - * compiled with any crypto support. - */ -#define MONGOC_ENABLE_CRYPTO @MONGOC_ENABLE_CRYPTO@ - -#if MONGOC_ENABLE_CRYPTO != 1 -# undef MONGOC_ENABLE_CRYPTO -#endif - - -/* - * Use system crypto profile - */ -#define MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE @MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE@ - -#if MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE != 1 -# undef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE -#endif - - -/* - * Use ASN1_STRING_get0_data () rather than the deprecated ASN1_STRING_data - */ -#define MONGOC_HAVE_ASN1_STRING_GET0_DATA @MONGOC_HAVE_ASN1_STRING_GET0_DATA@ - -#if MONGOC_HAVE_ASN1_STRING_GET0_DATA != 1 -# undef MONGOC_HAVE_ASN1_STRING_GET0_DATA -#endif - - -/* - * MONGOC_ENABLE_SASL is set from configure to determine if we are - * compiled with SASL support. - */ -#define MONGOC_ENABLE_SASL @MONGOC_ENABLE_SASL@ - -#if MONGOC_ENABLE_SASL != 1 -# undef MONGOC_ENABLE_SASL -#endif - - -/* - * MONGOC_ENABLE_SASL_CYRUS is set from configure to determine if we are - * compiled with Cyrus SASL support. - */ -#define MONGOC_ENABLE_SASL_CYRUS @MONGOC_ENABLE_SASL_CYRUS@ - -#if MONGOC_ENABLE_SASL_CYRUS != 1 -# undef MONGOC_ENABLE_SASL_CYRUS -#endif - - -/* - * MONGOC_ENABLE_SASL_SSPI is set from configure to determine if we are - * compiled with SSPI support. - */ -#define MONGOC_ENABLE_SASL_SSPI @MONGOC_ENABLE_SASL_SSPI@ - -#if MONGOC_ENABLE_SASL_SSPI != 1 -# undef MONGOC_ENABLE_SASL_SSPI -#endif - -/* - * MONGOC_HAVE_SASL_CLIENT_DONE is set from configure to determine if we - * have SASL and its version is new enough to use sasl_client_done (), - * which supersedes sasl_done (). - */ -#define MONGOC_HAVE_SASL_CLIENT_DONE @MONGOC_HAVE_SASL_CLIENT_DONE@ - -#if MONGOC_HAVE_SASL_CLIENT_DONE != 1 -# undef MONGOC_HAVE_SASL_CLIENT_DONE -#endif - - -/* - * Disable automatic calls to mongoc_init() and mongoc_cleanup() - * before main() is called, and after exit() (respectively). - */ -#define MONGOC_NO_AUTOMATIC_GLOBALS @MONGOC_NO_AUTOMATIC_GLOBALS@ - -#if MONGOC_NO_AUTOMATIC_GLOBALS != 1 -# undef MONGOC_NO_AUTOMATIC_GLOBALS -#endif - -/* - * MONGOC_HAVE_SOCKLEN is set from configure to determine if we - * need to emulate the type. - */ -#define MONGOC_HAVE_SOCKLEN @MONGOC_HAVE_SOCKLEN@ - -#if MONGOC_HAVE_SOCKLEN != 1 -# undef MONGOC_HAVE_SOCKLEN -#endif - - -/* - * MONGOC_HAVE_DNSAPI is set from configure to determine if we should use the - * Windows dnsapi for SRV record lookups. - */ -#define MONGOC_HAVE_DNSAPI @MONGOC_HAVE_DNSAPI@ - -#if MONGOC_HAVE_DNSAPI != 1 -# undef MONGOC_HAVE_DNSAPI -#endif - - -/* - * MONGOC_HAVE_RES_NSEARCH is set from configure to determine if we - * have thread-safe res_nsearch(). - */ -#define MONGOC_HAVE_RES_NSEARCH @MONGOC_HAVE_RES_NSEARCH@ - -#if MONGOC_HAVE_RES_NSEARCH != 1 -# undef MONGOC_HAVE_RES_NSEARCH -#endif - - -/* - * MONGOC_HAVE_RES_NDESTROY is set from configure to determine if we - * have BSD / Darwin's res_ndestroy(). - */ -#define MONGOC_HAVE_RES_NDESTROY @MONGOC_HAVE_RES_NDESTROY@ - -#if MONGOC_HAVE_RES_NDESTROY != 1 -# undef MONGOC_HAVE_RES_NDESTROY -#endif - - -/* - * MONGOC_HAVE_RES_NCLOSE is set from configure to determine if we - * have Linux's res_nclose(). - */ -#define MONGOC_HAVE_RES_NCLOSE @MONGOC_HAVE_RES_NCLOSE@ - -#if MONGOC_HAVE_RES_NCLOSE != 1 -# undef MONGOC_HAVE_RES_NCLOSE -#endif - - -/* - * MONGOC_HAVE_RES_SEARCH is set from configure to determine if we - * have thread-unsafe res_search(). It's unset if we have the preferred - * res_nsearch(). - */ -#define MONGOC_HAVE_RES_SEARCH @MONGOC_HAVE_RES_SEARCH@ - -#if MONGOC_HAVE_RES_SEARCH != 1 -# undef MONGOC_HAVE_RES_SEARCH -#endif - - -/* - * Set from configure, see - * https://curl.haxx.se/mail/lib-2009-04/0287.html - */ -#define MONGOC_SOCKET_ARG2 @MONGOC_SOCKET_ARG2@ -#define MONGOC_SOCKET_ARG3 @MONGOC_SOCKET_ARG3@ - -/* - * Enable wire protocol compression negotiation - * - */ -#define MONGOC_ENABLE_COMPRESSION @MONGOC_ENABLE_COMPRESSION@ - -#if MONGOC_ENABLE_COMPRESSION != 1 -# undef MONGOC_ENABLE_COMPRESSION -#endif - -/* - * Set if we have snappy compression support - * - */ -#define MONGOC_ENABLE_COMPRESSION_SNAPPY @MONGOC_ENABLE_COMPRESSION_SNAPPY@ - -#if MONGOC_ENABLE_COMPRESSION_SNAPPY != 1 -# undef MONGOC_ENABLE_COMPRESSION_SNAPPY -#endif - - -/* - * Set if we have zlib compression support - * - */ -#define MONGOC_ENABLE_COMPRESSION_ZLIB @MONGOC_ENABLE_COMPRESSION_ZLIB@ - -#if MONGOC_ENABLE_COMPRESSION_ZLIB != 1 -# undef MONGOC_ENABLE_COMPRESSION_ZLIB -#endif - -/* - * Set if we have zstd compression support - * - */ -#define MONGOC_ENABLE_COMPRESSION_ZSTD @MONGOC_ENABLE_COMPRESSION_ZSTD@ - -#if MONGOC_ENABLE_COMPRESSION_ZSTD != 1 -# undef MONGOC_ENABLE_COMPRESSION_ZSTD -#endif - -/* - * Set if performance counters are available and not disabled. - * - */ -#define MONGOC_ENABLE_SHM_COUNTERS @MONGOC_ENABLE_SHM_COUNTERS@ - -#if MONGOC_ENABLE_SHM_COUNTERS != 1 -# undef MONGOC_ENABLE_SHM_COUNTERS -#endif - -/* - * Set if we have enabled fast counters on Intel using the RDTSCP instruction - * - */ -#define MONGOC_ENABLE_RDTSCP @MONGOC_ENABLE_RDTSCP@ - -#if MONGOC_ENABLE_RDTSCP != 1 -# undef MONGOC_ENABLE_RDTSCP -#endif - - -/* - * Set if we have the sched_getcpu() function for use with counters - * - */ -#define MONGOC_HAVE_SCHED_GETCPU @MONGOC_HAVE_SCHED_GETCPU@ - -#if MONGOC_HAVE_SCHED_GETCPU != 1 -# undef MONGOC_HAVE_SCHED_GETCPU -#endif - -/* - * Set if tracing is enabled. Logs things like network communication and - * entry/exit of certain functions. - * - */ -#define MONGOC_TRACE @MONGOC_TRACE@ - -#if MONGOC_TRACE != 1 -# undef MONGOC_TRACE -#endif - -/* - * Set if we have ICU support. - */ -#define MONGOC_ENABLE_ICU @MONGOC_ENABLE_ICU@ - -#if MONGOC_ENABLE_ICU != 1 -# undef MONGOC_ENABLE_ICU -#endif - - -/* - * Set if we have Client Side Encryption support. - */ - -#define MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION @MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION@ - -#if MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION != 1 -# undef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION -#endif - -/* - * NOTICE: - * If you're about to update this file and add a config flag, make sure to - * update: - * o The bitfield in mongoc-handshake-private.h - * o _mongoc_handshake_get_config_hex_string() in mongoc-handshake.c - * o examples/parse_handshake_cfg.py - * o test_handshake_config_string in test-mongoc-handshake.c - */ - -#endif /* MONGOC_CONFIG_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-counters-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-counters-private.h deleted file mode 100644 index bb25875751a7bea0e2f1911cf4df2f5acb71178c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-counters-private.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_COUNTERS_PRIVATE_H -#define MONGOC_COUNTERS_PRIVATE_H - -#include <mongoc/mongoc.h> -#include <bson/bson.h> - -#ifdef __linux__ -#include <sched.h> -#include <sys/sysinfo.h> -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ - defined(__OpenBSD__) -#include <sys/types.h> -#include <sys/sysctl.h> -#include <sys/param.h> -#elif defined(__hpux__) -#include <sys/pstat.h> -#endif - - -BSON_BEGIN_DECLS - - -void -_mongoc_counters_init (void); -void -_mongoc_counters_cleanup (void); - - -static BSON_INLINE unsigned -_mongoc_get_cpu_count (void) -{ -#if defined(__linux__) - return get_nprocs (); -#elif defined(__hpux__) - struct pst_dynamic psd; - - if (pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) != -1) { - return psd.psd_max_proc_cnt; - } - return 1; -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ - defined(__OpenBSD__) - int mib[2]; - int maxproc; - size_t len; - - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - len = sizeof (maxproc); - - if (-1 == sysctl (mib, 2, &maxproc, &len, NULL, 0)) { - return 1; - } - - return len; -#elif defined(__APPLE__) || defined(__sun) || defined(_AIX) - int ncpu; - - ncpu = (int) sysconf (_SC_NPROCESSORS_ONLN); - return (ncpu > 0) ? ncpu : 1; -#elif defined(_MSC_VER) || defined(_WIN32) - SYSTEM_INFO si; - GetSystemInfo (&si); - return si.dwNumberOfProcessors; -#else -#warning "_mongoc_get_cpu_count() not supported, defaulting to 1." - return 1; -#endif -} - - -#define _mongoc_counter_add(v, count) bson_atomic_int64_add (&(v), (count)) - - -#if defined(MONGOC_ENABLE_RDTSCP) -static BSON_INLINE unsigned -_mongoc_sched_getcpu (void) -{ - volatile uint32_t rax, rdx, rcx; - __asm__ volatile("rdtscp\n" : "=a"(rax), "=d"(rdx), "=c"(rcx) : :); - unsigned node_id, core_id; - // node_id = (rcx & 0xFFF000)>>12; // node_id is unused - core_id = rcx & 0xFFF; - return core_id; -} -#elif defined(MONGOC_HAVE_SCHED_GETCPU) -#define _mongoc_sched_getcpu sched_getcpu -#else -#define _mongoc_sched_getcpu() (0) -#endif - - -#ifndef SLOTS_PER_CACHELINE -#define SLOTS_PER_CACHELINE 8 -#endif - - -typedef struct { - int64_t slots[SLOTS_PER_CACHELINE]; -} mongoc_counter_slots_t; - - -typedef struct { - mongoc_counter_slots_t *cpus; -} mongoc_counter_t; - - -#define COUNTER(ident, Category, Name, Description) \ - extern mongoc_counter_t __mongoc_counter_##ident; -#include "mongoc-counters.defs" -#undef COUNTER - - -enum { -#define COUNTER(ident, Category, Name, Description) COUNTER_##ident, -#include "mongoc-counters.defs" -#undef COUNTER - LAST_COUNTER -}; - -#ifdef MONGOC_ENABLE_SHM_COUNTERS -#define COUNTER(ident, Category, Name, Description) \ - static BSON_INLINE void mongoc_counter_##ident##_add (int64_t val) \ - { \ - (void) _mongoc_counter_add ( \ - __mongoc_counter_##ident.cpus[_mongoc_sched_getcpu ()] \ - .slots[COUNTER_##ident % SLOTS_PER_CACHELINE], \ - val); \ - } \ - static BSON_INLINE void mongoc_counter_##ident##_inc (void) \ - { \ - mongoc_counter_##ident##_add (1); \ - } \ - static BSON_INLINE void mongoc_counter_##ident##_dec (void) \ - { \ - mongoc_counter_##ident##_add (-1); \ - } \ - static BSON_INLINE void mongoc_counter_##ident##_reset (void) \ - { \ - uint32_t i; \ - for (i = 0; i < _mongoc_get_cpu_count (); i++) { \ - __mongoc_counter_##ident.cpus[i] \ - .slots[COUNTER_##ident % SLOTS_PER_CACHELINE] = 0; \ - } \ - bson_memory_barrier (); \ - } -#include "mongoc-counters.defs" -#undef COUNTER -#else -/* when counters are disabled, these functions are no-ops */ -#define COUNTER(ident, Category, Name, Description) \ - static BSON_INLINE void mongoc_counter_##ident##_add (int64_t val) \ - { \ - } \ - static BSON_INLINE void mongoc_counter_##ident##_inc (void) \ - { \ - } \ - static BSON_INLINE void mongoc_counter_##ident##_dec (void) \ - { \ - } \ - static BSON_INLINE void mongoc_counter_##ident##_reset (void) \ - { \ - } -#include "mongoc-counters.defs" -#undef COUNTER -#endif - -BSON_END_DECLS - - -#endif /* MONGOC_COUNTERS_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-counters.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-counters.c deleted file mode 100644 index 608d51b4eeb57bfd210a9eb2dac654c661ae6d08..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-counters.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright 2013 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 <bson/bson.h> - -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> - -#ifdef BSON_OS_UNIX -#include <sys/mman.h> -#include <sys/shm.h> -#endif - -#ifdef _MSC_VER -#include <windows.h> -#endif - -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-log.h" - - -#pragma pack(1) -typedef struct { - uint32_t offset; - uint32_t slot; - char category[24]; - char name[32]; - char description[64]; -} mongoc_counter_info_t; -#pragma pack() - - -BSON_STATIC_ASSERT2 (counter_info_t, sizeof (mongoc_counter_info_t) == 128); - - -#pragma pack(1) -typedef struct { - uint32_t size; - uint32_t n_cpu; - uint32_t n_counters; - uint32_t infos_offset; - uint32_t values_offset; - uint8_t padding[44]; -} mongoc_counters_t; -#pragma pack() - - -BSON_STATIC_ASSERT2 (counters_t, sizeof (mongoc_counters_t) == 64); - -#ifdef MONGOC_ENABLE_SHM_COUNTERS -/* When counters are enabled at compile time but fail to initiate a shared - * memory segment, then fall back to a malloc'd segment. This malloc'd segment - * isn't useful to anyone. But by using this fallback, the counter increment - * functions can behave the same. I.e. they do not need to have a runtime check - * for whether or not initiating the shared memory segment succeeded. */ -static void *gCounterFallback = NULL; - -#define COUNTER(ident, Category, Name, Description) \ - mongoc_counter_t __mongoc_counter_##ident; -#include "mongoc-counters.defs" -#undef COUNTER - -/** - * mongoc_counters_use_shm: - * - * Checks to see if counters should be exported over a shared memory segment. - * - * Returns: true if SHM is to be used. - */ -static bool -mongoc_counters_use_shm (void) -{ - return !getenv ("MONGOC_DISABLE_SHM"); -} - -/** - * mongoc_counters_calc_size: - * - * Returns the number of bytes required for the shared memory segment of - * the process. This segment contains the various statistical counters for - * the process. - * - * Returns: The number of bytes required. - */ -static size_t -mongoc_counters_calc_size (void) -{ - size_t n_cpu; - size_t n_groups; - size_t size; - - n_cpu = _mongoc_get_cpu_count (); - n_groups = (LAST_COUNTER / SLOTS_PER_CACHELINE) + 1; - size = (sizeof (mongoc_counters_t) + - (LAST_COUNTER * sizeof (mongoc_counter_info_t)) + - (n_cpu * n_groups * sizeof (mongoc_counter_slots_t))); - -#ifdef BSON_OS_UNIX - return BSON_MAX (getpagesize (), size); -#else - return size; -#endif -} -#endif - - -/** - * mongoc_counters_destroy: - * - * Removes the shared memory segment for the current processes counters. - */ -void -_mongoc_counters_cleanup (void) -{ -#ifdef MONGOC_ENABLE_SHM_COUNTERS - if (gCounterFallback) { - bson_free (gCounterFallback); - gCounterFallback = NULL; -#if defined(BSON_OS_UNIX) && defined(MONGOC_ENABLE_SHM_COUNTERS) - } else { - char name[32]; - int pid; - - pid = getpid (); - bson_snprintf (name, sizeof name, "/mongoc-%u", pid); - shm_unlink (name); -#endif - } -#endif -} - - -#ifdef MONGOC_ENABLE_SHM_COUNTERS -/** - * mongoc_counters_alloc: - * @size: The size of the shared memory segment. - * - * This function allocates the shared memory segment for use by counters - * within the process. - * - * Returns: A shared memory segment, or malloc'd memory on failure. - */ -static void * -mongoc_counters_alloc (size_t size) -{ -#if defined(BSON_OS_UNIX) && defined(MONGOC_ENABLE_SHM_COUNTERS) - void *mem; - char name[32]; - int pid; - int fd; - - if (!mongoc_counters_use_shm ()) { - goto skip_shm; - } - - pid = getpid (); - bson_snprintf (name, sizeof name, "/mongoc-%u", pid); - -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0 -#endif - if (-1 == (fd = shm_open (name, - O_CREAT | O_EXCL | O_RDWR, - S_IRUSR | S_IWUSR | O_NOFOLLOW))) { - goto fail_noclean; - } - - /* - * NOTE: - * - * ftruncate() will cause reads to be zero. Therefore, we don't need to - * do write() of zeroes to initialize the shared memory area. - */ - if (-1 == ftruncate (fd, size)) { - goto fail_cleanup; - } - - mem = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (mem == MAP_FAILED) { - goto fail_cleanup; - } - - close (fd); - memset (mem, 0, size); - - return mem; - -fail_cleanup: - shm_unlink (name); - close (fd); - -fail_noclean: - MONGOC_WARNING ("Falling back to malloc for counters."); - -skip_shm: -#endif - - gCounterFallback = (void *) bson_malloc0 (size); - - return gCounterFallback; -} - - -/** - * mongoc_counters_register: - * @counters: A mongoc_counter_t. - * @num: The counter number. - * @category: The counter category. - * @name: THe counter name. - * @description The counter description. - * - * Registers a new counter in the memory segment for counters. If the counters - * are exported over shared memory, it will be made available. - * - * Returns: The offset to the data for the counters values. - */ -static size_t -mongoc_counters_register (mongoc_counters_t *counters, - uint32_t num, - const char *category, - const char *name, - const char *description) -{ - mongoc_counter_info_t *infos; - char *segment; - int n_cpu; - - BSON_ASSERT (counters); - BSON_ASSERT (category); - BSON_ASSERT (name); - BSON_ASSERT (description); - - /* - * Implementation Note: - * - * The memory barrier is required so that all of the above has been - * completed. Then increment the n_counters so that a reading application - * only knows about the counter after we have initialized it. - */ - - n_cpu = _mongoc_get_cpu_count (); - segment = (char *) counters; - - infos = (mongoc_counter_info_t *) (segment + counters->infos_offset); - infos = &infos[counters->n_counters]; - infos->slot = num % SLOTS_PER_CACHELINE; - infos->offset = - (counters->values_offset + - ((num / SLOTS_PER_CACHELINE) * n_cpu * sizeof (mongoc_counter_slots_t))); - - bson_strncpy (infos->category, category, sizeof infos->category); - bson_strncpy (infos->name, name, sizeof infos->name); - bson_strncpy (infos->description, description, sizeof infos->description); - - bson_memory_barrier (); - - counters->n_counters++; - - return infos->offset; -} -#endif - -/** - * mongoc_counters_init: - * - * Initializes the mongoc counters system. This should be run on library - * initialization using the GCC constructor attribute. - */ -void -_mongoc_counters_init (void) -{ -#ifdef MONGOC_ENABLE_SHM_COUNTERS - mongoc_counter_info_t *info; - mongoc_counters_t *counters; - size_t infos_size; - size_t off; - size_t size; - char *segment; - - size = mongoc_counters_calc_size (); - segment = (char *) mongoc_counters_alloc (size); - infos_size = LAST_COUNTER * sizeof *info; - - counters = (mongoc_counters_t *) segment; - counters->n_cpu = _mongoc_get_cpu_count (); - counters->n_counters = 0; - counters->infos_offset = sizeof *counters; - counters->values_offset = (uint32_t) (counters->infos_offset + infos_size); - - BSON_ASSERT ((counters->values_offset % 64) == 0); - -#define COUNTER(ident, Category, Name, Desc) \ - off = mongoc_counters_register ( \ - counters, COUNTER_##ident, Category, Name, Desc); \ - __mongoc_counter_##ident.cpus = (mongoc_counter_slots_t *) (segment + off); -#include "mongoc-counters.defs" -#undef COUNTER - - /* - * NOTE: - * - * Only update the size of the shared memory area for the client after - * we have initialized the rest of the counters. Don't forget our memory - * barrier to prevent compiler reordering. - */ - bson_memory_barrier (); - counters->size = (uint32_t) size; -#endif -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-counters.defs b/lib/mongoc/libmongoc/src/mongoc/mongoc-counters.defs deleted file mode 100644 index 7b779edca42b1965906711ba584f6ac3e6517d05..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-counters.defs +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013 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. - */ - - -COUNTER(op_egress_total, "Operations", "Egress Total", "The number of sent operations.") -COUNTER(op_ingress_total, "Operations", "Ingress Total", "The number of received operations.") -COUNTER(op_egress_msg, "Operations", "Egress Messages", "The number of sent messages operations.") -COUNTER(op_ingress_msg, "Operations", "Ingress Messages", "The number of received messages operations.") -COUNTER(op_egress_compressed, "Operations", "Egress Compressed", "The number of sent compressed operations.") -COUNTER(op_ingress_compressed, "Operations", "Ingress Compressed", "The number of received compressed operations.") -COUNTER(op_egress_query, "Operations", "Egress Queries", "The number of sent Query operations.") -COUNTER(op_ingress_reply, "Operations", "Ingress Reply", "The number of received Reply operations.") -COUNTER(op_egress_getmore, "Operations", "Egress GetMore", "The number of sent GetMore operations.") -COUNTER(op_egress_insert, "Operations", "Egress Insert", "The number of sent Insert operations.") -COUNTER(op_egress_delete, "Operations", "Egress Delete", "The number of sent Delete operations.") -COUNTER(op_egress_update, "Operations", "Egress Update", "The number of sent Update operations.") -COUNTER(op_egress_killcursors, "Operations", "Egress KillCursors", "The number of sent KillCursors operations.") - - -COUNTER(cursors_active, "Cursors", "Active", "The number of active cursors.") -COUNTER(cursors_disposed, "Cursors", "Disposed", "The number of disposed cursors.") - - -COUNTER(clients_active, "Clients", "Active", "The number of active clients.") -COUNTER(clients_disposed, "Clients", "Disposed", "The number of disposed clients.") - - -COUNTER(streams_active, "Streams", "Active", "The number of active streams.") -COUNTER(streams_disposed, "Streams", "Disposed", "The number of disposed streams.") -COUNTER(streams_egress, "Streams", "Egress Bytes", "The number of bytes sent.") -COUNTER(streams_ingress, "Streams", "Ingress Bytes", "The number of bytes received.") -COUNTER(streams_timeout, "Streams", "N Socket Timeouts", "The number of socket timeouts.") - - -COUNTER(client_pools_active, "Client Pools", "Active", "The number of active client pools.") -COUNTER(client_pools_disposed, "Client Pools", "Disposed", "The number of disposed client pools.") - - -COUNTER(protocol_ingress_error, "Protocol", "Ingress Errors", "The number of protocol errors on ingress.") - - -COUNTER(auth_failure, "Auth", "Failures", "The number of failed authentication requests.") -COUNTER(auth_success, "Auth", "Success", "The number of successful authentication requests.") - - -COUNTER(dns_failure, "DNS", "Failure", "The number of failed DNS requests.") -COUNTER(dns_success, "DNS", "Success", "The number of successful DNS requests.") - diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-cng-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-cng-private.h deleted file mode 100644 index 47a2dca5e4d79886ac670635f3d77ab2626a7370..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-cng-private.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifdef MONGOC_ENABLE_CRYPTO_CNG - -#ifndef MONGOC_CRYPTO_CNG_PRIVATE_H -#define MONGOC_CRYPTO_CNG_PRIVATE_H - - -#include "mongoc/mongoc-config.h" - - -BSON_BEGIN_DECLS - -void -mongoc_crypto_cng_init (void); - -void -mongoc_crypto_cng_cleanup (void); - -void -mongoc_crypto_cng_hmac_sha1 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out); - -bool -mongoc_crypto_cng_sha1 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out); - -void -mongoc_crypto_cng_hmac_sha256 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out); - -bool -mongoc_crypto_cng_sha256 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out); - - -BSON_END_DECLS - -#endif /* MONGOC_CRYPTO_CNG_PRIVATE_H */ -#endif /* MONGOC_ENABLE_CRYPTO_CNG */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-cng.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-cng.c deleted file mode 100644 index 1c9cc9e8ff26abf33999707427e8ffc31d221a69..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-cng.c +++ /dev/null @@ -1,239 +0,0 @@ -/* Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_CRYPTO_CNG -#include "mongoc/mongoc-crypto-private.h" -#include "mongoc/mongoc-crypto-cng-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-thread-private.h" - -#include <windows.h> -#include <stdio.h> -#include <bcrypt.h> - -#define NT_SUCCESS(Status) (((NTSTATUS) (Status)) >= 0) -#define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L) - -static BCRYPT_ALG_HANDLE _sha1_hash_algo; -static BCRYPT_ALG_HANDLE _sha1_hmac_algo; -static BCRYPT_ALG_HANDLE _sha256_hash_algo; -static BCRYPT_ALG_HANDLE _sha256_hmac_algo; - -void -mongoc_crypto_cng_init (void) -{ - NTSTATUS status = STATUS_UNSUCCESSFUL; - _sha1_hash_algo = 0; - status = BCryptOpenAlgorithmProvider ( - &_sha1_hash_algo, BCRYPT_SHA1_ALGORITHM, NULL, 0); - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA1): %x", status); - } - - _sha1_hmac_algo = 0; - status = BCryptOpenAlgorithmProvider (&_sha1_hmac_algo, - BCRYPT_SHA1_ALGORITHM, - NULL, - BCRYPT_ALG_HANDLE_HMAC_FLAG); - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA1 HMAC): %x", status); - } - - _sha256_hash_algo = 0; - status = BCryptOpenAlgorithmProvider ( - &_sha256_hash_algo, BCRYPT_SHA256_ALGORITHM, NULL, 0); - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA256): %x", status); - } - - _sha256_hmac_algo = 0; - status = BCryptOpenAlgorithmProvider (&_sha256_hmac_algo, - BCRYPT_SHA256_ALGORITHM, - NULL, - BCRYPT_ALG_HANDLE_HMAC_FLAG); - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA256 HMAC): %x", status); - } -} - -void -mongoc_crypto_cng_cleanup (void) -{ - if (_sha1_hash_algo) { - BCryptCloseAlgorithmProvider (&_sha1_hash_algo, 0); - } - if (_sha1_hmac_algo) { - BCryptCloseAlgorithmProvider (&_sha1_hmac_algo, 0); - } - if (_sha256_hash_algo) { - BCryptCloseAlgorithmProvider (&_sha256_hash_algo, 0); - } - if (_sha256_hash_algo) { - BCryptCloseAlgorithmProvider (&_sha256_hash_algo, 0); - } -} - -bool -_mongoc_crypto_cng_hmac_or_hash (BCRYPT_ALG_HANDLE algorithm, - void *key, - size_t key_length, - void *data, - size_t data_length, - void *output) -{ - char *hash_object_buffer = 0; - ULONG hash_object_length = 0; - BCRYPT_HASH_HANDLE hash = 0; - ULONG mac_length = 0; - NTSTATUS status = STATUS_UNSUCCESSFUL; - bool retval = false; - ULONG noop = 0; - - status = BCryptGetProperty (algorithm, - BCRYPT_OBJECT_LENGTH, - (char *) &hash_object_length, - sizeof hash_object_length, - &noop, - 0); - - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptGetProperty(): OBJECT_LENGTH %x", status); - return false; - } - - status = BCryptGetProperty (algorithm, - BCRYPT_HASH_LENGTH, - (char *) &mac_length, - sizeof mac_length, - &noop, - 0); - - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptGetProperty(): HASH_LENGTH %x", status); - return false; - } - - hash_object_buffer = bson_malloc (hash_object_length); - - status = BCryptCreateHash (algorithm, - &hash, - hash_object_buffer, - hash_object_length, - key, - (ULONG) key_length, - 0); - - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptCreateHash(): %x", status); - goto cleanup; - } - - status = BCryptHashData (hash, data, (ULONG) data_length, 0); - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptHashData(): %x", status); - goto cleanup; - } - - status = BCryptFinishHash (hash, output, mac_length, 0); - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptFinishHash(): %x", status); - goto cleanup; - } - - retval = true; - -cleanup: - if (hash) { - (void) BCryptDestroyHash (hash); - } - - bson_free (hash_object_buffer); - return retval; -} - -void -mongoc_crypto_cng_hmac_sha1 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out) -{ - NTSTATUS status = STATUS_UNSUCCESSFUL; - - if (!_sha1_hmac_algo) { - return; - } - - _mongoc_crypto_cng_hmac_or_hash ( - _sha1_hmac_algo, key, key_len, data, data_len, hmac_out); -} - -bool -mongoc_crypto_cng_sha1 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out) -{ - NTSTATUS status = STATUS_UNSUCCESSFUL; - bool res; - - if (!_sha1_hash_algo) { - return false; - } - - res = _mongoc_crypto_cng_hmac_or_hash ( - _sha1_hash_algo, NULL, 0, input, input_len, hash_out); - return res; -} - -void -mongoc_crypto_cng_hmac_sha256 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out) -{ - NTSTATUS status = STATUS_UNSUCCESSFUL; - - if (!_sha256_hmac_algo) { - return; - } - - _mongoc_crypto_cng_hmac_or_hash ( - _sha256_hmac_algo, key, key_len, data, data_len, hmac_out); -} - -bool -mongoc_crypto_cng_sha256 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out) -{ - NTSTATUS status = STATUS_UNSUCCESSFUL; - bool res; - - if (!_sha256_hash_algo) { - return false; - } - - res = _mongoc_crypto_cng_hmac_or_hash ( - _sha256_hash_algo, NULL, 0, input, input_len, hash_out); - return res; -} -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h deleted file mode 100644 index 12d6aba6f30333b0b0f68c3c43af45e41e780209..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO - -#ifndef MONGOC_CRYPTO_COMMON_CRYPTO_PRIVATE_H -#define MONGOC_CRYPTO_COMMON_CRYPTO_PRIVATE_H - - -#include "mongoc/mongoc-config.h" - - -BSON_BEGIN_DECLS - -void -mongoc_crypto_common_crypto_hmac_sha1 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out); - -bool -mongoc_crypto_common_crypto_sha1 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out); - -void -mongoc_crypto_common_crypto_hmac_sha256 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out); - -bool -mongoc_crypto_common_crypto_sha256 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out); - -BSON_END_DECLS - -#endif /* MONGOC_CRYPTO_COMMON_CRYPTO_PRIVATE_H */ -#endif /* MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c deleted file mode 100644 index 93dfe3f49fd9d25136ecb072d0ecd5a65e96fe5d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright 2016 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 "mongoc/mongoc-config.h" -#include "mongoc/mongoc-crypto-private.h" - -#ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO -#include "mongoc/mongoc-crypto-common-crypto-private.h" -#include <CommonCrypto/CommonHMAC.h> -#include <CommonCrypto/CommonDigest.h> - - -void -mongoc_crypto_common_crypto_hmac_sha1 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out) -{ - /* U1 = HMAC(input, salt + 0001) */ - CCHmac ( - kCCHmacAlgSHA1, key, (size_t) key_len, data, (size_t) data_len, hmac_out); -} - -bool -mongoc_crypto_common_crypto_sha1 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out) -{ - if (CC_SHA1 (input, (CC_LONG) input_len, hash_out)) { - return true; - } - return false; -} - -void -mongoc_crypto_common_crypto_hmac_sha256 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out) -{ - CCHmac (kCCHmacAlgSHA256, - key, - (size_t) key_len, - data, - (size_t) data_len, - hmac_out); -} - -bool -mongoc_crypto_common_crypto_sha256 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out) -{ - if (CC_SHA256 (input, (CC_LONG) input_len, hash_out)) { - return true; - } - return false; -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h deleted file mode 100644 index de8eabb0b5c1d590aa7d435985d7c81a88f08602..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#include "mongoc/mongoc-config.h" -#include <bson/bson.h> - -#ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO - -#ifndef MONGOC_CRYPTO_OPENSSL_PRIVATE_H -#define MONGOC_CRYPTO_OPENSSL_PRIVATE_H - -#include "mongoc/mongoc-crypto-private.h" - -BSON_BEGIN_DECLS - -void -mongoc_crypto_openssl_hmac_sha1 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out); - -bool -mongoc_crypto_openssl_sha1 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out); - -void -mongoc_crypto_openssl_hmac_sha256 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out); - -bool -mongoc_crypto_openssl_sha256 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out); - -BSON_END_DECLS -#endif /* MONGOC_CRYPTO_OPENSSL_PRIVATE_H */ -#endif /* MONGOC_ENABLE_CRYPTO_LIBCRYPTO */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-openssl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-openssl.c deleted file mode 100644 index e40ec10c9e8d879e9c48aa549a6ade20732cc514..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-openssl.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" -#include <bson/bson.h> - -#ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO -#include "mongoc/mongoc-crypto-openssl-private.h" -#include "mongoc/mongoc-crypto-private.h" - -#include <openssl/sha.h> -#include <openssl/evp.h> -#include <openssl/hmac.h> - - -void -mongoc_crypto_openssl_hmac_sha1 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out) -{ - /* U1 = HMAC(input, salt + 0001) */ - HMAC (EVP_sha1 (), key, key_len, data, data_len, hmac_out, NULL); -} - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) -EVP_MD_CTX * -EVP_MD_CTX_new (void) -{ - return bson_malloc0 (sizeof (EVP_MD_CTX)); -} - -void -EVP_MD_CTX_free (EVP_MD_CTX *ctx) -{ - EVP_MD_CTX_cleanup (ctx); - bson_free (ctx); -} -#endif - -bool -mongoc_crypto_openssl_sha1 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out) -{ - EVP_MD_CTX *digest_ctxp = EVP_MD_CTX_new (); - bool rval = false; - - if (1 != EVP_DigestInit_ex (digest_ctxp, EVP_sha1 (), NULL)) { - goto cleanup; - } - - if (1 != EVP_DigestUpdate (digest_ctxp, input, input_len)) { - goto cleanup; - } - - rval = (1 == EVP_DigestFinal_ex (digest_ctxp, hash_out, NULL)); - -cleanup: - EVP_MD_CTX_free (digest_ctxp); - - return rval; -} - -void -mongoc_crypto_openssl_hmac_sha256 (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out) -{ - /* U1 = HMAC(input, salt + 0001) */ - HMAC (EVP_sha256 (), key, key_len, data, data_len, hmac_out, NULL); -} - -bool -mongoc_crypto_openssl_sha256 (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out) -{ - EVP_MD_CTX *digest_ctxp = EVP_MD_CTX_new (); - bool rval = false; - - if (1 != EVP_DigestInit_ex (digest_ctxp, EVP_sha256 (), NULL)) { - goto cleanup; - } - - if (1 != EVP_DigestUpdate (digest_ctxp, input, input_len)) { - goto cleanup; - } - - rval = (1 == EVP_DigestFinal_ex (digest_ctxp, hash_out, NULL)); - -cleanup: - EVP_MD_CTX_free (digest_ctxp); - - return rval; -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-private.h deleted file mode 100644 index d99db69188e70cd4eeeadf2623a55bb264d7efc5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto-private.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#include "mongoc/mongoc-config.h" -#include <bson/bson.h> - -#ifdef MONGOC_ENABLE_CRYPTO - -#ifndef MONGOC_CRYPTO_PRIVATE_H -#define MONGOC_CRYPTO_PRIVATE_H - - -BSON_BEGIN_DECLS - -typedef struct _mongoc_crypto_t mongoc_crypto_t; -typedef enum { - MONGOC_CRYPTO_ALGORITHM_SHA_1, - MONGOC_CRYPTO_ALGORITHM_SHA_256 -} mongoc_crypto_hash_algorithm_t; - -struct _mongoc_crypto_t { - void (*hmac) (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out); - bool (*hash) (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out); - mongoc_crypto_hash_algorithm_t algorithm; -}; - -void -mongoc_crypto_init (mongoc_crypto_t *crypto, - mongoc_crypto_hash_algorithm_t algo); - -void -mongoc_crypto_hmac (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out); - -bool -mongoc_crypto_hash (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *hash_out); - -BSON_END_DECLS -#endif /* MONGOC_CRYPTO_PRIVATE_H */ -#endif /* MONGOC_ENABLE_CRYPTO */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto.c deleted file mode 100644 index 30da1febca2d5c609cdecd33bed4350640799397..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-crypto.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_CRYPTO - -#include <bson/bson.h> -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-crypto-private.h" -#if defined(MONGOC_ENABLE_CRYPTO_LIBCRYPTO) -#include "mongoc/mongoc-crypto-openssl-private.h" -#elif defined(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO) -#include "mongoc/mongoc-crypto-common-crypto-private.h" -#elif defined(MONGOC_ENABLE_CRYPTO_CNG) -#include "mongoc/mongoc-crypto-cng-private.h" -#endif - -void -mongoc_crypto_init (mongoc_crypto_t *crypto, - mongoc_crypto_hash_algorithm_t algo) -{ - crypto->hmac = NULL; - crypto->hash = NULL; - if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_1) { -#ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO - crypto->hmac = mongoc_crypto_openssl_hmac_sha1; - crypto->hash = mongoc_crypto_openssl_sha1; -#elif defined(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO) - crypto->hmac = mongoc_crypto_common_crypto_hmac_sha1; - crypto->hash = mongoc_crypto_common_crypto_sha1; -#elif defined(MONGOC_ENABLE_CRYPTO_CNG) - crypto->hmac = mongoc_crypto_cng_hmac_sha1; - crypto->hash = mongoc_crypto_cng_sha1; -#endif - } else if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_256) { -#ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO - crypto->hmac = mongoc_crypto_openssl_hmac_sha256; - crypto->hash = mongoc_crypto_openssl_sha256; -#elif defined(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO) - crypto->hmac = mongoc_crypto_common_crypto_hmac_sha256; - crypto->hash = mongoc_crypto_common_crypto_sha256; -#elif defined(MONGOC_ENABLE_CRYPTO_CNG) - crypto->hmac = mongoc_crypto_cng_hmac_sha256; - crypto->hash = mongoc_crypto_cng_sha256; -#endif - } - BSON_ASSERT (crypto->hmac); - BSON_ASSERT (crypto->hash); - crypto->algorithm = algo; -} - -void -mongoc_crypto_hmac (mongoc_crypto_t *crypto, - const void *key, - int key_len, - const unsigned char *data, - int data_len, - unsigned char *hmac_out) -{ - crypto->hmac (crypto, key, key_len, data, data_len, hmac_out); -} - -bool -mongoc_crypto_hash (mongoc_crypto_t *crypto, - const unsigned char *input, - const size_t input_len, - unsigned char *output) -{ - return crypto->hash (crypto, input, input_len, output); -} -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-array.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-array.c deleted file mode 100644 index 9e3712f4c5c2cb117c25f1662d3f1e4c5229ae3d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-array.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" - -typedef struct _data_array_t { - bson_t cmd; - bson_t array; - bson_iter_t iter; - bson_t bson; /* current document */ - char *field_name; -} data_array_t; - - -static mongoc_cursor_state_t -_prime (mongoc_cursor_t *cursor) -{ - bson_iter_t iter; - data_array_t *data = (data_array_t *) cursor->impl.data; - - bson_destroy (&data->array); - /* this cursor is only used with the listDatabases command. it iterates - * over the array in the response's "databases" field. */ - if (_mongoc_cursor_run_command ( - cursor, &data->cmd, &cursor->opts, &data->array, false) && - bson_iter_init_find (&iter, &data->array, data->field_name) && - BSON_ITER_HOLDS_ARRAY (&iter) && - bson_iter_recurse (&iter, &data->iter)) { - return IN_BATCH; - } - return DONE; -} - - -static mongoc_cursor_state_t -_pop_from_batch (mongoc_cursor_t *cursor) -{ - uint32_t document_len; - const uint8_t *document; - data_array_t *data = (data_array_t *) cursor->impl.data; - if (bson_iter_next (&data->iter)) { - bson_iter_document (&data->iter, &document_len, &document); - BSON_ASSERT (bson_init_static (&data->bson, document, document_len)); - cursor->current = &data->bson; - return IN_BATCH; - } - return DONE; -} - - -static void -_clone (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src) -{ - data_array_t *data_dst = bson_malloc0 (sizeof (data_array_t)); - data_array_t *data_src = (data_array_t *) src->data; - bson_init (&data_dst->array); - bson_copy_to (&data_src->cmd, &data_dst->cmd); - data_dst->field_name = bson_strdup (data_src->field_name); - dst->data = data_dst; -} - - -static void -_destroy (mongoc_cursor_impl_t *impl) -{ - data_array_t *data = (data_array_t *) impl->data; - bson_destroy (&data->array); - bson_destroy (&data->cmd); - bson_free (data->field_name); - bson_free (data); -} - - -mongoc_cursor_t * -_mongoc_cursor_array_new (mongoc_client_t *client, - const char *db_and_coll, - const bson_t *cmd, - const bson_t *opts, - const char *field_name) -{ - mongoc_cursor_t *cursor = _mongoc_cursor_new_with_opts ( - client, db_and_coll, opts, NULL, NULL, NULL); - data_array_t *data = bson_malloc0 (sizeof (*data)); - bson_copy_to (cmd, &data->cmd); - bson_init (&data->array); - data->field_name = bson_strdup (field_name); - cursor->impl.prime = _prime; - cursor->impl.pop_from_batch = _pop_from_batch; - cursor->impl.destroy = _destroy; - cursor->impl.clone = _clone; - cursor->impl.data = (void *) data; - return cursor; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-change-stream.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-change-stream.c deleted file mode 100644 index 1eb2e5f895c5f86159c8f8d9b5f868e47a9150c5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-change-stream.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" - -typedef struct _data_change_stream_t { - mongoc_cursor_response_t response; - bson_t post_batch_resume_token; -} _data_change_stream_t; - - -static void -_update_post_batch_resume_token (mongoc_cursor_t *cursor) -{ - _data_change_stream_t *data = (_data_change_stream_t *) cursor->impl.data; - bson_iter_t iter, child; - - if (mongoc_cursor_error (cursor, NULL)) { - return; - } - - if (bson_iter_init (&iter, &data->response.reply) && - bson_iter_find_descendant ( - &iter, "cursor.postBatchResumeToken", &child) && - BSON_ITER_HOLDS_DOCUMENT (&child)) { - uint32_t len; - const uint8_t *buf; - bson_t post_batch_resume_token; - - bson_iter_document (&child, &len, &buf); - BSON_ASSERT (bson_init_static (&post_batch_resume_token, buf, len)); - bson_destroy (&data->post_batch_resume_token); - bson_copy_to (&post_batch_resume_token, &data->post_batch_resume_token); - } -} - - -static mongoc_cursor_state_t -_prime (mongoc_cursor_t *cursor) -{ - fprintf (stderr, "Prime unsupported on change stream cursor."); - BSON_ASSERT (false); - - return IN_BATCH; -} - - -static mongoc_cursor_state_t -_pop_from_batch (mongoc_cursor_t *cursor) -{ - _data_change_stream_t *data = (_data_change_stream_t *) cursor->impl.data; - _mongoc_cursor_response_read (cursor, &data->response, &cursor->current); - if (cursor->current) { - return IN_BATCH; - } else { - return cursor->cursor_id ? END_OF_BATCH : DONE; - } -} - - -mongoc_cursor_state_t -_get_next_batch (mongoc_cursor_t *cursor) -{ - _data_change_stream_t *data = (_data_change_stream_t *) cursor->impl.data; - bson_t getmore_cmd; - - _mongoc_cursor_prepare_getmore_command (cursor, &getmore_cmd); - _mongoc_cursor_response_refresh ( - cursor, &getmore_cmd, NULL /* opts */, &data->response); - bson_destroy (&getmore_cmd); - - _update_post_batch_resume_token (cursor); - - return IN_BATCH; -} - - -static void -_destroy (mongoc_cursor_impl_t *impl) -{ - _data_change_stream_t *data = (_data_change_stream_t *) impl->data; - bson_destroy (&data->response.reply); - bson_destroy (&data->post_batch_resume_token); - bson_free (data); -} - - -static void -_clone (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src) -{ - fprintf (stderr, "Clone unsupported on change stream cursor."); - BSON_ASSERT (false); -} - - -mongoc_cursor_t * -_mongoc_cursor_change_stream_new (mongoc_client_t *client, - bson_t *reply, - const bson_t *getmore_opts) -{ - mongoc_cursor_t *cursor; - _data_change_stream_t *data; - - BSON_ASSERT (client); - BSON_ASSERT (reply); - - data = bson_malloc0 (sizeof (*data)); - /* _mongoc_cursor_response_t.reply is already uninitialized and we can trust - * that reply comes from mongoc_client_read_command_with_opts() */ - BSON_ASSERT (bson_steal (&data->response.reply, reply)); - bson_init (&data->post_batch_resume_token); - - cursor = _mongoc_cursor_new_with_opts ( - client, NULL, getmore_opts, NULL, NULL, NULL); - cursor->impl.prime = _prime; - cursor->impl.pop_from_batch = _pop_from_batch; - cursor->impl.get_next_batch = _get_next_batch; - cursor->impl.destroy = _destroy; - cursor->impl.clone = _clone; - cursor->impl.data = (void *) data; - cursor->state = IN_BATCH; - - if (!_mongoc_cursor_start_reading_response (cursor, &data->response)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Couldn't parse cursor document"); - } - - _update_post_batch_resume_token (cursor); - - return cursor; -} - - -static bool -_bson_iter_has_next (bson_iter_t *iter) -{ - bson_iter_t iter_copy = {0}; - - memcpy (&iter_copy, iter, sizeof (bson_iter_t)); - - return bson_iter_next (&iter_copy); -} - - -bool -_mongoc_cursor_change_stream_end_of_batch (mongoc_cursor_t *cursor) -{ - _data_change_stream_t *data = (_data_change_stream_t *) cursor->impl.data; - - return !_bson_iter_has_next (&data->response.batch_iter); -} - - -const bson_t * -_mongoc_cursor_change_stream_get_post_batch_resume_token ( - mongoc_cursor_t *cursor) -{ - _data_change_stream_t *data = (_data_change_stream_t *) cursor->impl.data; - - return &data->post_batch_resume_token; -} - - -bool -_mongoc_cursor_change_stream_has_post_batch_resume_token ( - mongoc_cursor_t *cursor) -{ - _data_change_stream_t *data = (_data_change_stream_t *) cursor->impl.data; - - return !bson_empty (&data->post_batch_resume_token); -} - - -const bson_t * -_mongoc_cursor_change_stream_get_reply (mongoc_cursor_t *cursor) -{ - _data_change_stream_t *data = (_data_change_stream_t *) cursor->impl.data; - - return &data->response.reply; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c deleted file mode 100644 index b6ce0dbfcbf4056498047ac79687532d9394cbb6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" - -/* This cursor is returned by the deprecated functions mongoc_client_command, - * mongoc_database_command, and mongoc_collection_command. It runs the command - * on the first call to mongoc_cursor_next and returns the only result. */ -typedef struct _data_cmd_deprecated_t { - bson_t cmd; - bson_t reply; -} data_cmd_deprecated_t; - - -static mongoc_cursor_state_t -_prime (mongoc_cursor_t *cursor) -{ - data_cmd_deprecated_t *data = (data_cmd_deprecated_t *) cursor->impl.data; - bson_destroy (&data->reply); - if (_mongoc_cursor_run_command ( - cursor, &data->cmd, &cursor->opts, &data->reply, true)) { - return IN_BATCH; - } else { - return DONE; - } -} - - -static mongoc_cursor_state_t -_pop_from_batch (mongoc_cursor_t *cursor) -{ - data_cmd_deprecated_t *data = (data_cmd_deprecated_t *) cursor->impl.data; - cursor->current = &data->reply; - /* don't return DONE here. a cursor is marked DONE when it returns NULL. */ - return END_OF_BATCH; -} - -static mongoc_cursor_state_t -_get_next_batch (mongoc_cursor_t *cursor) -{ - /* there's no next batch to get, return DONE immediately. */ - return DONE; -} - - -static void -_clone (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src) -{ - data_cmd_deprecated_t *data_src = (data_cmd_deprecated_t *) src->data; - data_cmd_deprecated_t *data_dst = - bson_malloc0 (sizeof (data_cmd_deprecated_t)); - bson_init (&data_dst->reply); - bson_copy_to (&data_src->cmd, &data_dst->cmd); - dst->data = data_dst; -} - - -static void -_destroy (mongoc_cursor_impl_t *impl) -{ - data_cmd_deprecated_t *data = (data_cmd_deprecated_t *) impl->data; - bson_destroy (&data->reply); - bson_destroy (&data->cmd); - bson_free (data); -} - - -mongoc_cursor_t * -_mongoc_cursor_cmd_deprecated_new (mongoc_client_t *client, - const char *db_and_coll, - const bson_t *cmd, - const mongoc_read_prefs_t *read_prefs) -{ - mongoc_cursor_t *cursor = - _mongoc_cursor_new_with_opts (client, - db_and_coll, - NULL, - read_prefs /* user prefs */, - NULL /* default prefs */, - NULL); - data_cmd_deprecated_t *data = bson_malloc0 (sizeof (data_cmd_deprecated_t)); - _mongoc_cursor_check_and_copy_to (cursor, "command", cmd, &data->cmd); - bson_init (&data->reply); - cursor->impl.prime = _prime; - cursor->impl.pop_from_batch = _pop_from_batch; - cursor->impl.get_next_batch = _get_next_batch; - cursor->impl.data = data; - cursor->impl.clone = _clone; - cursor->impl.destroy = _destroy; - return cursor; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-cmd.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-cmd.c deleted file mode 100644 index 290727c3879ed50cdc8d7777213263e950c6f588..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-cmd.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" - -typedef enum { NONE, CMD_RESPONSE, OP_GETMORE_RESPONSE } reading_from_t; -typedef enum { UNKNOWN, GETMORE_CMD, OP_GETMORE } getmore_type_t; -typedef struct _data_cmd_t { - /* Two paths: - * - Mongo 3.2+, sent "getMore" cmd, we're reading reply's "nextBatch" array - * - Mongo 2.6 to 3, after "aggregate" or similar command we sent OP_GETMORE, - * we're reading the raw reply from a stream - */ - mongoc_cursor_response_t response; - mongoc_cursor_response_legacy_t response_legacy; - reading_from_t reading_from; - getmore_type_t getmore_type; /* cache after first getmore. */ - bson_t cmd; -} data_cmd_t; - - -static getmore_type_t -_getmore_type (mongoc_cursor_t *cursor) -{ - mongoc_server_stream_t *server_stream; - bool use_cmd; - data_cmd_t *data = (data_cmd_t *) cursor->impl.data; - if (data->getmore_type != UNKNOWN) { - return data->getmore_type; - } - server_stream = _mongoc_cursor_fetch_stream (cursor); - if (!server_stream) { - return UNKNOWN; - } - use_cmd = server_stream->sd->max_wire_version >= WIRE_VERSION_FIND_CMD && - !_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST); - data->getmore_type = use_cmd ? GETMORE_CMD : OP_GETMORE; - mongoc_server_stream_cleanup (server_stream); - return data->getmore_type; -} - - -static mongoc_cursor_state_t -_prime (mongoc_cursor_t *cursor) -{ - data_cmd_t *data = (data_cmd_t *) cursor->impl.data; - bson_t copied_opts; - bson_init (&copied_opts); - - cursor->operation_id = ++cursor->client->cluster.operation_id; - /* commands like agg have a cursor field, so copy opts without "batchSize" */ - bson_copy_to_excluding_noinit ( - &cursor->opts, &copied_opts, "batchSize", "tailable", NULL); - - /* server replies to aggregate/listIndexes/listCollections with: - * {cursor: {id: N, firstBatch: []}} */ - _mongoc_cursor_response_refresh ( - cursor, &data->cmd, &copied_opts, &data->response); - data->reading_from = CMD_RESPONSE; - bson_destroy (&copied_opts); - return IN_BATCH; -} - - -static mongoc_cursor_state_t -_pop_from_batch (mongoc_cursor_t *cursor) -{ - data_cmd_t *data = (data_cmd_t *) cursor->impl.data; - - switch (data->reading_from) { - case CMD_RESPONSE: - _mongoc_cursor_response_read (cursor, &data->response, &cursor->current); - break; - case OP_GETMORE_RESPONSE: - cursor->current = bson_reader_read (data->response_legacy.reader, NULL); - break; - case NONE: - default: - fprintf (stderr, "trying to pop from an uninitialized cursor reader.\n"); - BSON_ASSERT (false); - } - if (cursor->current) { - return IN_BATCH; - } else { - return cursor->cursor_id ? END_OF_BATCH : DONE; - } -} - - -static mongoc_cursor_state_t -_get_next_batch (mongoc_cursor_t *cursor) -{ - data_cmd_t *data = (data_cmd_t *) cursor->impl.data; - bson_t getmore_cmd; - getmore_type_t getmore_type = _getmore_type (cursor); - - switch (getmore_type) { - case GETMORE_CMD: - _mongoc_cursor_prepare_getmore_command (cursor, &getmore_cmd); - _mongoc_cursor_response_refresh ( - cursor, &getmore_cmd, NULL /* opts */, &data->response); - bson_destroy (&getmore_cmd); - data->reading_from = CMD_RESPONSE; - return IN_BATCH; - case OP_GETMORE: - _mongoc_cursor_op_getmore (cursor, &data->response_legacy); - data->reading_from = OP_GETMORE_RESPONSE; - return IN_BATCH; - case UNKNOWN: - default: - return DONE; - } -} - - -static void -_destroy (mongoc_cursor_impl_t *impl) -{ - data_cmd_t *data = (data_cmd_t *) impl->data; - bson_destroy (&data->response.reply); - bson_destroy (&data->cmd); - _mongoc_cursor_response_legacy_destroy (&data->response_legacy); - bson_free (data); -} - - -static void -_clone (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src) -{ - data_cmd_t *data_src = (data_cmd_t *) src->data; - data_cmd_t *data_dst = bson_malloc0 (sizeof (data_cmd_t)); - bson_init (&data_dst->response.reply); - _mongoc_cursor_response_legacy_init (&data_dst->response_legacy); - bson_copy_to (&data_src->cmd, &data_dst->cmd); - dst->data = data_dst; -} - - -mongoc_cursor_t * -_mongoc_cursor_cmd_new (mongoc_client_t *client, - const char *db_and_coll, - const bson_t *cmd, - const bson_t *opts, - const mongoc_read_prefs_t *user_prefs, - const mongoc_read_prefs_t *default_prefs, - const mongoc_read_concern_t *read_concern) -{ - mongoc_cursor_t *cursor; - data_cmd_t *data = bson_malloc0 (sizeof (*data)); - - cursor = _mongoc_cursor_new_with_opts ( - client, db_and_coll, opts, user_prefs, default_prefs, read_concern); - _mongoc_cursor_response_legacy_init (&data->response_legacy); - _mongoc_cursor_check_and_copy_to (cursor, "command", cmd, &data->cmd); - bson_init (&data->response.reply); - cursor->impl.prime = _prime; - cursor->impl.pop_from_batch = _pop_from_batch; - cursor->impl.get_next_batch = _get_next_batch; - cursor->impl.destroy = _destroy; - cursor->impl.clone = _clone; - cursor->impl.data = (void *) data; - return cursor; -} - - -mongoc_cursor_t * -_mongoc_cursor_cmd_new_from_reply (mongoc_client_t *client, - const bson_t *cmd, - const bson_t *opts, - bson_t *reply) -{ - mongoc_cursor_t *cursor = - _mongoc_cursor_cmd_new (client, NULL, cmd, opts, NULL, NULL, NULL); - data_cmd_t *data = (data_cmd_t *) cursor->impl.data; - - data->reading_from = CMD_RESPONSE; - cursor->state = IN_BATCH; - - bson_destroy (&data->response.reply); - if (!bson_steal (&data->response.reply, reply)) { - bson_destroy (&data->response.reply); - BSON_ASSERT (bson_steal (&data->response.reply, bson_copy (reply))); - } - - if (!_mongoc_cursor_start_reading_response (cursor, &data->response)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Couldn't parse cursor document"); - } - return cursor; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c deleted file mode 100644 index 12a947f6944b49360671712db27bd1cde9987a6f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" - -typedef struct _data_find_cmd_t { - mongoc_cursor_response_t response; - bson_t filter; -} data_find_cmd_t; - - -static mongoc_cursor_state_t -_prime (mongoc_cursor_t *cursor) -{ - data_find_cmd_t *data = (data_find_cmd_t *) cursor->impl.data; - bson_t find_cmd; - - bson_init (&find_cmd); - cursor->operation_id = ++cursor->client->cluster.operation_id; - /* construct { find: "<collection>", filter: {<filter>} } */ - _mongoc_cursor_prepare_find_command (cursor, &data->filter, &find_cmd); - _mongoc_cursor_response_refresh ( - cursor, &find_cmd, &cursor->opts, &data->response); - bson_destroy (&find_cmd); - return IN_BATCH; -} - - -static mongoc_cursor_state_t -_pop_from_batch (mongoc_cursor_t *cursor) -{ - data_find_cmd_t *data = (data_find_cmd_t *) cursor->impl.data; - _mongoc_cursor_response_read (cursor, &data->response, &cursor->current); - if (cursor->current) { - return IN_BATCH; - } else { - return cursor->cursor_id ? END_OF_BATCH : DONE; - } -} - - -static mongoc_cursor_state_t -_get_next_batch (mongoc_cursor_t *cursor) -{ - data_find_cmd_t *data = (data_find_cmd_t *) cursor->impl.data; - bson_t getmore_cmd; - - if (!cursor->cursor_id) { - return DONE; - } - _mongoc_cursor_prepare_getmore_command (cursor, &getmore_cmd); - _mongoc_cursor_response_refresh ( - cursor, &getmore_cmd, NULL /* opts */, &data->response); - bson_destroy (&getmore_cmd); - return IN_BATCH; -} - - -static void -_destroy (mongoc_cursor_impl_t *impl) -{ - data_find_cmd_t *data = (data_find_cmd_t *) impl->data; - bson_destroy (&data->filter); - bson_destroy (&data->response.reply); - bson_free (data); -} - - -static void -_clone (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src) -{ - data_find_cmd_t *data_src = (data_find_cmd_t *) src->data; - data_find_cmd_t *data_dst = bson_malloc0 (sizeof (data_find_cmd_t)); - bson_init (&data_dst->response.reply); - bson_copy_to (&data_src->filter, &data_dst->filter); - dst->data = data_dst; -} - - -/* transition a find cursor to use the find command. */ -void -_mongoc_cursor_impl_find_cmd_init (mongoc_cursor_t *cursor, bson_t *filter) -{ - data_find_cmd_t *data = bson_malloc0 (sizeof (*data)); - BSON_ASSERT (bson_steal (&data->filter, filter)); - bson_init (&data->response.reply); - cursor->impl.prime = _prime; - cursor->impl.pop_from_batch = _pop_from_batch; - cursor->impl.get_next_batch = _get_next_batch; - cursor->impl.destroy = _destroy; - cursor->impl.clone = _clone; - cursor->impl.data = (void *) data; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c deleted file mode 100644 index 6fe4155c0436b235572b55883e065e6bba9e702c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-cursor-private.h" - -typedef struct _data_find_opquery_t { - mongoc_cursor_response_legacy_t response_legacy; - bson_t filter; -} data_find_opquery_t; - - -static bool -_hit_limit (mongoc_cursor_t *cursor) -{ - int64_t limit, limit_abs; - limit = mongoc_cursor_get_limit (cursor); - /* don't use llabs, that is a C99 function. */ - limit_abs = limit > 0 ? limit : -limit; - /* mark as done if we've hit the limit. */ - if (limit && cursor->count >= limit_abs) { - return true; - } - return false; -} - - -static mongoc_cursor_state_t -_prime (mongoc_cursor_t *cursor) -{ - data_find_opquery_t *data = (data_find_opquery_t *) cursor->impl.data; - if (_hit_limit (cursor)) { - return DONE; - } - - _mongoc_cursor_op_query_find (cursor, &data->filter, &data->response_legacy); - return IN_BATCH; -} - - -static mongoc_cursor_state_t -_pop_from_batch (mongoc_cursor_t *cursor) -{ - data_find_opquery_t *data = (data_find_opquery_t *) cursor->impl.data; - - if (_hit_limit (cursor)) { - return DONE; - } - - cursor->current = bson_reader_read (data->response_legacy.reader, NULL); - if (cursor->current) { - return IN_BATCH; - } else { - return cursor->cursor_id ? END_OF_BATCH : DONE; - } -} - - -static mongoc_cursor_state_t -_get_next_batch (mongoc_cursor_t *cursor) -{ - data_find_opquery_t *data = (data_find_opquery_t *) cursor->impl.data; - _mongoc_cursor_op_getmore (cursor, &data->response_legacy); - return IN_BATCH; -} - - -static void -_destroy (mongoc_cursor_impl_t *impl) -{ - data_find_opquery_t *data = (data_find_opquery_t *) impl->data; - _mongoc_cursor_response_legacy_destroy (&data->response_legacy); - bson_destroy (&data->filter); - bson_free (data); -} - - -static void -_clone (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src) -{ - data_find_opquery_t *data_dst = bson_malloc0 (sizeof (data_find_opquery_t)); - data_find_opquery_t *data_src = (data_find_opquery_t *) src->data; - _mongoc_cursor_response_legacy_init (&data_dst->response_legacy); - bson_copy_to (&data_src->filter, &data_dst->filter); - dst->data = data_dst; -} - - -void -_mongoc_cursor_impl_find_opquery_init (mongoc_cursor_t *cursor, bson_t *filter) -{ - data_find_opquery_t *data = bson_malloc0 (sizeof (*data)); - _mongoc_cursor_response_legacy_init (&data->response_legacy); - BSON_ASSERT (bson_steal (&data->filter, filter)); - cursor->impl.prime = _prime; - cursor->impl.pop_from_batch = _pop_from_batch; - cursor->impl.get_next_batch = _get_next_batch; - cursor->impl.destroy = _destroy; - cursor->impl.clone = _clone; - cursor->impl.data = data; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find.c deleted file mode 100644 index 0e0d6ae1d3399d137e75f6ea0f5bd568e8039294..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-find.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" - -typedef struct _data_find_t { - bson_t filter; -} data_find_t; - - -extern void -_mongoc_cursor_impl_find_cmd_init (mongoc_cursor_t *cursor, bson_t *filter); -extern void -_mongoc_cursor_impl_find_opquery_init (mongoc_cursor_t *cursor, bson_t *filter); - - -static mongoc_cursor_state_t -_prime (mongoc_cursor_t *cursor) -{ - bool use_find_command; - mongoc_server_stream_t *server_stream; - data_find_t *data = (data_find_t *) cursor->impl.data; - - /* determine if this should be a command or op_query cursor. */ - server_stream = _mongoc_cursor_fetch_stream (cursor); - if (!server_stream) { - return DONE; - } - /* find_getmore_killcursors spec: - * "The find command does not support the exhaust flag from OP_QUERY." */ - use_find_command = - server_stream->sd->max_wire_version >= WIRE_VERSION_FIND_CMD && - !_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST); - mongoc_server_stream_cleanup (server_stream); - - /* set all mongoc_impl_t function pointers. */ - if (use_find_command) { - _mongoc_cursor_impl_find_cmd_init (cursor, &data->filter /* stolen */); - } else { - _mongoc_cursor_impl_find_opquery_init (cursor, - &data->filter /* stolen */); - } - /* destroy this impl data since impl functions have been replaced. */ - bson_free (data); - /* prime with the new implementation. */ - return cursor->impl.prime (cursor); -} - - -static void -_clone (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src) -{ - data_find_t *data_dst = bson_malloc0 (sizeof (data_find_t)); - data_find_t *data_src = (data_find_t *) src->data; - bson_copy_to (&data_src->filter, &data_dst->filter); - dst->data = data_dst; -} - - -static void -_destroy (mongoc_cursor_impl_t *impl) -{ - data_find_t *data = (data_find_t *) impl->data; - bson_destroy (&data->filter); - bson_free (data); -} - - -mongoc_cursor_t * -_mongoc_cursor_find_new (mongoc_client_t *client, - const char *db_and_coll, - const bson_t *filter, - const bson_t *opts, - const mongoc_read_prefs_t *user_prefs, - const mongoc_read_prefs_t *default_prefs, - const mongoc_read_concern_t *read_concern) -{ - mongoc_cursor_t *cursor; - data_find_t *data = bson_malloc0 (sizeof (data_find_t)); - cursor = _mongoc_cursor_new_with_opts ( - client, db_and_coll, opts, user_prefs, default_prefs, read_concern); - _mongoc_cursor_check_and_copy_to (cursor, "filter", filter, &data->filter); - cursor->impl.prime = _prime; - cursor->impl.clone = _clone; - cursor->impl.destroy = _destroy; - cursor->impl.data = data; - return cursor; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-legacy.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-legacy.c deleted file mode 100644 index 10b0d82353a7e7598ae7139073ebca9ec53361ae..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-legacy.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Copyright 2018-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. - */ - -/* cursor functions for pre-3.2 MongoDB, including: - * - OP_QUERY find (superseded by the find command) - * - OP_GETMORE (superseded by the getMore command) - * - receiving OP_REPLY documents in a stream (instead of batch) - */ - -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-rpc-private.h" - - -static bool -_mongoc_cursor_monitor_legacy_get_more (mongoc_cursor_t *cursor, - mongoc_server_stream_t *server_stream) -{ - bson_t doc; - char db[MONGOC_NAMESPACE_MAX]; - mongoc_client_t *client; - mongoc_apm_command_started_t event; - - ENTRY; - - client = cursor->client; - if (!client->apm_callbacks.started) { - /* successful */ - RETURN (true); - } - - _mongoc_cursor_prepare_getmore_command (cursor, &doc); - - bson_strncpy (db, cursor->ns, cursor->dblen + 1); - mongoc_apm_command_started_init (&event, - &doc, - db, - "getMore", - client->cluster.request_id, - cursor->operation_id, - &server_stream->sd->host, - server_stream->sd->id, - client->apm_context); - - client->apm_callbacks.started (&event); - mongoc_apm_command_started_cleanup (&event); - bson_destroy (&doc); - - RETURN (true); -} - - -static bool -_mongoc_cursor_monitor_legacy_query (mongoc_cursor_t *cursor, - const bson_t *filter, - mongoc_server_stream_t *server_stream) -{ - bson_t doc; - mongoc_client_t *client; - char db[MONGOC_NAMESPACE_MAX]; - bool r; - - ENTRY; - - client = cursor->client; - if (!client->apm_callbacks.started) { - /* successful */ - RETURN (true); - } - - bson_init (&doc); - bson_strncpy (db, cursor->ns, cursor->dblen + 1); - - /* simulate a MongoDB 3.2+ "find" command */ - _mongoc_cursor_prepare_find_command (cursor, filter, &doc); - - bson_copy_to_excluding_noinit ( - &cursor->opts, &doc, "serverId", "maxAwaitTimeMS", "sessionId", NULL); - - r = _mongoc_cursor_monitor_command (cursor, server_stream, &doc, "find"); - - bson_destroy (&doc); - - RETURN (r); -} - - -void -_mongoc_cursor_op_getmore (mongoc_cursor_t *cursor, - mongoc_cursor_response_legacy_t *response) -{ - int64_t started; - mongoc_rpc_t rpc; - uint32_t request_id; - mongoc_cluster_t *cluster; - mongoc_query_flags_t flags; - mongoc_server_stream_t *server_stream; - - ENTRY; - - started = bson_get_monotonic_time (); - cluster = &cursor->client->cluster; - - server_stream = _mongoc_cursor_fetch_stream (cursor); - if (!server_stream) { - return; - } - - if (!_mongoc_cursor_opts_to_flags (cursor, server_stream, &flags)) { - GOTO (fail); - } - - if (cursor->in_exhaust) { - request_id = (uint32_t) response->rpc.header.request_id; - } else { - request_id = ++cluster->request_id; - - rpc.get_more.cursor_id = cursor->cursor_id; - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_GET_MORE; - rpc.get_more.zero = 0; - rpc.get_more.collection = cursor->ns; - - if (flags & MONGOC_QUERY_TAILABLE_CURSOR) { - rpc.get_more.n_return = 0; - } else { - rpc.get_more.n_return = _mongoc_n_return (cursor); - } - - if (!_mongoc_cursor_monitor_legacy_get_more (cursor, server_stream)) { - GOTO (fail); - } - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - cluster, &rpc, server_stream, &cursor->error)) { - GOTO (fail); - } - } - - _mongoc_buffer_clear (&response->buffer, false); - - /* reset the last known cursor id. */ - cursor->cursor_id = 0; - - if (!_mongoc_client_recv (cursor->client, - &response->rpc, - &response->buffer, - server_stream, - &cursor->error)) { - GOTO (fail); - } - - if (response->rpc.header.opcode != MONGOC_OPCODE_REPLY) { - bson_set_error (&cursor->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid opcode. Expected %d, got %d.", - MONGOC_OPCODE_REPLY, - response->rpc.header.opcode); - GOTO (fail); - } - - if (response->rpc.header.response_to != request_id) { - bson_set_error (&cursor->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid response_to for getmore. Expected %d, got %d.", - request_id, - response->rpc.header.response_to); - GOTO (fail); - } - - if (!_mongoc_rpc_check_ok (&response->rpc, - cursor->client->error_api_version, - &cursor->error, - &cursor->error_doc)) { - GOTO (fail); - } - - if (response->reader) { - bson_reader_destroy (response->reader); - } - - cursor->cursor_id = response->rpc.reply.cursor_id; - - response->reader = - bson_reader_new_from_data (response->rpc.reply.documents, - (size_t) response->rpc.reply.documents_len); - - _mongoc_cursor_monitor_succeeded (cursor, - response, - bson_get_monotonic_time () - started, - false, /* not first batch */ - server_stream, - "getMore"); - - GOTO (done); -fail: - _mongoc_cursor_monitor_failed ( - cursor, bson_get_monotonic_time () - started, server_stream, "getMore"); -done: - mongoc_server_stream_cleanup (server_stream); -} - - -#define OPT_CHECK(_type) \ - do { \ - if (!BSON_ITER_HOLDS_##_type (&iter)) { \ - bson_set_error (&cursor->error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - "invalid option %s, should be type %s", \ - key, \ - #_type); \ - return NULL; \ - } \ - } while (false) - - -#define OPT_CHECK_INT() \ - do { \ - if (!BSON_ITER_HOLDS_INT (&iter)) { \ - bson_set_error (&cursor->error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - "invalid option %s, should be integer", \ - key); \ - return NULL; \ - } \ - } while (false) - - -#define OPT_ERR(_msg) \ - do { \ - bson_set_error (&cursor->error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - _msg); \ - return NULL; \ - } while (false) - - -#define OPT_BSON_ERR(_msg) \ - do { \ - bson_set_error ( \ - &cursor->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, _msg); \ - return NULL; \ - } while (false) - - -#define OPT_FLAG(_flag) \ - do { \ - OPT_CHECK (BOOL); \ - if (bson_iter_as_bool (&iter)) { \ - *flags |= _flag; \ - } \ - } while (false) - - -#define PUSH_DOLLAR_QUERY() \ - do { \ - if (!pushed_dollar_query) { \ - pushed_dollar_query = true; \ - bson_append_document (query, "$query", 6, filter); \ - } \ - } while (false) - - -#define OPT_SUBDOCUMENT(_opt_name, _legacy_name) \ - do { \ - OPT_CHECK (DOCUMENT); \ - bson_iter_document (&iter, &len, &data); \ - if (!bson_init_static (&subdocument, data, (size_t) len)) { \ - OPT_BSON_ERR ("Invalid '" #_opt_name "' subdocument in 'opts'."); \ - } \ - BSON_APPEND_DOCUMENT (query, "$" #_legacy_name, &subdocument); \ - } while (false) - -static bson_t * -_mongoc_cursor_parse_opts_for_op_query (mongoc_cursor_t *cursor, - mongoc_server_stream_t *stream, - bson_t *filter, - bson_t *query /* OUT */, - bson_t *fields /* OUT */, - mongoc_query_flags_t *flags /* OUT */, - int32_t *skip /* OUT */) -{ - bool pushed_dollar_query; - bson_iter_t iter; - uint32_t len; - const uint8_t *data; - bson_t subdocument; - const char *key; - char *dollar_modifier; - - *flags = MONGOC_QUERY_NONE; - *skip = 0; - - /* assume we'll send filter straight to server, like "{a: 1}". if we find an - * opt we must add, like "sort", we push the query like "$query: {a: 1}", - * then add a query modifier for the option, in this example "$orderby". - */ - pushed_dollar_query = false; - - if (!bson_iter_init (&iter, &cursor->opts)) { - OPT_BSON_ERR ("Invalid 'opts' parameter."); - } - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - - /* most common options first */ - if (!strcmp (key, MONGOC_CURSOR_PROJECTION)) { - OPT_CHECK (DOCUMENT); - bson_iter_document (&iter, &len, &data); - if (!bson_init_static (&subdocument, data, (size_t) len)) { - OPT_BSON_ERR ("Invalid 'projection' subdocument in 'opts'."); - } - bson_destroy (fields); - bson_copy_to (&subdocument, fields); - } else if (!strcmp (key, MONGOC_CURSOR_SORT)) { - PUSH_DOLLAR_QUERY (); - OPT_SUBDOCUMENT (sort, orderby); - } else if (!strcmp (key, MONGOC_CURSOR_SKIP)) { - OPT_CHECK_INT (); - *skip = (int32_t) bson_iter_as_int64 (&iter); - } - /* the rest of the options, alphabetically */ - else if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) { - OPT_FLAG (MONGOC_QUERY_PARTIAL); - } else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) { - OPT_FLAG (MONGOC_QUERY_AWAIT_DATA); - } else if (!strcmp (key, MONGOC_CURSOR_COMMENT)) { - OPT_CHECK (UTF8); - PUSH_DOLLAR_QUERY (); - BSON_APPEND_UTF8 (query, "$comment", bson_iter_utf8 (&iter, NULL)); - } else if (!strcmp (key, MONGOC_CURSOR_HINT)) { - if (BSON_ITER_HOLDS_UTF8 (&iter)) { - PUSH_DOLLAR_QUERY (); - BSON_APPEND_UTF8 (query, "$hint", bson_iter_utf8 (&iter, NULL)); - } else if (BSON_ITER_HOLDS_DOCUMENT (&iter)) { - PUSH_DOLLAR_QUERY (); - OPT_SUBDOCUMENT (hint, hint); - } else { - OPT_ERR ("Wrong type for 'hint' field in 'opts'."); - } - } else if (!strcmp (key, MONGOC_CURSOR_MAX)) { - PUSH_DOLLAR_QUERY (); - OPT_SUBDOCUMENT (max, max); - } else if (!strcmp (key, MONGOC_CURSOR_MAX_SCAN)) { - OPT_CHECK_INT (); - PUSH_DOLLAR_QUERY (); - BSON_APPEND_INT64 (query, "$maxScan", bson_iter_as_int64 (&iter)); - } else if (!strcmp (key, MONGOC_CURSOR_MAX_TIME_MS)) { - OPT_CHECK_INT (); - PUSH_DOLLAR_QUERY (); - BSON_APPEND_INT64 (query, "$maxTimeMS", bson_iter_as_int64 (&iter)); - } else if (!strcmp (key, MONGOC_CURSOR_MIN)) { - PUSH_DOLLAR_QUERY (); - OPT_SUBDOCUMENT (min, min); - } else if (!strcmp (key, MONGOC_CURSOR_READ_CONCERN)) { - OPT_ERR ("Set readConcern on client, database, or collection," - " not in a query."); - } else if (!strcmp (key, MONGOC_CURSOR_RETURN_KEY)) { - OPT_CHECK (BOOL); - PUSH_DOLLAR_QUERY (); - BSON_APPEND_BOOL (query, "$returnKey", bson_iter_as_bool (&iter)); - } else if (!strcmp (key, MONGOC_CURSOR_SHOW_RECORD_ID)) { - OPT_CHECK (BOOL); - PUSH_DOLLAR_QUERY (); - BSON_APPEND_BOOL (query, "$showDiskLoc", bson_iter_as_bool (&iter)); - } else if (!strcmp (key, MONGOC_CURSOR_SNAPSHOT)) { - OPT_CHECK (BOOL); - PUSH_DOLLAR_QUERY (); - BSON_APPEND_BOOL (query, "$snapshot", bson_iter_as_bool (&iter)); - } else if (!strcmp (key, MONGOC_CURSOR_COLLATION)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - return NULL; - } - /* singleBatch limit and batchSize are handled in _mongoc_n_return, - * exhaust noCursorTimeout oplogReplay tailable in _mongoc_cursor_flags - * maxAwaitTimeMS is handled in _mongoc_cursor_prepare_getmore_command - * sessionId is used to retrieve the mongoc_client_session_t - */ - else if (strcmp (key, MONGOC_CURSOR_SINGLE_BATCH) && - strcmp (key, MONGOC_CURSOR_LIMIT) && - strcmp (key, MONGOC_CURSOR_BATCH_SIZE) && - strcmp (key, MONGOC_CURSOR_EXHAUST) && - strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT) && - strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY) && - strcmp (key, MONGOC_CURSOR_TAILABLE) && - strcmp (key, MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) { - /* pass unrecognized options to server, prefixed with $ */ - PUSH_DOLLAR_QUERY (); - dollar_modifier = bson_strdup_printf ("$%s", key); - if (!bson_append_iter (query, dollar_modifier, -1, &iter)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Error adding \"%s\" to query", - dollar_modifier); - bson_free (dollar_modifier); - return NULL; - } - bson_free (dollar_modifier); - } - } - - if (!_mongoc_cursor_opts_to_flags (cursor, stream, flags)) { - /* cursor->error is set */ - return NULL; - } - - return pushed_dollar_query ? query : filter; -} - -#undef OPT_CHECK -#undef OPT_ERR -#undef OPT_BSON_ERR -#undef OPT_FLAG -#undef OPT_SUBDOCUMENT - - -bool -_mongoc_cursor_op_query_find (mongoc_cursor_t *cursor, - bson_t *filter, - mongoc_cursor_response_legacy_t *response) -{ - int64_t started; - uint32_t request_id; - mongoc_rpc_t rpc; - const bson_t *query_ptr; - bson_t query = BSON_INITIALIZER; - bson_t fields = BSON_INITIALIZER; - mongoc_query_flags_t flags; - mongoc_assemble_query_result_t result = ASSEMBLE_QUERY_RESULT_INIT; - bool succeeded = false; - mongoc_server_stream_t *server_stream; - - ENTRY; - - server_stream = _mongoc_cursor_fetch_stream (cursor); - if (!server_stream) { - return false; - } - - started = bson_get_monotonic_time (); - - /* When the user explicitly provides a readConcern -- but the server - * doesn't support readConcern, we must error: - * https://github.com/mongodb/specifications/blob/master/source/read-write-concern/read-write-concern.rst#errors-1 - */ - if (cursor->read_concern->level != NULL && - server_stream->sd->max_wire_version < WIRE_VERSION_READ_CONCERN) { - bson_set_error (&cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support readConcern"); - GOTO (done); - } - - cursor->operation_id = ++cursor->client->cluster.operation_id; - - request_id = ++cursor->client->cluster.request_id; - - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_QUERY; - rpc.query.flags = MONGOC_QUERY_NONE; - rpc.query.collection = cursor->ns; - rpc.query.skip = 0; - rpc.query.n_return = 0; - rpc.query.fields = NULL; - - query_ptr = _mongoc_cursor_parse_opts_for_op_query ( - cursor, server_stream, filter, &query, &fields, &flags, &rpc.query.skip); - - if (!query_ptr) { - /* invalid opts. cursor->error is set */ - GOTO (done); - } - - assemble_query ( - cursor->read_prefs, server_stream, query_ptr, flags, &result); - - rpc.query.query = bson_get_data (result.assembled_query); - rpc.query.flags = result.flags; - rpc.query.n_return = _mongoc_n_return (cursor); - if (!bson_empty (&fields)) { - rpc.query.fields = bson_get_data (&fields); - } - - /* cursor from mongoc_collection_find[_with_opts] is about to send its - * initial OP_QUERY to pre-3.2 MongoDB */ - if (!_mongoc_cursor_monitor_legacy_query (cursor, filter, server_stream)) { - GOTO (done); - } - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - &cursor->client->cluster, &rpc, server_stream, &cursor->error)) { - GOTO (done); - } - - _mongoc_buffer_clear (&response->buffer, false); - - if (!_mongoc_client_recv (cursor->client, - &response->rpc, - &response->buffer, - server_stream, - &cursor->error)) { - GOTO (done); - } - - if (response->rpc.header.opcode != MONGOC_OPCODE_REPLY) { - bson_set_error (&cursor->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid opcode. Expected %d, got %d.", - MONGOC_OPCODE_REPLY, - response->rpc.header.opcode); - GOTO (done); - } - - if (response->rpc.header.response_to != request_id) { - bson_set_error (&cursor->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid response_to for query. Expected %d, got %d.", - request_id, - response->rpc.header.response_to); - GOTO (done); - } - - if (!_mongoc_rpc_check_ok (&response->rpc, - cursor->client->error_api_version, - &cursor->error, - &cursor->error_doc)) { - GOTO (done); - } - - if (response->reader) { - bson_reader_destroy (response->reader); - } - - cursor->cursor_id = response->rpc.reply.cursor_id; - - response->reader = - bson_reader_new_from_data (response->rpc.reply.documents, - (size_t) response->rpc.reply.documents_len); - - if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) { - cursor->in_exhaust = true; - cursor->client->in_exhaust = true; - } - - _mongoc_cursor_monitor_succeeded (cursor, - response, - bson_get_monotonic_time () - started, - true, /* first_batch */ - server_stream, - "find"); - succeeded = true; - -done: - if (!succeeded) { - _mongoc_cursor_monitor_failed ( - cursor, bson_get_monotonic_time () - started, server_stream, "find"); - } - - mongoc_server_stream_cleanup (server_stream); - assemble_query_result_cleanup (&result); - bson_destroy (&query); - bson_destroy (&fields); - return succeeded; -} - - -void -_mongoc_cursor_response_legacy_init (mongoc_cursor_response_legacy_t *response) -{ - _mongoc_buffer_init (&response->buffer, NULL, 0, NULL, NULL); -} - - -void -_mongoc_cursor_response_legacy_destroy ( - mongoc_cursor_response_legacy_t *response) -{ - if (response->reader) { - bson_reader_destroy (response->reader); - response->reader = NULL; - } - _mongoc_buffer_destroy (&response->buffer); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-private.h deleted file mode 100644 index 6ccb13f2ee2faa0db0d875afdad370d1d1a53887..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor-private.h +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CURSOR_PRIVATE_H -#define MONGOC_CURSOR_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-buffer-private.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-server-stream-private.h" - - -BSON_BEGIN_DECLS - -#define MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS "allowPartialResults" -#define MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS_LEN 19 -#define MONGOC_CURSOR_AWAIT_DATA "awaitData" -#define MONGOC_CURSOR_AWAIT_DATA_LEN 9 -#define MONGOC_CURSOR_BATCH_SIZE "batchSize" -#define MONGOC_CURSOR_BATCH_SIZE_LEN 9 -#define MONGOC_CURSOR_COLLATION "collation" -#define MONGOC_CURSOR_COLLATION_LEN 9 -#define MONGOC_CURSOR_COMMENT "comment" -#define MONGOC_CURSOR_COMMENT_LEN 7 -#define MONGOC_CURSOR_EXHAUST "exhaust" -#define MONGOC_CURSOR_EXHAUST_LEN 7 -#define MONGOC_CURSOR_FILTER "filter" -#define MONGOC_CURSOR_FILTER_LEN 6 -#define MONGOC_CURSOR_FIND "find" -#define MONGOC_CURSOR_FIND_LEN 4 -#define MONGOC_CURSOR_HINT "hint" -#define MONGOC_CURSOR_HINT_LEN 4 -#define MONGOC_CURSOR_LIMIT "limit" -#define MONGOC_CURSOR_LIMIT_LEN 5 -#define MONGOC_CURSOR_MAX "max" -#define MONGOC_CURSOR_MAX_LEN 3 -#define MONGOC_CURSOR_MAX_AWAIT_TIME_MS "maxAwaitTimeMS" -#define MONGOC_CURSOR_MAX_AWAIT_TIME_MS_LEN 14 -#define MONGOC_CURSOR_MAX_SCAN "maxScan" -#define MONGOC_CURSOR_MAX_SCAN_LEN 7 -#define MONGOC_CURSOR_MAX_TIME_MS "maxTimeMS" -#define MONGOC_CURSOR_MAX_TIME_MS_LEN 9 -#define MONGOC_CURSOR_MIN "min" -#define MONGOC_CURSOR_MIN_LEN 3 -#define MONGOC_CURSOR_NO_CURSOR_TIMEOUT "noCursorTimeout" -#define MONGOC_CURSOR_NO_CURSOR_TIMEOUT_LEN 15 -#define MONGOC_CURSOR_OPLOG_REPLAY "oplogReplay" -#define MONGOC_CURSOR_OPLOG_REPLAY_LEN 11 -#define MONGOC_CURSOR_ORDERBY "orderby" -#define MONGOC_CURSOR_ORDERBY_LEN 7 -#define MONGOC_CURSOR_PROJECTION "projection" -#define MONGOC_CURSOR_PROJECTION_LEN 10 -#define MONGOC_CURSOR_QUERY "query" -#define MONGOC_CURSOR_QUERY_LEN 5 -#define MONGOC_CURSOR_READ_CONCERN "readConcern" -#define MONGOC_CURSOR_READ_CONCERN_LEN 11 -#define MONGOC_CURSOR_RETURN_KEY "returnKey" -#define MONGOC_CURSOR_RETURN_KEY_LEN 9 -#define MONGOC_CURSOR_SHOW_DISK_LOC "showDiskLoc" -#define MONGOC_CURSOR_SHOW_DISK_LOC_LEN 11 -#define MONGOC_CURSOR_SHOW_RECORD_ID "showRecordId" -#define MONGOC_CURSOR_SHOW_RECORD_ID_LEN 12 -#define MONGOC_CURSOR_SINGLE_BATCH "singleBatch" -#define MONGOC_CURSOR_SINGLE_BATCH_LEN 11 -#define MONGOC_CURSOR_SKIP "skip" -#define MONGOC_CURSOR_SKIP_LEN 4 -#define MONGOC_CURSOR_SNAPSHOT "snapshot" -#define MONGOC_CURSOR_SNAPSHOT_LEN 8 -#define MONGOC_CURSOR_SORT "sort" -#define MONGOC_CURSOR_SORT_LEN 4 -#define MONGOC_CURSOR_TAILABLE "tailable" -#define MONGOC_CURSOR_TAILABLE_LEN 8 - -typedef struct _mongoc_cursor_impl_t mongoc_cursor_impl_t; -typedef enum { UNPRIMED, IN_BATCH, END_OF_BATCH, DONE } mongoc_cursor_state_t; -typedef mongoc_cursor_state_t (*_mongoc_cursor_impl_transition_t) ( - mongoc_cursor_t *cursor); -struct _mongoc_cursor_impl_t { - void (*clone) (mongoc_cursor_impl_t *dst, const mongoc_cursor_impl_t *src); - void (*destroy) (mongoc_cursor_impl_t *ctx); - _mongoc_cursor_impl_transition_t prime; - _mongoc_cursor_impl_transition_t pop_from_batch; - _mongoc_cursor_impl_transition_t get_next_batch; - void *data; -}; - -/* pre-3.2 and exhaust cursor responses -- read documents from stream. */ -typedef struct _mongoc_cursor_response_legacy { - mongoc_rpc_t rpc; - mongoc_buffer_t buffer; - bson_reader_t *reader; -} mongoc_cursor_response_legacy_t; - -/* 3.2+ responses -- read batch docs like {cursor:{id: 123, firstBatch: []}} */ -typedef struct _mongoc_cursor_response_t { - bson_t reply; /* the entire command reply */ - bson_iter_t batch_iter; /* iterates over the batch array */ - bson_t current_doc; /* the current doc inside the batch array */ -} mongoc_cursor_response_t; - -struct _mongoc_cursor_t { - mongoc_client_t *client; - uint32_t client_generation; - - uint32_t server_id; - bool slave_ok; - - mongoc_cursor_state_t state; - bool in_exhaust; - - bson_t opts; - - mongoc_read_concern_t *read_concern; - mongoc_read_prefs_t *read_prefs; - mongoc_write_concern_t *write_concern; - - bool explicit_session; - mongoc_client_session_t *client_session; - - uint32_t count; - - char ns[140]; - uint32_t nslen; - uint32_t dblen; - - bson_error_t error; - bson_t error_doc; /* always initialized, and set with server errors. */ - - const bson_t *current; - - mongoc_cursor_impl_t impl; - - int64_t operation_id; - int64_t cursor_id; -}; - -int32_t -_mongoc_n_return (mongoc_cursor_t *cursor); -void -_mongoc_set_cursor_ns (mongoc_cursor_t *cursor, const char *ns, uint32_t nslen); -bool -_mongoc_cursor_get_opt_bool (const mongoc_cursor_t *cursor, const char *option); -void -_mongoc_cursor_flags_to_opts (mongoc_query_flags_t qflags, - bson_t *opts, - bool *slave_ok); -bool -_mongoc_cursor_translate_dollar_query_opts (const bson_t *query, - bson_t *opts, - bson_t *unwrapped, - bson_error_t *error); -mongoc_server_stream_t * -_mongoc_cursor_fetch_stream (mongoc_cursor_t *cursor); -void -_mongoc_cursor_collection (const mongoc_cursor_t *cursor, - const char **collection, - int *collection_len); -bool -_mongoc_cursor_run_command (mongoc_cursor_t *cursor, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bool retry_prohibited); -bool -_mongoc_cursor_more (mongoc_cursor_t *cursor); - -bool -_mongoc_cursor_set_opt_int64 (mongoc_cursor_t *cursor, - const char *option, - int64_t value); -void -_mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor, - int64_t duration, - mongoc_server_stream_t *stream, - const char *cmd_name); -bool -_mongoc_cursor_monitor_command (mongoc_cursor_t *cursor, - mongoc_server_stream_t *server_stream, - const bson_t *cmd, - const char *cmd_name); -void -_mongoc_cursor_prepare_find_command (mongoc_cursor_t *cursor, - const bson_t *filter, - bson_t *command); -const bson_t * -_mongoc_cursor_initial_query (mongoc_cursor_t *cursor); -const bson_t * -_mongoc_cursor_get_more (mongoc_cursor_t *cursor); -bool -_mongoc_cursor_opts_to_flags (mongoc_cursor_t *cursor, - mongoc_server_stream_t *stream, - mongoc_query_flags_t *flags /* OUT */); -void -_mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor, - mongoc_cursor_response_legacy_t *response, - int64_t duration, - bool first_batch, - mongoc_server_stream_t *stream, - const char *cmd_name); -/* start iterating a reply like - * {cursor: {id: 1234, ns: "db.collection", firstBatch: [...]}} or - * {cursor: {id: 1234, ns: "db.collection", nextBatch: [...]}} */ -void -_mongoc_cursor_response_refresh (mongoc_cursor_t *cursor, - const bson_t *command, - const bson_t *opts, - mongoc_cursor_response_t *response); -bool -_mongoc_cursor_start_reading_response (mongoc_cursor_t *cursor, - mongoc_cursor_response_t *response); -void -_mongoc_cursor_response_read (mongoc_cursor_t *cursor, - mongoc_cursor_response_t *response, - const bson_t **bson); -void -_mongoc_cursor_prepare_getmore_command (mongoc_cursor_t *cursor, - bson_t *command); -void -_mongoc_cursor_set_empty (mongoc_cursor_t *cursor); -bool -_mongoc_cursor_check_and_copy_to (mongoc_cursor_t *cursor, - const char *err_prefix, - const bson_t *src, - bson_t *dst); -void -_mongoc_cursor_prime (mongoc_cursor_t *cursor); -/* legacy functions defined in mongoc-cursor-legacy.c */ -bool -_mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson); -bool -_mongoc_cursor_op_query_find (mongoc_cursor_t *cursor, - bson_t *filter, - mongoc_cursor_response_legacy_t *response); -void -_mongoc_cursor_op_getmore (mongoc_cursor_t *cursor, - mongoc_cursor_response_legacy_t *response); -mongoc_cursor_t * -_mongoc_cursor_new_with_opts (mongoc_client_t *client, - const char *db_and_collection, - const bson_t *opts, - const mongoc_read_prefs_t *user_prefs, - const mongoc_read_prefs_t *default_prefs, - const mongoc_read_concern_t *read_concern); -void -_mongoc_cursor_response_legacy_init (mongoc_cursor_response_legacy_t *response); -void -_mongoc_cursor_response_legacy_destroy ( - mongoc_cursor_response_legacy_t *response); -/* cursor constructors. */ -mongoc_cursor_t * -_mongoc_cursor_find_new (mongoc_client_t *client, - const char *db_and_coll, - const bson_t *filter, - const bson_t *opts, - const mongoc_read_prefs_t *user_prefs, - const mongoc_read_prefs_t *default_prefs, - const mongoc_read_concern_t *read_concern); - -mongoc_cursor_t * -_mongoc_cursor_cmd_new (mongoc_client_t *client, - const char *db_and_coll, - const bson_t *cmd, - const bson_t *opts, - const mongoc_read_prefs_t *user_prefs, - const mongoc_read_prefs_t *default_prefs, - const mongoc_read_concern_t *read_concern); - -mongoc_cursor_t * -_mongoc_cursor_cmd_new_from_reply (mongoc_client_t *client, - const bson_t *cmd, - const bson_t *opts, - bson_t *reply); - -mongoc_cursor_t * -_mongoc_cursor_cmd_deprecated_new (mongoc_client_t *client, - const char *db_and_coll, - const bson_t *cmd, - const mongoc_read_prefs_t *read_prefs); - -mongoc_cursor_t * -_mongoc_cursor_array_new (mongoc_client_t *client, - const char *db_and_coll, - const bson_t *cmd, - const bson_t *opts, - const char *field_name); - -mongoc_cursor_t * -_mongoc_cursor_change_stream_new (mongoc_client_t *client, - bson_t *reply, - const bson_t *opts); - -bool -_mongoc_cursor_change_stream_end_of_batch (mongoc_cursor_t *cursor); - -const bson_t * -_mongoc_cursor_change_stream_get_post_batch_resume_token ( - mongoc_cursor_t *cursor); - -bool -_mongoc_cursor_change_stream_has_post_batch_resume_token ( - mongoc_cursor_t *cursor); - -const bson_t * -_mongoc_cursor_change_stream_get_reply (mongoc_cursor_t *cursor); - -BSON_END_DECLS - - -#endif /* MONGOC_CURSOR_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor.c deleted file mode 100644 index 2f7393c2b6dd8ef88919cdf8d945f8d8fed6396d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor.c +++ /dev/null @@ -1,1743 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-client-session-private.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-error-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-aggregate-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "cursor" - - -#define CURSOR_FAILED(cursor_) ((cursor_)->error.domain != 0) - -static bool -_translate_query_opt (const char *query_field, - const char **cmd_field, - int *len); - - -bool -_mongoc_cursor_set_opt_int64 (mongoc_cursor_t *cursor, - const char *option, - int64_t value) -{ - bson_iter_t iter; - - if (bson_iter_init_find (&iter, &cursor->opts, option)) { - if (!BSON_ITER_HOLDS_INT64 (&iter)) { - return false; - } - - bson_iter_overwrite_int64 (&iter, value); - return true; - } - - return BSON_APPEND_INT64 (&cursor->opts, option, value); -} - - -static int64_t -_mongoc_cursor_get_opt_int64 (const mongoc_cursor_t *cursor, - const char *option, - int64_t default_value) -{ - bson_iter_t iter; - - if (bson_iter_init_find (&iter, &cursor->opts, option)) { - return bson_iter_as_int64 (&iter); - } - - return default_value; -} - - -static bool -_mongoc_cursor_set_opt_bool (mongoc_cursor_t *cursor, - const char *option, - bool value) -{ - bson_iter_t iter; - - if (bson_iter_init_find (&iter, &cursor->opts, option)) { - if (!BSON_ITER_HOLDS_BOOL (&iter)) { - return false; - } - - bson_iter_overwrite_bool (&iter, value); - return true; - } - - return BSON_APPEND_BOOL (&cursor->opts, option, value); -} - - -bool -_mongoc_cursor_get_opt_bool (const mongoc_cursor_t *cursor, const char *option) -{ - bson_iter_t iter; - - if (bson_iter_init_find (&iter, &cursor->opts, option)) { - return bson_iter_as_bool (&iter); - } - - return false; -} - - -int32_t -_mongoc_n_return (mongoc_cursor_t *cursor) -{ - int64_t limit; - int64_t batch_size; - int64_t n_return; - - /* calculate numberToReturn according to: - * https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#combining-limit-and-batch-size-for-the-wire-protocol - */ - limit = mongoc_cursor_get_limit (cursor); - batch_size = mongoc_cursor_get_batch_size (cursor); - - if (limit < 0) { - n_return = limit; - } else if (limit == 0) { - n_return = batch_size; - } else if (batch_size == 0) { - n_return = limit; - } else if (limit < batch_size) { - n_return = limit; - } else { - n_return = batch_size; - } - - /* if a specified limit exists, account for documents already returned. */ - if (limit > 0 && cursor->count) { - int64_t remaining = limit - cursor->count; - /* remaining can be 0 if we have retrieved "limit" documents, but still - * have a cursor id: SERVER-21086. use nonzero batchSize to fetch final - * empty batch and trigger server to close cursor. */ - if (remaining <= 0) { - return 1; - } - - n_return = BSON_MIN (n_return, remaining); - } - - /* check boundary conditions */ - if (n_return < INT32_MIN) { - return INT32_MIN; - } else if (n_return > INT32_MAX) { - return INT32_MAX; - } else { - return (int32_t) n_return; - } -} - - -void -_mongoc_set_cursor_ns (mongoc_cursor_t *cursor, const char *ns, uint32_t nslen) -{ - const char *dot; - - bson_strncpy (cursor->ns, ns, sizeof cursor->ns); - cursor->nslen = BSON_MIN (nslen, sizeof cursor->ns); - dot = strstr (cursor->ns, "."); - - if (dot) { - cursor->dblen = (uint32_t) (dot - cursor->ns); - } else { - /* a database name with no collection name */ - cursor->dblen = cursor->nslen; - } -} - - -/* return first key beginning with $, or NULL. precondition: bson is valid. */ -static const char * -_first_dollar_field (const bson_t *bson) -{ - bson_iter_t iter; - const char *key; - - BSON_ASSERT (bson_iter_init (&iter, bson)); - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - - if (key[0] == '$') { - return key; - } - } - - return NULL; -} - - -/* if src is non-NULL, it is validated and copied to dst. returns false and - * sets the cursor error if validation fails. */ -bool -_mongoc_cursor_check_and_copy_to (mongoc_cursor_t *cursor, - const char *err_prefix, - const bson_t *src, - bson_t *dst) -{ - bson_error_t validate_err; - bson_init (dst); - if (src) { - if (!bson_validate_with_error ( - src, BSON_VALIDATE_EMPTY_KEYS, &validate_err)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Invalid %s: %s", - err_prefix, - validate_err.message); - return false; - } - - bson_destroy (dst); - bson_copy_to (src, dst); - } - return true; -} - - -mongoc_cursor_t * -_mongoc_cursor_new_with_opts (mongoc_client_t *client, - const char *db_and_collection, - const bson_t *opts, - const mongoc_read_prefs_t *user_prefs, - const mongoc_read_prefs_t *default_prefs, - const mongoc_read_concern_t *read_concern) -{ - mongoc_cursor_t *cursor; - mongoc_topology_description_type_t td_type; - uint32_t server_id; - mongoc_read_concern_t *read_concern_local = NULL; - bson_error_t validate_err; - const char *dollar_field; - bson_iter_t iter; - - ENTRY; - - BSON_ASSERT (client); - - cursor = (mongoc_cursor_t *) bson_malloc0 (sizeof *cursor); - cursor->client = client; - cursor->state = UNPRIMED; - cursor->client_generation = client->generation; - - bson_init (&cursor->opts); - bson_init (&cursor->error_doc); - - if (opts) { - if (!bson_validate_with_error ( - opts, BSON_VALIDATE_EMPTY_KEYS, &validate_err)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Invalid opts: %s", - validate_err.message); - GOTO (finish); - } - - dollar_field = _first_dollar_field (opts); - if (dollar_field) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot use $-modifiers in opts: \"%s\"", - dollar_field); - GOTO (finish); - } - - if (bson_iter_init_find (&iter, opts, "sessionId")) { - if (!_mongoc_client_session_from_iter ( - client, &iter, &cursor->client_session, &cursor->error)) { - GOTO (finish); - } - - cursor->explicit_session = true; - } - - if (bson_iter_init_find (&iter, opts, "readConcern")) { - read_concern_local = - _mongoc_read_concern_new_from_iter (&iter, &cursor->error); - - if (!read_concern_local) { - /* invalid read concern */ - GOTO (finish); - } - - read_concern = read_concern_local; - } - - /* true if there's a valid serverId or no serverId, false on err */ - if (!_mongoc_get_server_id_from_opts (opts, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - &server_id, - &cursor->error)) { - GOTO (finish); - } - - if (server_id) { - (void) mongoc_cursor_set_hint (cursor, server_id); - } - - bson_copy_to_excluding_noinit (opts, - &cursor->opts, - "serverId", - "sessionId", - "bypassDocumentValidation", - NULL); - - - /* only include bypassDocumentValidation if it's true */ - if (bson_iter_init_find (&iter, opts, "bypassDocumentValidation") && - bson_iter_as_bool (&iter)) { - BSON_APPEND_BOOL (&cursor->opts, "bypassDocumentValidation", true); - } - } - - if (_mongoc_client_session_in_txn (cursor->client_session)) { - if (!IS_PREF_PRIMARY (user_prefs)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Read preference in a transaction must be primary"); - GOTO (finish); - } - - cursor->read_prefs = - mongoc_read_prefs_copy (cursor->client_session->txn.opts.read_prefs); - - if (bson_has_field (opts, "readConcern")) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot set read concern after starting transaction"); - GOTO (finish); - } - } else if (user_prefs) { - cursor->read_prefs = mongoc_read_prefs_copy (user_prefs); - } else if (default_prefs) { - cursor->read_prefs = mongoc_read_prefs_copy (default_prefs); - } else { - cursor->read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - } - - cursor->read_concern = read_concern ? mongoc_read_concern_copy (read_concern) - : mongoc_read_concern_new (); - - if (db_and_collection) { - _mongoc_set_cursor_ns ( - cursor, db_and_collection, (uint32_t) strlen (db_and_collection)); - } - - if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) { - if (_mongoc_cursor_get_opt_int64 (cursor, MONGOC_CURSOR_LIMIT, 0)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot specify both 'exhaust' and 'limit'."); - GOTO (finish); - } - - td_type = _mongoc_topology_get_type (client->topology); - - if (td_type == MONGOC_TOPOLOGY_SHARDED) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot use exhaust cursor with sharded cluster."); - GOTO (finish); - } - } - - (void) _mongoc_read_prefs_validate (cursor->read_prefs, &cursor->error); - -finish: - mongoc_read_concern_destroy (read_concern_local); - mongoc_counter_cursors_active_inc (); - - RETURN (cursor); -} - - -static bool -_translate_query_opt (const char *query_field, const char **cmd_field, int *len) -{ - if (query_field[0] != '$') { - *cmd_field = query_field; - *len = -1; - return true; - } - - /* strip the leading '$' */ - query_field++; - - if (!strcmp (MONGOC_CURSOR_ORDERBY, query_field)) { - *cmd_field = MONGOC_CURSOR_SORT; - *len = MONGOC_CURSOR_SORT_LEN; - } else if (!strcmp (MONGOC_CURSOR_SHOW_DISK_LOC, - query_field)) { /* <= MongoDb 3.0 */ - *cmd_field = MONGOC_CURSOR_SHOW_RECORD_ID; - *len = MONGOC_CURSOR_SHOW_RECORD_ID_LEN; - } else if (!strcmp (MONGOC_CURSOR_HINT, query_field)) { - *cmd_field = MONGOC_CURSOR_HINT; - *len = MONGOC_CURSOR_HINT_LEN; - } else if (!strcmp (MONGOC_CURSOR_COMMENT, query_field)) { - *cmd_field = MONGOC_CURSOR_COMMENT; - *len = MONGOC_CURSOR_COMMENT_LEN; - } else if (!strcmp (MONGOC_CURSOR_MAX_SCAN, query_field)) { - *cmd_field = MONGOC_CURSOR_MAX_SCAN; - *len = MONGOC_CURSOR_MAX_SCAN_LEN; - } else if (!strcmp (MONGOC_CURSOR_MAX_TIME_MS, query_field)) { - *cmd_field = MONGOC_CURSOR_MAX_TIME_MS; - *len = MONGOC_CURSOR_MAX_TIME_MS_LEN; - } else if (!strcmp (MONGOC_CURSOR_MAX, query_field)) { - *cmd_field = MONGOC_CURSOR_MAX; - *len = MONGOC_CURSOR_MAX_LEN; - } else if (!strcmp (MONGOC_CURSOR_MIN, query_field)) { - *cmd_field = MONGOC_CURSOR_MIN; - *len = MONGOC_CURSOR_MIN_LEN; - } else if (!strcmp (MONGOC_CURSOR_RETURN_KEY, query_field)) { - *cmd_field = MONGOC_CURSOR_RETURN_KEY; - *len = MONGOC_CURSOR_RETURN_KEY_LEN; - } else if (!strcmp (MONGOC_CURSOR_SNAPSHOT, query_field)) { - *cmd_field = MONGOC_CURSOR_SNAPSHOT; - *len = MONGOC_CURSOR_SNAPSHOT_LEN; - } else { - /* not a special command field, must be a query operator like $or */ - return false; - } - - return true; -} - - -/* set up a new opt bson from older ways of specifying options. - * slave_ok may be NULL. - * error may be NULL. - */ -void -_mongoc_cursor_flags_to_opts (mongoc_query_flags_t qflags, - bson_t *opts, /* IN/OUT */ - bool *slave_ok /* OUT */) -{ - ENTRY; - BSON_ASSERT (opts); - - if (slave_ok) { - *slave_ok = !!(qflags & MONGOC_QUERY_SLAVE_OK); - } - - if (qflags & MONGOC_QUERY_TAILABLE_CURSOR) { - bson_append_bool ( - opts, MONGOC_CURSOR_TAILABLE, MONGOC_CURSOR_TAILABLE_LEN, true); - } - - if (qflags & MONGOC_QUERY_OPLOG_REPLAY) { - bson_append_bool (opts, - MONGOC_CURSOR_OPLOG_REPLAY, - MONGOC_CURSOR_OPLOG_REPLAY_LEN, - true); - } - - if (qflags & MONGOC_QUERY_NO_CURSOR_TIMEOUT) { - bson_append_bool (opts, - MONGOC_CURSOR_NO_CURSOR_TIMEOUT, - MONGOC_CURSOR_NO_CURSOR_TIMEOUT_LEN, - true); - } - - if (qflags & MONGOC_QUERY_AWAIT_DATA) { - bson_append_bool ( - opts, MONGOC_CURSOR_AWAIT_DATA, MONGOC_CURSOR_AWAIT_DATA_LEN, true); - } - - if (qflags & MONGOC_QUERY_EXHAUST) { - bson_append_bool ( - opts, MONGOC_CURSOR_EXHAUST, MONGOC_CURSOR_EXHAUST_LEN, true); - } - - if (qflags & MONGOC_QUERY_PARTIAL) { - bson_append_bool (opts, - MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS, - MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS_LEN, - true); - } -} - -/* Checks if the passed query was wrapped in a $query, and if so, parses the - * query modifiers: - * https://docs.mongodb.com/manual/reference/operator/query-modifier/ - * and translates them to find command options: - * https://docs.mongodb.com/manual/reference/command/find/ - * opts must be initialized, and may already have options set. - * unwrapped must be uninitialized, and will be initialized at return. - * Returns true if query was unwrapped. */ -bool -_mongoc_cursor_translate_dollar_query_opts (const bson_t *query, - bson_t *opts, - bson_t *unwrapped, - bson_error_t *error) -{ - bool has_filter = false; - const char *key; - bson_iter_t iter; - const char *opt_key; - int len; - uint32_t data_len; - const uint8_t *data; - bson_error_t error_local = {0}; - - ENTRY; - BSON_ASSERT (query); - BSON_ASSERT (opts); - /* If the query is explicitly specified wrapped in $query, unwrap it and - * translate the options to new options. */ - if (bson_has_field (query, "$query")) { - /* like "{$query: {a: 1}, $orderby: {b: 1}, $otherModifier: true}" */ - if (!bson_iter_init (&iter, query)) { - bson_set_error (&error_local, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid BSON in query document"); - GOTO (done); - } - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - if (key[0] != '$') { - bson_set_error (&error_local, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot mix $query with non-dollar field '%s'", - key); - GOTO (done); - } - if (!strcmp (key, "$query")) { - /* set "filter" to the incoming document's "$query" */ - bson_iter_document (&iter, &data_len, &data); - if (!bson_init_static (unwrapped, data, (size_t) data_len)) { - bson_set_error (&error_local, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid BSON in $query subdocument"); - GOTO (done); - } - has_filter = true; - } else if (_translate_query_opt (key, &opt_key, &len)) { - /* "$orderby" becomes "sort", etc., "$unknown" -> "unknown" */ - if (!bson_append_iter (opts, opt_key, len, &iter)) { - bson_set_error (&error_local, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Error adding \"%s\" to query", - opt_key); - } - } else { - /* strip leading "$" */ - if (!bson_append_iter (opts, key + 1, -1, &iter)) { - bson_set_error (&error_local, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Error adding \"%s\" to query", - key); - } - } - } - } -done: - if (error) { - memcpy (error, &error_local, sizeof (bson_error_t)); - } - if (!has_filter) { - bson_init (unwrapped); - } - RETURN (has_filter); -} - - -void -mongoc_cursor_destroy (mongoc_cursor_t *cursor) -{ - char db[MONGOC_NAMESPACE_MAX]; - ENTRY; - - if (!cursor) { - EXIT; - } - - if (cursor->impl.destroy) { - cursor->impl.destroy (&cursor->impl); - } - - if (cursor->client_generation == cursor->client->generation) { - if (cursor->in_exhaust) { - cursor->client->in_exhaust = false; - if (cursor->state != DONE) { - /* The only way to stop an exhaust cursor is to kill the connection - */ - mongoc_cluster_disconnect_node ( - &cursor->client->cluster, cursor->server_id, false, NULL); - } - } else if (cursor->cursor_id) { - bson_strncpy (db, cursor->ns, cursor->dblen + 1); - - _mongoc_client_kill_cursor (cursor->client, - cursor->server_id, - cursor->cursor_id, - cursor->operation_id, - db, - cursor->ns + cursor->dblen + 1, - cursor->client_session); - } - } - - if (cursor->client_session && !cursor->explicit_session) { - mongoc_client_session_destroy (cursor->client_session); - } - - mongoc_read_prefs_destroy (cursor->read_prefs); - mongoc_read_concern_destroy (cursor->read_concern); - mongoc_write_concern_destroy (cursor->write_concern); - - bson_destroy (&cursor->opts); - bson_destroy (&cursor->error_doc); - bson_free (cursor); - - mongoc_counter_cursors_active_dec (); - mongoc_counter_cursors_disposed_inc (); - - EXIT; -} - - -mongoc_server_stream_t * -_mongoc_cursor_fetch_stream (mongoc_cursor_t *cursor) -{ - mongoc_server_stream_t *server_stream; - bson_t reply; - - ENTRY; - - if (cursor->server_id) { - server_stream = - mongoc_cluster_stream_for_server (&cursor->client->cluster, - cursor->server_id, - true /* reconnect_ok */, - cursor->client_session, - &reply, - &cursor->error); - } else { - server_stream = mongoc_cluster_stream_for_reads (&cursor->client->cluster, - cursor->read_prefs, - cursor->client_session, - &reply, - &cursor->error); - - if (server_stream) { - cursor->server_id = server_stream->sd->id; - } - } - - if (!server_stream) { - bson_destroy (&cursor->error_doc); - bson_copy_to (&reply, &cursor->error_doc); - bson_destroy (&reply); - } - - RETURN (server_stream); -} - - -bool -_mongoc_cursor_monitor_command (mongoc_cursor_t *cursor, - mongoc_server_stream_t *server_stream, - const bson_t *cmd, - const char *cmd_name) -{ - mongoc_client_t *client; - mongoc_apm_command_started_t event; - char db[MONGOC_NAMESPACE_MAX]; - - ENTRY; - - client = cursor->client; - if (!client->apm_callbacks.started) { - /* successful */ - RETURN (true); - } - - bson_strncpy (db, cursor->ns, cursor->dblen + 1); - - mongoc_apm_command_started_init (&event, - cmd, - db, - cmd_name, - client->cluster.request_id, - cursor->operation_id, - &server_stream->sd->host, - server_stream->sd->id, - client->apm_context); - - client->apm_callbacks.started (&event); - mongoc_apm_command_started_cleanup (&event); - - RETURN (true); -} - - -/* append array of docs from current cursor batch */ -static void -_mongoc_cursor_append_docs_array (mongoc_cursor_t *cursor, - bson_t *docs, - mongoc_cursor_response_legacy_t *response) -{ - bool eof = false; - char str[16]; - const char *key; - uint32_t i = 0; - size_t keylen; - const bson_t *doc; - - while ((doc = bson_reader_read (response->reader, &eof))) { - keylen = bson_uint32_to_string (i, &key, str, sizeof str); - bson_append_document (docs, key, (int) keylen, doc); - } - - bson_reader_reset (response->reader); -} - - -void -_mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor, - mongoc_cursor_response_legacy_t *response, - int64_t duration, - bool first_batch, - mongoc_server_stream_t *stream, - const char *cmd_name) -{ - bson_t docs_array; - mongoc_apm_command_succeeded_t event; - mongoc_client_t *client; - bson_t reply; - bson_t reply_cursor; - - ENTRY; - - client = cursor->client; - - if (!client->apm_callbacks.succeeded) { - EXIT; - } - - /* we sent OP_QUERY/OP_GETMORE, fake a reply to find/getMore command: - * {ok: 1, cursor: {id: 17, ns: "...", first/nextBatch: [ ... docs ... ]}} - */ - bson_init (&docs_array); - _mongoc_cursor_append_docs_array (cursor, &docs_array, response); - - bson_init (&reply); - bson_append_int32 (&reply, "ok", 2, 1); - bson_append_document_begin (&reply, "cursor", 6, &reply_cursor); - bson_append_int64 (&reply_cursor, "id", 2, mongoc_cursor_get_id (cursor)); - bson_append_utf8 (&reply_cursor, "ns", 2, cursor->ns, cursor->nslen); - bson_append_array (&reply_cursor, - first_batch ? "firstBatch" : "nextBatch", - first_batch ? 10 : 9, - &docs_array); - bson_append_document_end (&reply, &reply_cursor); - bson_destroy (&docs_array); - - mongoc_apm_command_succeeded_init (&event, - duration, - &reply, - cmd_name, - client->cluster.request_id, - cursor->operation_id, - &stream->sd->host, - stream->sd->id, - client->apm_context); - - client->apm_callbacks.succeeded (&event); - - mongoc_apm_command_succeeded_cleanup (&event); - bson_destroy (&reply); - - EXIT; -} - - -void -_mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor, - int64_t duration, - mongoc_server_stream_t *stream, - const char *cmd_name) -{ - mongoc_apm_command_failed_t event; - mongoc_client_t *client; - bson_t reply; - - ENTRY; - - client = cursor->client; - - if (!client->apm_callbacks.failed) { - EXIT; - } - - /* we sent OP_QUERY/OP_GETMORE, fake a reply to find/getMore command: - * {ok: 0} - */ - bson_init (&reply); - bson_append_int32 (&reply, "ok", 2, 0); - - mongoc_apm_command_failed_init (&event, - duration, - cmd_name, - &cursor->error, - &reply, - client->cluster.request_id, - cursor->operation_id, - &stream->sd->host, - stream->sd->id, - client->apm_context); - - client->apm_callbacks.failed (&event); - - mongoc_apm_command_failed_cleanup (&event); - bson_destroy (&reply); - - EXIT; -} - - -#define ADD_FLAG(_flags, _value) \ - do { \ - if (!BSON_ITER_HOLDS_BOOL (&iter)) { \ - bson_set_error (&cursor->error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - "invalid option %s, should be type bool", \ - key); \ - return false; \ - } \ - if (bson_iter_as_bool (&iter)) { \ - *_flags |= _value; \ - } \ - } while (false); - -bool -_mongoc_cursor_opts_to_flags (mongoc_cursor_t *cursor, - mongoc_server_stream_t *stream, - mongoc_query_flags_t *flags /* OUT */) -{ - bson_iter_t iter; - const char *key; - - *flags = MONGOC_QUERY_NONE; - - if (!bson_iter_init (&iter, &cursor->opts)) { - bson_set_error (&cursor->error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - - if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) { - ADD_FLAG (flags, MONGOC_QUERY_PARTIAL); - } else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) { - ADD_FLAG (flags, MONGOC_QUERY_AWAIT_DATA); - } else if (!strcmp (key, MONGOC_CURSOR_EXHAUST)) { - ADD_FLAG (flags, MONGOC_QUERY_EXHAUST); - } else if (!strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT)) { - ADD_FLAG (flags, MONGOC_QUERY_NO_CURSOR_TIMEOUT); - } else if (!strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY)) { - ADD_FLAG (flags, MONGOC_QUERY_OPLOG_REPLAY); - } else if (!strcmp (key, MONGOC_CURSOR_TAILABLE)) { - ADD_FLAG (flags, MONGOC_QUERY_TAILABLE_CURSOR); - } - } - - if (cursor->slave_ok) { - *flags |= MONGOC_QUERY_SLAVE_OK; - } else if (cursor->server_id && - (stream->topology_type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY || - stream->topology_type == MONGOC_TOPOLOGY_RS_NO_PRIMARY) && - stream->sd->type != MONGOC_SERVER_RS_PRIMARY) { - *flags |= MONGOC_QUERY_SLAVE_OK; - } - - return true; -} - -bool -_mongoc_cursor_run_command (mongoc_cursor_t *cursor, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bool retry_prohibited) -{ - mongoc_server_stream_t *server_stream; - bson_iter_t iter; - mongoc_cmd_parts_t parts; - const char *cmd_name; - bool is_primary; - mongoc_read_prefs_t *prefs = NULL; - char db[MONGOC_NAMESPACE_MAX]; - mongoc_session_opt_t *session_opts; - bool ret = false; - bool is_retryable = true; - - ENTRY; - - mongoc_cmd_parts_init ( - &parts, cursor->client, db, MONGOC_QUERY_NONE, command); - parts.is_read_command = true; - parts.read_prefs = cursor->read_prefs; - parts.assembled.operation_id = cursor->operation_id; - server_stream = _mongoc_cursor_fetch_stream (cursor); - - if (!server_stream) { - _mongoc_bson_init_if_set (reply); - GOTO (done); - } - - if (opts) { - if (!bson_iter_init (&iter, opts)) { - _mongoc_bson_init_if_set (reply); - bson_set_error (&cursor->error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid BSON in opts document"); - GOTO (done); - } - if (!mongoc_cmd_parts_append_opts (&parts, - &iter, - server_stream->sd->max_wire_version, - &cursor->error)) { - _mongoc_bson_init_if_set (reply); - GOTO (done); - } - } - - if (parts.assembled.session) { - /* initial query/aggregate/etc, and opts contains "sessionId" */ - BSON_ASSERT (!cursor->client_session); - BSON_ASSERT (!cursor->explicit_session); - cursor->client_session = parts.assembled.session; - cursor->explicit_session = true; - } else if (cursor->client_session) { - /* a getMore with implicit or explicit session already acquired */ - mongoc_cmd_parts_set_session (&parts, cursor->client_session); - } else { - /* try to create an implicit session. not causally consistent. we keep - * the session but leave cursor->explicit_session as 0, so we use the - * same lsid for getMores but destroy the session when the cursor dies. - */ - session_opts = mongoc_session_opts_new (); - mongoc_session_opts_set_causal_consistency (session_opts, false); - /* returns NULL if sessions aren't supported. ignore errors. */ - cursor->client_session = - mongoc_client_start_session (cursor->client, session_opts, NULL); - mongoc_cmd_parts_set_session (&parts, cursor->client_session); - mongoc_session_opts_destroy (session_opts); - } - - if (!mongoc_cmd_parts_set_read_concern (&parts, - cursor->read_concern, - server_stream->sd->max_wire_version, - &cursor->error)) { - _mongoc_bson_init_if_set (reply); - GOTO (done); - } - - bson_strncpy (db, cursor->ns, cursor->dblen + 1); - parts.assembled.db_name = db; - - if (!_mongoc_cursor_opts_to_flags ( - cursor, server_stream, &parts.user_query_flags)) { - _mongoc_bson_init_if_set (reply); - GOTO (done); - } - - /* we might use mongoc_cursor_set_hint to target a secondary but have no - * read preference, so the secondary rejects the read. same if we have a - * direct connection to a secondary (topology type "single"). with - * OP_QUERY we handle this by setting slaveOk. here we use $readPreference. - */ - cmd_name = _mongoc_get_command_name (command); - is_primary = - !cursor->read_prefs || cursor->read_prefs->mode == MONGOC_READ_PRIMARY; - - if (strcmp (cmd_name, "getMore") != 0 && - server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG && - is_primary && parts.user_query_flags & MONGOC_QUERY_SLAVE_OK) { - parts.read_prefs = prefs = - mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED); - } else { - parts.read_prefs = cursor->read_prefs; - } - - is_retryable = _is_retryable_read (&parts, server_stream); - if (!strcmp (cmd_name, "getMore")) { - is_retryable = false; - } - if (!strcmp (cmd_name, "aggregate")) { - bson_iter_t pipeline_iter; - if (bson_iter_init_find (&pipeline_iter, command, "pipeline") && - BSON_ITER_HOLDS_ARRAY (&pipeline_iter) && - bson_iter_recurse (&pipeline_iter, &pipeline_iter)) { - if (_has_write_key (&pipeline_iter)) { - is_retryable = false; - } - } - } - if (is_retryable && retry_prohibited) { - is_retryable = false; - } - - if (cursor->write_concern && - !mongoc_write_concern_is_default (cursor->write_concern) && - server_stream->sd->max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN) { - parts.assembled.is_acknowledged = - mongoc_write_concern_is_acknowledged (cursor->write_concern); - mongoc_write_concern_append (cursor->write_concern, &parts.extra); - } - - if (!mongoc_cmd_parts_assemble (&parts, server_stream, &cursor->error)) { - _mongoc_bson_init_if_set (reply); - GOTO (done); - } - -retry: - ret = mongoc_cluster_run_command_monitored ( - &cursor->client->cluster, &parts.assembled, reply, &cursor->error); - - if (ret) { - memset (&cursor->error, 0, sizeof (bson_error_t)); - } - - if (is_retryable && - _mongoc_read_error_get_type (ret, &cursor->error, reply) == - MONGOC_READ_ERR_RETRY) { - is_retryable = false; - - mongoc_server_stream_cleanup (server_stream); - - server_stream = mongoc_cluster_stream_for_reads (&cursor->client->cluster, - cursor->read_prefs, - cursor->client_session, - reply, - &cursor->error); - - if (server_stream && - server_stream->sd->max_wire_version >= WIRE_VERSION_RETRY_READS) { - cursor->server_id = server_stream->sd->id; - parts.assembled.server_stream = server_stream; - bson_destroy (reply); - GOTO (retry); - } - } - - if (cursor->error.domain) { - bson_destroy (&cursor->error_doc); - bson_copy_to (reply, &cursor->error_doc); - } - - /* Read and Write Concern Spec: "Drivers SHOULD parse server replies for a - * "writeConcernError" field and report the error only in command-specific - * helper methods that take a separate write concern parameter or an options - * parameter that may contain a write concern option. - * - * Only command helpers with names like "_with_write_concern" can create - * cursors with a non-NULL write_concern field. - */ - if (ret && cursor->write_concern) { - ret = !_mongoc_parse_wc_err (reply, &cursor->error); - } - -done: - mongoc_server_stream_cleanup (server_stream); - mongoc_cmd_parts_cleanup (&parts); - mongoc_read_prefs_destroy (prefs); - - return ret; -} - - -void -_mongoc_cursor_collection (const mongoc_cursor_t *cursor, - const char **collection, - int *collection_len) -{ - /* ns is like "db.collection". Collection name is located past the ".". */ - *collection = cursor->ns + (cursor->dblen + 1); - /* Collection name's length is ns length, minus length of db name and ".". */ - *collection_len = cursor->nslen - cursor->dblen - 1; - - BSON_ASSERT (*collection_len > 0); -} - - -void -_mongoc_cursor_prepare_find_command (mongoc_cursor_t *cursor, - const bson_t *filter, - bson_t *command) -{ - const char *collection; - int collection_len; - - _mongoc_cursor_collection (cursor, &collection, &collection_len); - bson_append_utf8 (command, - MONGOC_CURSOR_FIND, - MONGOC_CURSOR_FIND_LEN, - collection, - collection_len); - bson_append_document ( - command, MONGOC_CURSOR_FILTER, MONGOC_CURSOR_FILTER_LEN, filter); -} - - -bool -mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error) -{ - ENTRY; - - RETURN (mongoc_cursor_error_document (cursor, error, NULL)); -} - - -bool -mongoc_cursor_error_document (mongoc_cursor_t *cursor, - bson_error_t *error, - const bson_t **doc) -{ - ENTRY; - - BSON_ASSERT (cursor); - - if (BSON_UNLIKELY (CURSOR_FAILED (cursor))) { - bson_set_error (error, - cursor->error.domain, - cursor->error.code, - "%s", - cursor->error.message); - - if (doc) { - *doc = &cursor->error_doc; - } - - RETURN (true); - } - - if (doc) { - *doc = NULL; - } - - RETURN (false); -} - - -static mongoc_cursor_state_t -_call_transition (mongoc_cursor_t *cursor) -{ - mongoc_cursor_state_t state = cursor->state; - _mongoc_cursor_impl_transition_t fn = NULL; - switch (state) { - case UNPRIMED: - fn = cursor->impl.prime; - break; - case IN_BATCH: - fn = cursor->impl.pop_from_batch; - break; - case END_OF_BATCH: - fn = cursor->impl.get_next_batch; - break; - case DONE: - default: - fn = NULL; - break; - } - if (!fn) { - return DONE; - } - state = fn (cursor); - if (cursor->error.domain) { - state = DONE; - } - return state; -} - - -bool -mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson) -{ - bool ret = false; - bool attempted_refresh = false; - - ENTRY; - - BSON_ASSERT (cursor); - BSON_ASSERT (bson); - - TRACE ("cursor_id(%" PRId64 ")", cursor->cursor_id); - - if (cursor->client_generation != cursor->client->generation) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot advance cursor after client reset"); - RETURN (false); - } - - if (bson) { - *bson = NULL; - } - - if (CURSOR_FAILED (cursor)) { - RETURN (false); - } - - if (cursor->state == DONE) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot advance a completed or failed cursor."); - RETURN (false); - } - - /* - * We cannot proceed if another cursor is receiving results in exhaust mode. - */ - if (cursor->client->in_exhaust && !cursor->in_exhaust) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_IN_EXHAUST, - "Another cursor derived from this client is in exhaust."); - RETURN (false); - } - - cursor->current = NULL; - - /* if an error was set on this cursor before calling next, transition to DONE - * immediately. */ - if (cursor->error.domain) { - cursor->state = DONE; - GOTO (done); - } - - while (cursor->state != DONE) { - /* even when there is no data to return, some cursors remain open and - * continue sending empty batches (e.g. a tailable or change stream - * cursor). in that case, do not attempt to get another batch. */ - if (cursor->state == END_OF_BATCH) { - if (attempted_refresh) { - RETURN (false); - } - attempted_refresh = true; - } - - cursor->state = _call_transition (cursor); - - /* check if we received a document. */ - if (cursor->current) { - *bson = cursor->current; - ret = true; - GOTO (done); - } - - if (cursor->state == DONE) { - GOTO (done); - } - } - -done: - cursor->count++; - RETURN (ret); -} - - -bool -mongoc_cursor_more (mongoc_cursor_t *cursor) -{ - ENTRY; - - BSON_ASSERT (cursor); - - if (CURSOR_FAILED (cursor)) { - RETURN (false); - } - - RETURN (cursor->state != DONE); -} - - -void -mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host) -{ - mongoc_server_description_t *description; - - BSON_ASSERT (cursor); - BSON_ASSERT (host); - - memset (host, 0, sizeof *host); - - if (!cursor->server_id) { - MONGOC_WARNING ("%s(): Must send query before fetching peer.", BSON_FUNC); - return; - } - - description = mongoc_topology_server_by_id ( - cursor->client->topology, cursor->server_id, &cursor->error); - if (!description) { - return; - } - - *host = description->host; - - mongoc_server_description_destroy (description); - - EXIT; -} - - -mongoc_cursor_t * -mongoc_cursor_clone (const mongoc_cursor_t *cursor) -{ - mongoc_cursor_t *_clone; - - BSON_ASSERT (cursor); - - _clone = (mongoc_cursor_t *) bson_malloc0 (sizeof *_clone); - - _clone->client = cursor->client; - _clone->nslen = cursor->nslen; - _clone->dblen = cursor->dblen; - _clone->explicit_session = cursor->explicit_session; - - if (cursor->read_prefs) { - _clone->read_prefs = mongoc_read_prefs_copy (cursor->read_prefs); - } - - if (cursor->read_concern) { - _clone->read_concern = mongoc_read_concern_copy (cursor->read_concern); - } - - if (cursor->write_concern) { - _clone->write_concern = mongoc_write_concern_copy (cursor->write_concern); - } - - if (cursor->explicit_session) { - _clone->client_session = cursor->client_session; - } - - bson_copy_to (&cursor->opts, &_clone->opts); - bson_init (&_clone->error_doc); - - bson_strncpy (_clone->ns, cursor->ns, sizeof _clone->ns); - - /* copy the context functions by default. */ - memcpy (&_clone->impl, &cursor->impl, sizeof (cursor->impl)); - if (cursor->impl.clone) { - cursor->impl.clone (&_clone->impl, &cursor->impl); - } - - mongoc_counter_cursors_active_inc (); - - RETURN (_clone); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_cursor_is_alive -- - * - * Deprecated for mongoc_cursor_more. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_cursor_is_alive (const mongoc_cursor_t *cursor) /* IN */ -{ - return mongoc_cursor_more ((mongoc_cursor_t *) cursor); -} - - -const bson_t * -mongoc_cursor_current (const mongoc_cursor_t *cursor) /* IN */ -{ - BSON_ASSERT (cursor); - - return cursor->current; -} - - -void -mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size) -{ - BSON_ASSERT (cursor); - - _mongoc_cursor_set_opt_int64 ( - cursor, MONGOC_CURSOR_BATCH_SIZE, (int64_t) batch_size); -} - - -uint32_t -mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor) -{ - BSON_ASSERT (cursor); - - return (uint32_t) _mongoc_cursor_get_opt_int64 ( - cursor, MONGOC_CURSOR_BATCH_SIZE, 0); -} - - -bool -mongoc_cursor_set_limit (mongoc_cursor_t *cursor, int64_t limit) -{ - BSON_ASSERT (cursor); - - if (cursor->state == UNPRIMED) { - if (limit < 0) { - return _mongoc_cursor_set_opt_int64 ( - cursor, MONGOC_CURSOR_LIMIT, -limit) && - _mongoc_cursor_set_opt_bool ( - cursor, MONGOC_CURSOR_SINGLE_BATCH, true); - } else { - return _mongoc_cursor_set_opt_int64 ( - cursor, MONGOC_CURSOR_LIMIT, limit); - } - } else { - return false; - } -} - - -int64_t -mongoc_cursor_get_limit (const mongoc_cursor_t *cursor) -{ - int64_t limit; - bool single_batch; - - BSON_ASSERT (cursor); - - limit = _mongoc_cursor_get_opt_int64 (cursor, MONGOC_CURSOR_LIMIT, 0); - single_batch = - _mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_SINGLE_BATCH); - - if (limit > 0 && single_batch) { - limit = -limit; - } - - return limit; -} - - -bool -mongoc_cursor_set_hint (mongoc_cursor_t *cursor, uint32_t server_id) -{ - BSON_ASSERT (cursor); - - if (cursor->server_id) { - MONGOC_ERROR ("mongoc_cursor_set_hint: server_id already set"); - return false; - } - - if (!server_id) { - MONGOC_ERROR ("mongoc_cursor_set_hint: cannot set server_id to 0"); - return false; - } - - cursor->server_id = server_id; - - return true; -} - - -uint32_t -mongoc_cursor_get_hint (const mongoc_cursor_t *cursor) -{ - BSON_ASSERT (cursor); - - return cursor->server_id; -} - - -int64_t -mongoc_cursor_get_id (const mongoc_cursor_t *cursor) -{ - BSON_ASSERT (cursor); - - return cursor->cursor_id; -} - - -void -mongoc_cursor_set_max_await_time_ms (mongoc_cursor_t *cursor, - uint32_t max_await_time_ms) -{ - BSON_ASSERT (cursor); - - if (cursor->state == UNPRIMED) { - _mongoc_cursor_set_opt_int64 ( - cursor, MONGOC_CURSOR_MAX_AWAIT_TIME_MS, (int64_t) max_await_time_ms); - } -} - - -uint32_t -mongoc_cursor_get_max_await_time_ms (const mongoc_cursor_t *cursor) -{ - bson_iter_t iter; - - BSON_ASSERT (cursor); - - if (bson_iter_init_find ( - &iter, &cursor->opts, MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) { - return (uint32_t) bson_iter_as_int64 (&iter); - } - - return 0; -} - - -/* deprecated for mongoc_cursor_new_from_command_reply_with_opts */ -mongoc_cursor_t * -mongoc_cursor_new_from_command_reply (mongoc_client_t *client, - bson_t *reply, - uint32_t server_id) -{ - mongoc_cursor_t *cursor; - bson_t cmd = BSON_INITIALIZER; - bson_t opts = BSON_INITIALIZER; - - BSON_ASSERT (client); - BSON_ASSERT (reply); - /* options are passed through by adding them to reply. */ - bson_copy_to_excluding_noinit (reply, - &opts, - "cursor", - "ok", - "operationTime", - "$clusterTime", - "$gleStats", - NULL); - - if (server_id) { - bson_append_int64 (&opts, "serverId", 8, server_id); - } - - cursor = _mongoc_cursor_cmd_new_from_reply (client, &cmd, &opts, reply); - bson_destroy (&cmd); - bson_destroy (&opts); - - return cursor; -} - - -mongoc_cursor_t * -mongoc_cursor_new_from_command_reply_with_opts (mongoc_client_t *client, - bson_t *reply, - const bson_t *opts) -{ - mongoc_cursor_t *cursor; - bson_t cmd = BSON_INITIALIZER; - - BSON_ASSERT (client); - BSON_ASSERT (reply); - - cursor = _mongoc_cursor_cmd_new_from_reply (client, &cmd, opts, reply); - bson_destroy (&cmd); - - return cursor; -} - - -bool -_mongoc_cursor_start_reading_response (mongoc_cursor_t *cursor, - mongoc_cursor_response_t *response) -{ - bson_iter_t iter; - bson_iter_t child; - const char *ns; - uint32_t nslen; - bool in_batch = false; - - if (bson_iter_init_find (&iter, &response->reply, "cursor") && - BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child)) { - while (bson_iter_next (&child)) { - if (BSON_ITER_IS_KEY (&child, "id")) { - cursor->cursor_id = bson_iter_as_int64 (&child); - } else if (BSON_ITER_IS_KEY (&child, "ns")) { - ns = bson_iter_utf8 (&child, &nslen); - _mongoc_set_cursor_ns (cursor, ns, nslen); - } else if (BSON_ITER_IS_KEY (&child, "firstBatch") || - BSON_ITER_IS_KEY (&child, "nextBatch")) { - if (BSON_ITER_HOLDS_ARRAY (&child) && - bson_iter_recurse (&child, &response->batch_iter)) { - in_batch = true; - } - } - } - } - - /* Driver Sessions Spec: "When an implicit session is associated with a - * cursor for use with getMore operations, the session MUST be returned to - * the pool immediately following a getMore operation that indicates that the - * cursor has been exhausted." */ - if (cursor->cursor_id == 0 && cursor->client_session && - !cursor->explicit_session) { - mongoc_client_session_destroy (cursor->client_session); - cursor->client_session = NULL; - } - - return in_batch; -} - - -void -_mongoc_cursor_response_read (mongoc_cursor_t *cursor, - mongoc_cursor_response_t *response, - const bson_t **bson) -{ - const uint8_t *data = NULL; - uint32_t data_len = 0; - - ENTRY; - - if (bson_iter_next (&response->batch_iter) && - BSON_ITER_HOLDS_DOCUMENT (&response->batch_iter)) { - bson_iter_document (&response->batch_iter, &data_len, &data); - - /* bson_iter_next guarantees valid BSON, so this must succeed */ - BSON_ASSERT (bson_init_static (&response->current_doc, data, data_len)); - *bson = &response->current_doc; - } -} - -/* sets cursor error if could not get the next batch. */ -void -_mongoc_cursor_response_refresh (mongoc_cursor_t *cursor, - const bson_t *command, - const bson_t *opts, - mongoc_cursor_response_t *response) -{ - ENTRY; - - bson_destroy (&response->reply); - - /* server replies to find / aggregate with {cursor: {id: N, firstBatch: []}}, - * to getMore command with {cursor: {id: N, nextBatch: []}}. */ - if (_mongoc_cursor_run_command ( - cursor, command, opts, &response->reply, false) && - _mongoc_cursor_start_reading_response (cursor, response)) { - return; - } - if (!cursor->error.domain) { - bson_set_error (&cursor->error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Invalid reply to %s command.", - _mongoc_get_command_name (command)); - } -} - -void -_mongoc_cursor_prepare_getmore_command (mongoc_cursor_t *cursor, - bson_t *command) -{ - const char *collection; - int collection_len; - int64_t batch_size; - bool await_data; - int64_t max_await_time_ms; - - ENTRY; - - _mongoc_cursor_collection (cursor, &collection, &collection_len); - - bson_init (command); - bson_append_int64 (command, "getMore", 7, mongoc_cursor_get_id (cursor)); - bson_append_utf8 (command, "collection", 10, collection, collection_len); - - batch_size = mongoc_cursor_get_batch_size (cursor); - - /* See find, getMore, and killCursors Spec for batchSize rules */ - if (batch_size) { - bson_append_int64 (command, - MONGOC_CURSOR_BATCH_SIZE, - MONGOC_CURSOR_BATCH_SIZE_LEN, - abs (_mongoc_n_return (cursor))); - } - - /* Find, getMore And killCursors Commands Spec: "In the case of a tailable - cursor with awaitData == true the driver MUST provide a Cursor level - option named maxAwaitTimeMS (See CRUD specification for details). The - maxTimeMS option on the getMore command MUST be set to the value of the - option maxAwaitTimeMS. If no maxAwaitTimeMS is specified, the driver - SHOULD not set maxTimeMS on the getMore command." - */ - await_data = _mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_TAILABLE) && - _mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_AWAIT_DATA); - - if (await_data) { - max_await_time_ms = _mongoc_cursor_get_opt_int64 ( - cursor, MONGOC_CURSOR_MAX_AWAIT_TIME_MS, 0); - if (max_await_time_ms) { - bson_append_int64 (command, - MONGOC_CURSOR_MAX_TIME_MS, - MONGOC_CURSOR_MAX_TIME_MS_LEN, - max_await_time_ms); - } - } -} - -/* sets the cursor to be empty so it returns NULL on the first call to - * cursor_next but does not return an error. */ -void -_mongoc_cursor_set_empty (mongoc_cursor_t *cursor) -{ - memset (&cursor->error, 0, sizeof (bson_error_t)); - bson_reinit (&cursor->error_doc); - cursor->state = IN_BATCH; -} - -void -_mongoc_cursor_prime (mongoc_cursor_t *cursor) -{ - cursor->state = cursor->impl.prime (cursor); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor.h deleted file mode 100644 index 5c85d21c5d7082d4fce1e2525bd1f1b3d22bfccc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cursor.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CURSOR_H -#define MONGOC_CURSOR_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-host-list.h" - - -BSON_BEGIN_DECLS - -typedef struct _mongoc_cursor_t mongoc_cursor_t; - - -/* forward decl */ -struct _mongoc_client_t; - -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_cursor_clone (const mongoc_cursor_t *cursor) - BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (void) -mongoc_cursor_destroy (mongoc_cursor_t *cursor); -MONGOC_EXPORT (bool) -mongoc_cursor_more (mongoc_cursor_t *cursor); -MONGOC_EXPORT (bool) -mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson); -MONGOC_EXPORT (bool) -mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_cursor_error_document (mongoc_cursor_t *cursor, - bson_error_t *error, - const bson_t **doc); -MONGOC_EXPORT (void) -mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host); -MONGOC_EXPORT (bool) -mongoc_cursor_is_alive (const mongoc_cursor_t *cursor) - BSON_GNUC_DEPRECATED_FOR (mongoc_cursor_more); -MONGOC_EXPORT (const bson_t *) -mongoc_cursor_current (const mongoc_cursor_t *cursor); -MONGOC_EXPORT (void) -mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size); -MONGOC_EXPORT (uint32_t) -mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor); -MONGOC_EXPORT (bool) -mongoc_cursor_set_limit (mongoc_cursor_t *cursor, int64_t limit); -MONGOC_EXPORT (int64_t) -mongoc_cursor_get_limit (const mongoc_cursor_t *cursor); -/* These names include the term "hint" for backward compatibility, should be - * mongoc_cursor_get_server_id, mongoc_cursor_set_server_id. */ -MONGOC_EXPORT (bool) -mongoc_cursor_set_hint (mongoc_cursor_t *cursor, uint32_t server_id); -MONGOC_EXPORT (uint32_t) -mongoc_cursor_get_hint (const mongoc_cursor_t *cursor); -MONGOC_EXPORT (int64_t) -mongoc_cursor_get_id (const mongoc_cursor_t *cursor); -MONGOC_EXPORT (void) -mongoc_cursor_set_max_await_time_ms (mongoc_cursor_t *cursor, - uint32_t max_await_time_ms); -MONGOC_EXPORT (uint32_t) -mongoc_cursor_get_max_await_time_ms (const mongoc_cursor_t *cursor); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_cursor_new_from_command_reply (struct _mongoc_client_t *client, - bson_t *reply, - uint32_t server_id) - BSON_GNUC_WARN_UNUSED_RESULT - BSON_GNUC_DEPRECATED_FOR (mongoc_cursor_new_from_command_reply_with_opts); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_cursor_new_from_command_reply_with_opts (struct _mongoc_client_t *client, - bson_t *reply, - const bson_t *opts) - BSON_GNUC_WARN_UNUSED_RESULT; - -BSON_END_DECLS - - -#endif /* MONGOC_CURSOR_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cyrus-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-cyrus-private.h deleted file mode 100644 index 05e023ca36156bafeb554867c9110fa228e8a51e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cyrus-private.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_CYRUS_PRIVATE_H -#define MONGOC_CYRUS_PRIVATE_H - -#include "mongoc/mongoc-uri.h" -#include "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-sasl-private.h" -#include <bson/bson.h> -#include <sasl/sasl.h> -#include <sasl/saslutil.h> - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_cyrus_t mongoc_cyrus_t; - - -struct _mongoc_cyrus_t { - mongoc_sasl_t credentials; - sasl_callback_t callbacks[6]; - sasl_conn_t *conn; - bool done; - int step; - sasl_interact_t *interact; -}; - - -#ifndef SASL_CALLBACK_FN -#define SASL_CALLBACK_FN(_f) ((int (*) (void)) (_f)) -#endif - -void -_mongoc_cyrus_init (mongoc_cyrus_t *sasl); -bool -_mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl, - mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - const char *hostname, - bson_error_t *error); -int -_mongoc_cyrus_log (mongoc_cyrus_t *sasl, int level, const char *message); -void -_mongoc_cyrus_destroy (mongoc_cyrus_t *sasl); -bool -_mongoc_cyrus_step (mongoc_cyrus_t *sasl, - const uint8_t *inbuf, - uint32_t inbuflen, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen, - bson_error_t *error); - - -BSON_END_DECLS - - -#endif /* MONGOC_CYRUS_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-cyrus.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-cyrus.c deleted file mode 100644 index 7de3369927e4f0dccd293da8ae49b0f3ca1ac2e2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-cyrus.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SASL_CYRUS - -#include <string.h> - -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-cyrus-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-trace-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "CYRUS-SASL" - -bool -_mongoc_cyrus_set_mechanism (mongoc_cyrus_t *sasl, - const char *mechanism, - bson_error_t *error) -{ - bson_string_t *str = bson_string_new (""); - const char **mechs = sasl_global_listmech (); - int i = 0; - bool ok = false; - - BSON_ASSERT (sasl); - - for (i = 0; mechs[i]; i++) { - if (!strcmp (mechs[i], mechanism)) { - ok = true; - break; - } - bson_string_append (str, mechs[i]); - if (mechs[i + 1]) { - bson_string_append (str, ","); - } - } - - if (ok) { - bson_free (sasl->credentials.mechanism); - sasl->credentials.mechanism = mechanism ? bson_strdup (mechanism) : NULL; - } else { - bson_set_error (error, - MONGOC_ERROR_SASL, - SASL_NOMECH, - "SASL Failure: Unsupported mechanism by client: %s. " - "Available mechanisms: %s", - mechanism, - str->str); - } - - bson_string_free (str, true); - return ok; -} - - -static int -_mongoc_cyrus_get_pass (mongoc_cyrus_t *sasl, - int param_id, - const char **result, - unsigned *result_len) -{ - BSON_ASSERT (sasl); - BSON_ASSERT (param_id == SASL_CB_PASS); - - if (result) { - *result = sasl->credentials.pass; - } - - if (result_len) { - *result_len = sasl->credentials.pass - ? (unsigned) strlen (sasl->credentials.pass) - : 0; - } - - return (sasl->credentials.pass != NULL) ? SASL_OK : SASL_FAIL; -} - - -static int -_mongoc_cyrus_canon_user (sasl_conn_t *conn, - mongoc_cyrus_t *sasl, - const char *in, - unsigned inlen, - unsigned flags, - const char *user_realm, - char *out, - unsigned out_max, - unsigned *out_len) -{ - TRACE ("Canonicalizing %s (%" PRIu32 ")\n", in, inlen); - strcpy (out, in); - *out_len = inlen; - return SASL_OK; -} - -static int -_mongoc_cyrus_get_user (mongoc_cyrus_t *sasl, - int param_id, - const char **result, - unsigned *result_len) -{ - BSON_ASSERT (sasl); - BSON_ASSERT ((param_id == SASL_CB_USER) || (param_id == SASL_CB_AUTHNAME)); - - if (result) { - *result = sasl->credentials.user; - } - - if (result_len) { - *result_len = sasl->credentials.user - ? (unsigned) strlen (sasl->credentials.user) - : 0; - } - - return (sasl->credentials.user != NULL) ? SASL_OK : SASL_FAIL; -} - - -void -_mongoc_cyrus_init (mongoc_cyrus_t *sasl) -{ - sasl_callback_t callbacks[] = { - {SASL_CB_AUTHNAME, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl}, - {SASL_CB_USER, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl}, - {SASL_CB_PASS, SASL_CALLBACK_FN (_mongoc_cyrus_get_pass), sasl}, - {SASL_CB_CANON_USER, SASL_CALLBACK_FN (_mongoc_cyrus_canon_user), sasl}, - {SASL_CB_LIST_END}}; - - BSON_ASSERT (sasl); - - memset (sasl, 0, sizeof *sasl); - - memcpy (&sasl->callbacks, callbacks, sizeof callbacks); - - sasl->done = false; - sasl->step = 0; - sasl->conn = NULL; - sasl->interact = NULL; - sasl->credentials.mechanism = NULL; - sasl->credentials.user = NULL; - sasl->credentials.pass = NULL; - sasl->credentials.service_name = NULL; - sasl->credentials.service_host = NULL; -} - -bool -_mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl, - mongoc_cluster_t *cluster, - mongoc_stream_t *stream, - const char *hostname, - bson_error_t *error) -{ - const char *mechanism; - char real_name[BSON_HOST_NAME_MAX + 1]; - - _mongoc_cyrus_init (sasl); - - mechanism = mongoc_uri_get_auth_mechanism (cluster->uri); - if (!mechanism) { - mechanism = "GSSAPI"; - } - - if (!_mongoc_cyrus_set_mechanism (sasl, mechanism, error)) { - _mongoc_cyrus_destroy (sasl); - return false; - } - - _mongoc_sasl_set_pass ((mongoc_sasl_t *) sasl, - mongoc_uri_get_password (cluster->uri)); - _mongoc_sasl_set_user ((mongoc_sasl_t *) sasl, - mongoc_uri_get_username (cluster->uri)); - _mongoc_sasl_set_properties ((mongoc_sasl_t *) sasl, cluster->uri); - - /* - * If the URI requested canonicalizeHostname, we need to resolve the real - * hostname for the IP Address and pass that to the SASL layer. Some - * underlying GSSAPI layers will do this for us, but can be disabled in - * their config (krb.conf). - * - * This allows the consumer to specify canonicalizeHostname=true in the URI - * and have us do that for them. - * - * See CDRIVER-323 for more information. - */ - if (sasl->credentials.canonicalize_host_name && - _mongoc_sasl_get_canonicalized_name ( - stream, real_name, sizeof real_name)) { - _mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, real_name); - } else { - _mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, hostname); - } - return true; -} - - -void -_mongoc_cyrus_destroy (mongoc_cyrus_t *sasl) -{ - BSON_ASSERT (sasl); - - if (sasl->conn) { - sasl_dispose (&sasl->conn); - } - - bson_free (sasl->credentials.user); - bson_free (sasl->credentials.pass); - bson_free (sasl->credentials.mechanism); - bson_free (sasl->credentials.service_name); - bson_free (sasl->credentials.service_host); -} - - -static bool -_mongoc_cyrus_is_failure (int status, bson_error_t *error) -{ - bool ret = (status < 0); - - TRACE ("Got status: %d ok is %d, continue=%d interact=%d\n", - status, - SASL_OK, - SASL_CONTINUE, - SASL_INTERACT); - if (ret) { - switch (status) { - case SASL_NOMEM: - bson_set_error (error, - MONGOC_ERROR_SASL, - status, - "SASL Failure: insufficient memory."); - break; - case SASL_NOMECH: { - bson_string_t *str = bson_string_new ("available mechanisms: "); - const char **mechs = sasl_global_listmech (); - int i = 0; - - for (i = 0; mechs[i]; i++) { - bson_string_append (str, mechs[i]); - if (mechs[i + 1]) { - bson_string_append (str, ","); - } - } - bson_set_error (error, - MONGOC_ERROR_SASL, - status, - "SASL Failure: failure to negotiate mechanism (%s)", - str->str); - bson_string_free (str, 0); - } break; - case SASL_BADPARAM: - bson_set_error (error, - MONGOC_ERROR_SASL, - status, - "Bad parameter supplied. Please file a bug " - "with mongo-c-driver."); - break; - default: - bson_set_error (error, - MONGOC_ERROR_SASL, - status, - "SASL Failure: (%d): %s", - status, - sasl_errstring (status, NULL, NULL)); - break; - } - } - - return ret; -} - - -static bool -_mongoc_cyrus_start (mongoc_cyrus_t *sasl, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen, - bson_error_t *error) -{ - const char *service_name = "mongodb"; - const char *service_host = ""; - const char *mechanism = NULL; - const char *raw = NULL; - unsigned raw_len = 0; - int status; - - BSON_ASSERT (sasl); - BSON_ASSERT (outbuf); - BSON_ASSERT (outbufmax); - BSON_ASSERT (outbuflen); - - if (sasl->credentials.service_name) { - service_name = sasl->credentials.service_name; - } - - if (sasl->credentials.service_host) { - service_host = sasl->credentials.service_host; - } - - status = sasl_client_new ( - service_name, service_host, NULL, NULL, sasl->callbacks, 0, &sasl->conn); - TRACE ("Created new sasl client %s", - status == SASL_OK ? "successfully" : "UNSUCCESSFULLY"); - if (_mongoc_cyrus_is_failure (status, error)) { - return false; - } - - status = sasl_client_start (sasl->conn, - sasl->credentials.mechanism, - &sasl->interact, - &raw, - &raw_len, - &mechanism); - TRACE ("Started the sasl client %s", - status == SASL_CONTINUE ? "successfully" : "UNSUCCESSFULLY"); - if (_mongoc_cyrus_is_failure (status, error)) { - return false; - } - - if ((0 != strcasecmp (mechanism, "GSSAPI")) && - (0 != strcasecmp (mechanism, "PLAIN"))) { - bson_set_error (error, - MONGOC_ERROR_SASL, - SASL_NOMECH, - "SASL Failure: invalid mechanism \"%s\"", - mechanism); - return false; - } - - - status = sasl_encode64 (raw, raw_len, (char *) outbuf, outbufmax, outbuflen); - if (_mongoc_cyrus_is_failure (status, error)) { - return false; - } - - return true; -} - - -bool -_mongoc_cyrus_step (mongoc_cyrus_t *sasl, - const uint8_t *inbuf, - uint32_t inbuflen, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen, - bson_error_t *error) -{ - const char *raw = NULL; - unsigned rawlen = 0; - int status; - - BSON_ASSERT (sasl); - BSON_ASSERT (inbuf); - BSON_ASSERT (outbuf); - BSON_ASSERT (outbuflen); - - TRACE ("Running %d, inbuflen: %" PRIu32, sasl->step, inbuflen); - sasl->step++; - - if (sasl->step == 1) { - return _mongoc_cyrus_start (sasl, outbuf, outbufmax, outbuflen, error); - } else if (sasl->step >= 10) { - bson_set_error (error, - MONGOC_ERROR_SASL, - SASL_NOTDONE, - "SASL Failure: maximum steps detected"); - return false; - } - - TRACE ("Running %d, inbuflen: %" PRIu32, sasl->step, inbuflen); - if (!inbuflen) { - bson_set_error (error, - MONGOC_ERROR_SASL, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "SASL Failure: no payload provided from server: %s", - sasl_errdetail (sasl->conn)); - return false; - } - - status = sasl_decode64 ( - (char *) inbuf, inbuflen, (char *) outbuf, outbufmax, outbuflen); - if (_mongoc_cyrus_is_failure (status, error)) { - return false; - } - - TRACE ("%s", "Running client_step"); - status = sasl_client_step ( - sasl->conn, (char *) outbuf, *outbuflen, &sasl->interact, &raw, &rawlen); - TRACE ("%s sent a client step", - status == SASL_OK ? "Successfully" : "UNSUCCESSFULLY"); - if (_mongoc_cyrus_is_failure (status, error)) { - return false; - } - - status = sasl_encode64 (raw, rawlen, (char *) outbuf, outbufmax, outbuflen); - if (_mongoc_cyrus_is_failure (status, error)) { - return false; - } - - return true; -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-database-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-database-private.h deleted file mode 100644 index 53a77e9548961aae57310caf330d2c8c53030b86..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-database-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_DATABASE_PRIVATE_H -#define MONGOC_DATABASE_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-read-concern.h" -#include "mongoc/mongoc-write-concern.h" - -BSON_BEGIN_DECLS - - -struct _mongoc_database_t { - mongoc_client_t *client; - char name[128]; - mongoc_read_prefs_t *read_prefs; - mongoc_read_concern_t *read_concern; - mongoc_write_concern_t *write_concern; -}; - - -mongoc_database_t * -_mongoc_database_new (mongoc_client_t *client, - const char *name, - const mongoc_read_prefs_t *read_prefs, - const mongoc_read_concern_t *read_concern, - const mongoc_write_concern_t *write_concern); - -BSON_END_DECLS - - -#endif /* MONGOC_DATABASE_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-database.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-database.c deleted file mode 100644 index ff60bb76f47c56d03252626548a9318a778cc1f0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-database.c +++ /dev/null @@ -1,1027 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-aggregate-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-database.h" -#include "mongoc/mongoc-database-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-change-stream-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "database" - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_database_new -- - * - * Create a new instance of mongoc_database_t for @client. - * - * @client must stay valid for the life of the resulting - * database structure. - * - * Returns: - * A newly allocated mongoc_database_t that should be freed with - * mongoc_database_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_database_t * -_mongoc_database_new (mongoc_client_t *client, - const char *name, - const mongoc_read_prefs_t *read_prefs, - const mongoc_read_concern_t *read_concern, - const mongoc_write_concern_t *write_concern) -{ - mongoc_database_t *db; - - ENTRY; - - BSON_ASSERT (client); - BSON_ASSERT (name); - - db = (mongoc_database_t *) bson_malloc0 (sizeof *db); - db->client = client; - db->write_concern = write_concern ? mongoc_write_concern_copy (write_concern) - : mongoc_write_concern_new (); - db->read_concern = read_concern ? mongoc_read_concern_copy (read_concern) - : mongoc_read_concern_new (); - db->read_prefs = read_prefs ? mongoc_read_prefs_copy (read_prefs) - : mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - bson_strncpy (db->name, name, sizeof db->name); - - RETURN (db); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_destroy -- - * - * Releases resources associated with @database. - * - * Returns: - * None. - * - * Side effects: - * Everything. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_database_destroy (mongoc_database_t *database) -{ - ENTRY; - - if (!database) { - EXIT; - } - - if (database->read_prefs) { - mongoc_read_prefs_destroy (database->read_prefs); - database->read_prefs = NULL; - } - - if (database->read_concern) { - mongoc_read_concern_destroy (database->read_concern); - database->read_concern = NULL; - } - - if (database->write_concern) { - mongoc_write_concern_destroy (database->write_concern); - database->write_concern = NULL; - } - - bson_free (database); - - EXIT; -} - - -mongoc_cursor_t * -mongoc_database_aggregate (mongoc_database_t *db, /* IN */ - const bson_t *pipeline, /* IN */ - const bson_t *opts, /* IN */ - const mongoc_read_prefs_t *read_prefs) /* IN */ -{ - return _mongoc_aggregate (db->client, - db->name, - MONGOC_QUERY_NONE, - pipeline, - opts, - read_prefs, - db->read_prefs, - db->read_concern, - db->write_concern); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_copy -- - * - * Returns a copy of @database that needs to be freed by calling - * mongoc_database_destroy. - * - * Returns: - * A copy of this database. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_database_t * -mongoc_database_copy (mongoc_database_t *database) -{ - ENTRY; - - BSON_ASSERT (database); - - RETURN (_mongoc_database_new (database->client, - database->name, - database->read_prefs, - database->read_concern, - database->write_concern)); -} - -mongoc_cursor_t * -mongoc_database_command (mongoc_database_t *database, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *command, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs) -{ - char ns[MONGOC_NAMESPACE_MAX]; - - BSON_ASSERT (database); - BSON_ASSERT (command); - - bson_snprintf (ns, sizeof ns, "%s.$cmd", database->name); - - /* Server Selection Spec: "The generic command method has a default read - * preference of mode 'primary'. The generic command method MUST ignore any - * default read preference from client, database or collection - * configuration. The generic command method SHOULD allow an optional read - * preference argument." - */ - - /* flags, skip, limit, batch_size, fields are unused */ - return _mongoc_cursor_cmd_deprecated_new ( - database->client, ns, command, read_prefs); -} - - -bool -mongoc_database_command_simple (mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error) -{ - BSON_ASSERT (database); - BSON_ASSERT (command); - - /* Server Selection Spec: "The generic command method has a default read - * preference of mode 'primary'. The generic command method MUST ignore any - * default read preference from client, database or collection - * configuration. The generic command method SHOULD allow an optional read - * preference argument." - */ - - return _mongoc_client_command_with_opts (database->client, - database->name, - command, - MONGOC_CMD_RAW, - NULL /* opts */, - MONGOC_QUERY_NONE, - read_prefs, - NULL, /* user prefs */ - NULL /* read concern */, - NULL /* write concern */, - reply, - error); -} - - -bool -mongoc_database_read_command_with_opts (mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_client_command_with_opts (database->client, - database->name, - command, - MONGOC_CMD_READ, - opts, - MONGOC_QUERY_NONE, - read_prefs, - database->read_prefs, - database->read_concern, - database->write_concern, - reply, - error); -} - - -bool -mongoc_database_write_command_with_opts (mongoc_database_t *database, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_client_command_with_opts (database->client, - database->name, - command, - MONGOC_CMD_WRITE, - opts, - MONGOC_QUERY_NONE, - NULL, /* user prefs */ - database->read_prefs, - database->read_concern, - database->write_concern, - reply, - error); -} - - -bool -mongoc_database_read_write_command_with_opts ( - mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* IGNORED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_client_command_with_opts (database->client, - database->name, - command, - MONGOC_CMD_RW, - opts, - MONGOC_QUERY_NONE, - read_prefs, - database->read_prefs, - database->read_concern, - database->write_concern, - reply, - error); -} - - -bool -mongoc_database_command_with_opts (mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error) -{ - return _mongoc_client_command_with_opts (database->client, - database->name, - command, - MONGOC_CMD_RAW, - opts, - MONGOC_QUERY_NONE, - read_prefs, - NULL, /* default prefs */ - database->read_concern, - database->write_concern, - reply, - error); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_drop -- - * - * Requests that the MongoDB server drops @database, including all - * collections and indexes associated with @database. - * - * Make sure this is really what you want! - * - * Returns: - * true if @database was dropped. - * - * Side effects: - * @error may be set. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_database_drop (mongoc_database_t *database, bson_error_t *error) -{ - return mongoc_database_drop_with_opts (database, NULL, error); -} - - -bool -mongoc_database_drop_with_opts (mongoc_database_t *database, - const bson_t *opts, - bson_error_t *error) -{ - bool ret; - bson_t cmd; - - BSON_ASSERT (database); - - bson_init (&cmd); - bson_append_int32 (&cmd, "dropDatabase", 12, 1); - - ret = _mongoc_client_command_with_opts (database->client, - database->name, - &cmd, - MONGOC_CMD_WRITE, - opts, - MONGOC_QUERY_NONE, - NULL, /* user prefs */ - database->read_prefs, - database->read_concern, - database->write_concern, - NULL, /* reply */ - error); - bson_destroy (&cmd); - - return ret; -} - - -bool -mongoc_database_remove_user (mongoc_database_t *database, - const char *username, - bson_error_t *error) -{ - bson_t cmd; - bool ret; - - ENTRY; - - BSON_ASSERT (database); - BSON_ASSERT (username); - - bson_init (&cmd); - BSON_APPEND_UTF8 (&cmd, "dropUser", username); - ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error); - bson_destroy (&cmd); - - RETURN (ret); -} - - -bool -mongoc_database_remove_all_users (mongoc_database_t *database, - bson_error_t *error) -{ - bson_t cmd; - bool ret; - - ENTRY; - - BSON_ASSERT (database); - - bson_init (&cmd); - BSON_APPEND_INT32 (&cmd, "dropAllUsersFromDatabase", 1); - ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error); - bson_destroy (&cmd); - - RETURN (ret); -} - - -/** - * mongoc_database_add_user: - * @database: A #mongoc_database_t. - * @username: A string containing the username. - * @password: (allow-none): A string containing password, or NULL. - * @roles: (allow-none): An optional bson_t of roles. - * @custom_data: (allow-none): An optional bson_t of data to store. - * @error: (out) (allow-none): A location for a bson_error_t or %NULL. - * - * Creates a new user with access to @database. - * - * Returns: None. - * Side effects: None. - */ -bool -mongoc_database_add_user (mongoc_database_t *database, - const char *username, - const char *password, - const bson_t *roles, - const bson_t *custom_data, - bson_error_t *error) -{ - bson_t cmd; - bson_t ar; - bool ret = false; - - ENTRY; - - BSON_ASSERT (database); - BSON_ASSERT (username); - - bson_init (&cmd); - BSON_APPEND_UTF8 (&cmd, "createUser", username); - BSON_APPEND_UTF8 (&cmd, "pwd", password); - - if (custom_data) { - BSON_APPEND_DOCUMENT (&cmd, "customData", custom_data); - } - if (roles) { - BSON_APPEND_ARRAY (&cmd, "roles", roles); - } else { - bson_append_array_begin (&cmd, "roles", 5, &ar); - bson_append_array_end (&cmd, &ar); - } - - ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error); - - bson_destroy (&cmd); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_get_read_prefs -- - * - * Fetch the read preferences for @database. - * - * Returns: - * A mongoc_read_prefs_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_read_prefs_t * -mongoc_database_get_read_prefs (const mongoc_database_t *database) /* IN */ -{ - BSON_ASSERT (database); - return database->read_prefs; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_set_read_prefs -- - * - * Sets the default read preferences for @database. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_database_set_read_prefs (mongoc_database_t *database, - const mongoc_read_prefs_t *read_prefs) -{ - BSON_ASSERT (database); - - if (database->read_prefs) { - mongoc_read_prefs_destroy (database->read_prefs); - database->read_prefs = NULL; - } - - if (read_prefs) { - database->read_prefs = mongoc_read_prefs_copy (read_prefs); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_get_read_concern -- - * - * Fetches the read concern for @database. - * - * Returns: - * A mongoc_read_concern_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_read_concern_t * -mongoc_database_get_read_concern (const mongoc_database_t *database) -{ - BSON_ASSERT (database); - - return database->read_concern; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_set_read_concern -- - * - * Set the default read concern for @database. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_database_set_read_concern (mongoc_database_t *database, - const mongoc_read_concern_t *read_concern) -{ - BSON_ASSERT (database); - - if (database->read_concern) { - mongoc_read_concern_destroy (database->read_concern); - database->read_concern = NULL; - } - - if (read_concern) { - database->read_concern = mongoc_read_concern_copy (read_concern); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_get_write_concern -- - * - * Fetches the write concern for @database. - * - * Returns: - * A mongoc_write_concern_t that should not be modified or freed. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_write_concern_t * -mongoc_database_get_write_concern (const mongoc_database_t *database) -{ - BSON_ASSERT (database); - - return database->write_concern; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_database_set_write_concern -- - * - * Set the default write concern for @database. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_database_set_write_concern (mongoc_database_t *database, - const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (database); - - if (database->write_concern) { - mongoc_write_concern_destroy (database->write_concern); - database->write_concern = NULL; - } - - if (write_concern) { - database->write_concern = mongoc_write_concern_copy (write_concern); - } -} - - -/** - * mongoc_database_has_collection: - * @database: (in): A #mongoc_database_t. - * @name: (in): The name of the collection to check for. - * @error: (out) (allow-none): A location for a #bson_error_t, or %NULL. - * - * Checks to see if a collection exists within the database on the MongoDB - * server. - * - * This will return %false if their was an error communicating with the - * server, or if the collection does not exist. - * - * If @error is provided, it will first be zeroed. Upon error, error.domain - * will be set. - * - * Returns: %true if @name exists, otherwise %false. @error may be set. - */ -bool -mongoc_database_has_collection (mongoc_database_t *database, - const char *name, - bson_error_t *error) -{ - bson_iter_t col_iter; - bool ret = false; - const char *cur_name; - bson_t opts = BSON_INITIALIZER; - bson_t filter; - mongoc_cursor_t *cursor; - const bson_t *doc; - - ENTRY; - - BSON_ASSERT (database); - BSON_ASSERT (name); - - if (error) { - memset (error, 0, sizeof *error); - } - - BSON_APPEND_DOCUMENT_BEGIN (&opts, "filter", &filter); - BSON_APPEND_UTF8 (&filter, "name", name); - bson_append_document_end (&opts, &filter); - - cursor = mongoc_database_find_collections_with_opts (database, &opts); - while (mongoc_cursor_next (cursor, &doc)) { - if (bson_iter_init (&col_iter, doc) && - bson_iter_find (&col_iter, "name") && - BSON_ITER_HOLDS_UTF8 (&col_iter) && - (cur_name = bson_iter_utf8 (&col_iter, NULL))) { - if (!strcmp (cur_name, name)) { - ret = true; - GOTO (cleanup); - } - } - } - - (void) mongoc_cursor_error (cursor, error); - -cleanup: - mongoc_cursor_destroy (cursor); - bson_destroy (&opts); - - RETURN (ret); -} - - -mongoc_cursor_t * -mongoc_database_find_collections (mongoc_database_t *database, - const bson_t *filter, - bson_error_t *error) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - - BSON_ASSERT (database); - - if (filter) { - if (!BSON_APPEND_DOCUMENT (&opts, "filter", filter)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'filter' parameter."); - bson_destroy (&opts); - return NULL; - } - } - - cursor = mongoc_database_find_collections_with_opts (database, &opts); - - bson_destroy (&opts); - - /* this deprecated API returns NULL on error */ - if (mongoc_cursor_error (cursor, error)) { - mongoc_cursor_destroy (cursor); - return NULL; - } - - return cursor; -} - - -mongoc_cursor_t * -mongoc_database_find_collections_with_opts (mongoc_database_t *database, - const bson_t *opts) -{ - mongoc_cursor_t *cursor; - bson_t cmd = BSON_INITIALIZER; - - BSON_ASSERT (database); - - BSON_APPEND_INT32 (&cmd, "listCollections", 1); - - /* Enumerate Collections Spec: "run listCollections on the primary node in - * replicaset mode" */ - cursor = _mongoc_cursor_cmd_new ( - database->client, database->name, &cmd, opts, NULL, NULL, NULL); - if (cursor->error.domain == 0) { - _mongoc_cursor_prime (cursor); - } - bson_destroy (&cmd); - - return cursor; -} - - -char ** -mongoc_database_get_collection_names (mongoc_database_t *database, - bson_error_t *error) -{ - return mongoc_database_get_collection_names_with_opts ( - database, NULL, error); -} - - -char ** -mongoc_database_get_collection_names_with_opts (mongoc_database_t *database, - const bson_t *opts, - bson_error_t *error) -{ - bson_t opts_copy; - bson_iter_t col; - const char *name; - char *namecopy; - mongoc_array_t strv_buf; - mongoc_cursor_t *cursor; - const bson_t *doc; - char **ret; - - BSON_ASSERT (database); - - if (opts) { - bson_copy_to (opts, &opts_copy); - } else { - bson_init (&opts_copy); - } - - /* nameOnly option is faster in MongoDB 4+, ignored by older versions, - * see Enumerating Collections Spec */ - if (!bson_has_field (&opts_copy, "nameOnly")) { - bson_append_bool (&opts_copy, "nameOnly", 8, true); - } - - cursor = mongoc_database_find_collections_with_opts (database, &opts_copy); - - _mongoc_array_init (&strv_buf, sizeof (char *)); - - while (mongoc_cursor_next (cursor, &doc)) { - if (bson_iter_init (&col, doc) && bson_iter_find (&col, "name") && - BSON_ITER_HOLDS_UTF8 (&col) && (name = bson_iter_utf8 (&col, NULL))) { - namecopy = bson_strdup (name); - _mongoc_array_append_val (&strv_buf, namecopy); - } - } - - /* append a null pointer for the last value. also handles the case - * of no values. */ - namecopy = NULL; - _mongoc_array_append_val (&strv_buf, namecopy); - - if (mongoc_cursor_error (cursor, error)) { - _mongoc_array_destroy (&strv_buf); - ret = NULL; - } else { - ret = (char **) strv_buf.data; - } - - mongoc_cursor_destroy (cursor); - bson_destroy (&opts_copy); - - return ret; -} - - -mongoc_collection_t * -mongoc_database_create_collection (mongoc_database_t *database, - const char *name, - const bson_t *opts, - bson_error_t *error) -{ - mongoc_collection_t *collection = NULL; - bson_iter_t iter; - bson_t cmd; - bool capped = false; - - BSON_ASSERT (database); - BSON_ASSERT (name); - - if (strchr (name, '$')) { - bson_set_error (error, - MONGOC_ERROR_NAMESPACE, - MONGOC_ERROR_NAMESPACE_INVALID, - "The namespace \"%s\" is invalid.", - name); - return NULL; - } - - if (opts) { - if (bson_iter_init_find (&iter, opts, "capped")) { - if (!BSON_ITER_HOLDS_BOOL (&iter)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The argument \"capped\" must be a boolean."); - return NULL; - } - capped = bson_iter_bool (&iter); - } - - if (bson_iter_init_find (&iter, opts, "size")) { - if (!BSON_ITER_HOLDS_INT (&iter)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The argument \"size\" must be an integer."); - return NULL; - } - if (!capped) { - bson_set_error ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The \"size\" parameter requires {\"capped\": true}"); - return NULL; - } - } - - if (bson_iter_init_find (&iter, opts, "max")) { - if (!BSON_ITER_HOLDS_INT (&iter)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The argument \"max\" must be an integer."); - return NULL; - } - if (!capped) { - bson_set_error ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The \"max\" parameter requires {\"capped\": true}"); - return NULL; - } - } - - if (bson_iter_init_find (&iter, opts, "storageEngine")) { - if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { - bson_set_error ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The \"storageEngine\" parameter must be a document"); - - return NULL; - } - - if (bson_iter_find (&iter, "wiredTiger")) { - if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The \"wiredTiger\" option must take a document " - "argument with a \"configString\" field"); - return NULL; - } - - if (bson_iter_find (&iter, "configString")) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) { - bson_set_error ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The \"configString\" parameter must be a string"); - return NULL; - } - } else { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The \"wiredTiger\" option must take a document " - "argument with a \"configString\" field"); - return NULL; - } - } - } - } - - - bson_init (&cmd); - BSON_APPEND_UTF8 (&cmd, "create", name); - - if (_mongoc_client_command_with_opts (database->client, - database->name, - &cmd, - MONGOC_CMD_WRITE, - opts, - MONGOC_QUERY_NONE, - NULL, /* user prefs */ - database->read_prefs, - database->read_concern, - database->write_concern, - NULL, /* reply */ - error)) { - collection = _mongoc_collection_new (database->client, - database->name, - name, - database->read_prefs, - database->read_concern, - database->write_concern); - } - - bson_destroy (&cmd); - - return collection; -} - - -mongoc_collection_t * -mongoc_database_get_collection (mongoc_database_t *database, - const char *collection) -{ - BSON_ASSERT (database); - BSON_ASSERT (collection); - - return _mongoc_collection_new (database->client, - database->name, - collection, - database->read_prefs, - database->read_concern, - database->write_concern); -} - - -const char * -mongoc_database_get_name (mongoc_database_t *database) -{ - BSON_ASSERT (database); - - return database->name; -} - - -mongoc_change_stream_t * -mongoc_database_watch (const mongoc_database_t *db, - const bson_t *pipeline, - const bson_t *opts) -{ - return _mongoc_change_stream_new_from_database (db, pipeline, opts); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-database.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-database.h deleted file mode 100644 index 08c40cbd4e662a0f4424edfc2f0af582fad36c6e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-database.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_DATABASE_H -#define MONGOC_DATABASE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-flags.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-read-concern.h" -#include "mongoc/mongoc-write-concern.h" - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_database_t mongoc_database_t; - - -MONGOC_EXPORT (const char *) -mongoc_database_get_name (mongoc_database_t *database); -MONGOC_EXPORT (bool) -mongoc_database_remove_user (mongoc_database_t *database, - const char *username, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_remove_all_users (mongoc_database_t *database, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_add_user (mongoc_database_t *database, - const char *username, - const char *password, - const bson_t *roles, - const bson_t *custom_data, - bson_error_t *error); -MONGOC_EXPORT (void) -mongoc_database_destroy (mongoc_database_t *database); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_database_aggregate (mongoc_database_t *db, - const bson_t *pipeline, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (mongoc_database_t *) -mongoc_database_copy (mongoc_database_t *database); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_database_command (mongoc_database_t *database, - mongoc_query_flags_t flags, - uint32_t skip, - uint32_t limit, - uint32_t batch_size, - const bson_t *command, - const bson_t *fields, - const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (bool) -mongoc_database_read_command_with_opts (mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_write_command_with_opts (mongoc_database_t *database, - const bson_t *command, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_read_write_command_with_opts ( - mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs /* IGNORED */, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_command_with_opts (mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - const bson_t *opts, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_command_simple (mongoc_database_t *database, - const bson_t *command, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_drop (mongoc_database_t *database, bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_drop_with_opts (mongoc_database_t *database, - const bson_t *opts, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_database_has_collection (mongoc_database_t *database, - const char *name, - bson_error_t *error); -MONGOC_EXPORT (mongoc_collection_t *) -mongoc_database_create_collection (mongoc_database_t *database, - const char *name, - const bson_t *options, - bson_error_t *error); -MONGOC_EXPORT (const mongoc_read_prefs_t *) -mongoc_database_get_read_prefs (const mongoc_database_t *database); -MONGOC_EXPORT (void) -mongoc_database_set_read_prefs (mongoc_database_t *database, - const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (const mongoc_write_concern_t *) -mongoc_database_get_write_concern (const mongoc_database_t *database); -MONGOC_EXPORT (void) -mongoc_database_set_write_concern (mongoc_database_t *database, - const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (const mongoc_read_concern_t *) -mongoc_database_get_read_concern (const mongoc_database_t *database); -MONGOC_EXPORT (void) -mongoc_database_set_read_concern (mongoc_database_t *database, - const mongoc_read_concern_t *read_concern); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_database_find_collections (mongoc_database_t *database, - const bson_t *filter, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_database_find_collections_with_opts); -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_database_find_collections_with_opts (mongoc_database_t *database, - const bson_t *opts); -MONGOC_EXPORT (char **) -mongoc_database_get_collection_names (mongoc_database_t *database, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_database_get_collection_names_with_opts); -MONGOC_EXPORT (char **) -mongoc_database_get_collection_names_with_opts (mongoc_database_t *database, - const bson_t *opts, - bson_error_t *error); -MONGOC_EXPORT (mongoc_collection_t *) -mongoc_database_get_collection (mongoc_database_t *database, const char *name); -MONGOC_EXPORT (mongoc_change_stream_t *) -mongoc_database_watch (const mongoc_database_t *db, - const bson_t *pipeline, - const bson_t *opts); - -BSON_END_DECLS - - -#endif /* MONGOC_DATABASE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-errno-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-errno-private.h deleted file mode 100644 index 254f2b11518207857c10e23a497656d2465cdf9f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-errno-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_ERRNO_PRIVATE_H -#define MONGOC_ERRNO_PRIVATE_H - -#include <bson/bson.h> -#include <errno.h> -#ifdef _WIN32 -#include <winsock2.h> -#include <winerror.h> -#endif - - -BSON_BEGIN_DECLS - - -#if defined(_WIN32) -#define MONGOC_ERRNO_IS_AGAIN(errno) \ - ((errno == EAGAIN) || (errno == WSAEWOULDBLOCK) || (errno == WSAEINPROGRESS)) -#define MONGOC_ERRNO_IS_TIMEDOUT(errno) (errno == WSAETIMEDOUT) -#elif defined(__sun) -/* for some reason, accept() returns -1 and errno of 0 */ -#define MONGOC_ERRNO_IS_AGAIN(errno) \ - ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK) || \ - (errno == EINPROGRESS) || (errno == 0)) -#define MONGOC_ERRNO_IS_TIMEDOUT(errno) (errno == ETIMEDOUT) -#else -#define MONGOC_ERRNO_IS_AGAIN(errno) \ - ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK) || \ - (errno == EINPROGRESS)) -#define MONGOC_ERRNO_IS_TIMEDOUT(errno) (errno == ETIMEDOUT) -#endif - - -BSON_END_DECLS - - -#endif /* MONGOC_ERRNO_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-error-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-error-private.h deleted file mode 100644 index 7c690d8974377acaf13abe09090cdae56940d6cd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-error-private.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#include <bson/bson.h> -#include <stddef.h> - -BSON_BEGIN_DECLS - -typedef enum { - MONGOC_READ_ERR_NONE, - MONGOC_READ_ERR_OTHER, - MONGOC_READ_ERR_RETRY, -} mongoc_read_err_type_t; - -mongoc_read_err_type_t -_mongoc_read_error_get_type (bool cmd_ret, - const bson_error_t *cmd_err, - const bson_t *reply); - -BSON_END_DECLS \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-error.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-error.c deleted file mode 100644 index e8c1ea6866d307b7128d169be9508ce31bdd3113..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-error.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2018-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 <bson/bson.h> - -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-error-private.h" -#include "mongoc/mongoc-rpc-private.h" - -bool -mongoc_error_has_label (const bson_t *reply, const char *label) -{ - bson_iter_t iter; - bson_iter_t error_labels; - - BSON_ASSERT (reply); - BSON_ASSERT (label); - - if (bson_iter_init_find (&iter, reply, "errorLabels") && - bson_iter_recurse (&iter, &error_labels)) { - while (bson_iter_next (&error_labels)) { - if (BSON_ITER_HOLDS_UTF8 (&error_labels) && - !strcmp (bson_iter_utf8 (&error_labels, NULL), label)) { - return true; - } - } - } - - return false; -} - - -/*-------------------------------------------------------------------------- - * - * _mongoc_read_error_get_type -- - * - * Checks if the error or reply from a read command is considered - * retryable according to the retryable reads spec. Checks both - * for a client error (a network exception) and a server error in - * the reply. @cmd_ret and @cmd_err come from the result of a - * read_command function. - * - * - * Return: - * A mongoc_read_error_type_t indicating the type of error (if any). - * - *-------------------------------------------------------------------------- - */ -mongoc_read_err_type_t -_mongoc_read_error_get_type (bool cmd_ret, - const bson_error_t *cmd_err, - const bson_t *reply) -{ - bson_error_t error; - - /* check for a client error. */ - if (!cmd_ret && cmd_err && cmd_err->domain == MONGOC_ERROR_STREAM) { - /* Retryable reads spec: "considered retryable if [...] any network - * exception (e.g. socket timeout or error) */ - return MONGOC_READ_ERR_RETRY; - } - - /* check for a server error. */ - if (_mongoc_cmd_check_ok_no_wce ( - reply, MONGOC_ERROR_API_VERSION_2, &error)) { - return MONGOC_READ_ERR_NONE; - } - - switch (error.code) { - case 11600: /* InterruptedAtShutdown */ - case 11602: /* InterruptedDueToReplStateChange */ - case 10107: /* NotMaster */ - case 13435: /* NotMasterNoSlaveOk */ - case 13436: /* NotMasterOrSecondary */ - case 189: /* PrimarySteppedDown */ - case 91: /* ShutdownInProgress */ - case 7: /* HostNotFound */ - case 6: /* HostUnreachable */ - case 89: /* NetworkTimeout */ - case 9001: /* SocketException */ - return MONGOC_READ_ERR_RETRY; - default: - if (strstr (error.message, "not master") || - strstr (error.message, "node is recovering")) { - return MONGOC_READ_ERR_RETRY; - } - return MONGOC_READ_ERR_OTHER; - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-error.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-error.h deleted file mode 100644 index 36cbfa58c891ece50688c00949185f6ac1bc8c9a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-error.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_ERRORS_H -#define MONGOC_ERRORS_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -#define MONGOC_ERROR_API_VERSION_LEGACY 1 -#define MONGOC_ERROR_API_VERSION_2 2 - -BSON_BEGIN_DECLS - - -typedef enum { - MONGOC_ERROR_CLIENT = 1, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_QUERY, - MONGOC_ERROR_INSERT, - MONGOC_ERROR_SASL, - MONGOC_ERROR_BSON, - MONGOC_ERROR_MATCHER, - MONGOC_ERROR_NAMESPACE, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COLLECTION, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_WRITE_CONCERN, - MONGOC_ERROR_SERVER, /* Error API Version 2 only */ - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION, /* An error coming from libmongocrypt */ -} mongoc_error_domain_t; - - -typedef enum { - MONGOC_ERROR_STREAM_INVALID_TYPE = 1, - MONGOC_ERROR_STREAM_INVALID_STATE, - MONGOC_ERROR_STREAM_NAME_RESOLUTION, - MONGOC_ERROR_STREAM_SOCKET, - MONGOC_ERROR_STREAM_CONNECT, - MONGOC_ERROR_STREAM_NOT_ESTABLISHED, - - MONGOC_ERROR_CLIENT_NOT_READY, - MONGOC_ERROR_CLIENT_TOO_BIG, - MONGOC_ERROR_CLIENT_TOO_SMALL, - MONGOC_ERROR_CLIENT_GETNONCE, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER, - MONGOC_ERROR_CLIENT_IN_EXHAUST, - - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - - MONGOC_ERROR_QUERY_FAILURE, - - MONGOC_ERROR_BSON_INVALID, - - MONGOC_ERROR_MATCHER_INVALID, - - MONGOC_ERROR_NAMESPACE_INVALID, - MONGOC_ERROR_NAMESPACE_INVALID_FILTER_TYPE, - - MONGOC_ERROR_COMMAND_INVALID_ARG, - - MONGOC_ERROR_COLLECTION_INSERT_FAILED, - MONGOC_ERROR_COLLECTION_UPDATE_FAILED, - MONGOC_ERROR_COLLECTION_DELETE_FAILED, - MONGOC_ERROR_COLLECTION_DOES_NOT_EXIST = 26, - - MONGOC_ERROR_GRIDFS_INVALID_FILENAME, - - MONGOC_ERROR_SCRAM_NOT_DONE, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - - MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND = 59, - MONGOC_ERROR_QUERY_NOT_TAILABLE = 13051, - - MONGOC_ERROR_SERVER_SELECTION_BAD_WIRE_VERSION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - MONGOC_ERROR_SERVER_SELECTION_INVALID_ID, - - MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - MONGOC_ERROR_GRIDFS_PROTOCOL_ERROR, - - /* Dup with query failure. */ - MONGOC_ERROR_PROTOCOL_ERROR = 17, - - MONGOC_ERROR_WRITE_CONCERN_ERROR = 64, - - MONGOC_ERROR_DUPLICATE_KEY = 11000, - - MONGOC_ERROR_MAX_TIME_MS_EXPIRED = 50, - - MONGOC_ERROR_CHANGE_STREAM_NO_RESUME_TOKEN, - MONGOC_ERROR_CLIENT_SESSION_FAILURE, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - MONGOC_ERROR_GRIDFS_CORRUPT, - MONGOC_ERROR_GRIDFS_BUCKET_FILE_NOT_FOUND, - MONGOC_ERROR_GRIDFS_BUCKET_STREAM, - - /* An error related to initializing client side encryption. */ - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE, - MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG -} mongoc_error_code_t; - -MONGOC_EXPORT (bool) -mongoc_error_has_label (const bson_t *reply, const char *label); - -BSON_END_DECLS - - -#endif /* MONGOC_ERRORS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify-private.h deleted file mode 100644 index 1f346e2d08b9a504bb115f5a91f5ec31528b6003..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify-private.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_FIND_AND_MODIFY_PRIVATE_H -#define MONGOC_FIND_AND_MODIFY_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-write-command-private.h" - -BSON_BEGIN_DECLS - -struct _mongoc_find_and_modify_opts_t { - bson_t *sort; - bson_t *update; - bson_t *fields; - mongoc_find_and_modify_flags_t flags; - bool bypass_document_validation; - uint32_t max_time_ms; - bson_t extra; -}; - - -BSON_END_DECLS - - -#endif /* MONGOC_FIND_AND_MODIFY_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify.c deleted file mode 100644 index f59467ba507284aae7409120b6d906c96751dfb8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-find-and-modify.h" -#include "mongoc/mongoc-find-and-modify-private.h" -#include "mongoc/mongoc-util-private.h" - - -/** - * mongoc_find_and_modify_new: - * - * Create a new mongoc_find_and_modify_t. - * - * Returns: A newly allocated mongoc_find_and_modify_t. This should be freed - * with mongoc_find_and_modify_destroy(). - */ -mongoc_find_and_modify_opts_t * -mongoc_find_and_modify_opts_new (void) -{ - mongoc_find_and_modify_opts_t *opts = NULL; - - opts = (mongoc_find_and_modify_opts_t *) bson_malloc0 (sizeof *opts); - bson_init (&opts->extra); - opts->bypass_document_validation = false; - - return opts; -} - -bool -mongoc_find_and_modify_opts_set_sort (mongoc_find_and_modify_opts_t *opts, - const bson_t *sort) -{ - BSON_ASSERT (opts); - - if (sort) { - bson_destroy (opts->sort); - opts->sort = bson_copy (sort); - return true; - } - - return false; -} - -void -mongoc_find_and_modify_opts_get_sort (const mongoc_find_and_modify_opts_t *opts, - bson_t *sort) -{ - BSON_ASSERT (opts); - BSON_ASSERT (sort); - - if (opts->sort) { - bson_copy_to (opts->sort, sort); - } else { - bson_init (sort); - } -} - -bool -mongoc_find_and_modify_opts_set_update (mongoc_find_and_modify_opts_t *opts, - const bson_t *update) -{ - BSON_ASSERT (opts); - - if (update) { - bson_destroy (opts->update); - opts->update = bson_copy (update); - return true; - } - - return false; -} - -void -mongoc_find_and_modify_opts_get_update ( - const mongoc_find_and_modify_opts_t *opts, bson_t *update) -{ - BSON_ASSERT (opts); - BSON_ASSERT (update); - - if (opts->update) { - bson_copy_to (opts->update, update); - } else { - bson_init (update); - } -} - -bool -mongoc_find_and_modify_opts_set_fields (mongoc_find_and_modify_opts_t *opts, - const bson_t *fields) -{ - BSON_ASSERT (opts); - - if (fields) { - bson_destroy (opts->fields); - opts->fields = bson_copy (fields); - return true; - } - - return false; -} - -void -mongoc_find_and_modify_opts_get_fields ( - const mongoc_find_and_modify_opts_t *opts, bson_t *fields) -{ - BSON_ASSERT (opts); - BSON_ASSERT (fields); - - if (opts->fields) { - bson_copy_to (opts->fields, fields); - } else { - bson_init (fields); - } -} - -bool -mongoc_find_and_modify_opts_set_flags ( - mongoc_find_and_modify_opts_t *opts, - const mongoc_find_and_modify_flags_t flags) -{ - BSON_ASSERT (opts); - - opts->flags = flags; - return true; -} - -mongoc_find_and_modify_flags_t -mongoc_find_and_modify_opts_get_flags ( - const mongoc_find_and_modify_opts_t *opts) -{ - BSON_ASSERT (opts); - - return opts->flags; -} - -bool -mongoc_find_and_modify_opts_set_bypass_document_validation ( - mongoc_find_and_modify_opts_t *opts, bool bypass) -{ - BSON_ASSERT (opts); - - opts->bypass_document_validation = bypass; - return true; -} - -bool -mongoc_find_and_modify_opts_get_bypass_document_validation ( - const mongoc_find_and_modify_opts_t *opts) -{ - BSON_ASSERT (opts); - - return opts->bypass_document_validation; -} - -bool -mongoc_find_and_modify_opts_set_max_time_ms ( - mongoc_find_and_modify_opts_t *opts, uint32_t max_time_ms) -{ - BSON_ASSERT (opts); - - opts->max_time_ms = max_time_ms; - return true; -} - -uint32_t -mongoc_find_and_modify_opts_get_max_time_ms ( - const mongoc_find_and_modify_opts_t *opts) -{ - BSON_ASSERT (opts); - - return opts->max_time_ms; -} - -bool -mongoc_find_and_modify_opts_append (mongoc_find_and_modify_opts_t *opts, - const bson_t *extra) -{ - BSON_ASSERT (opts); - BSON_ASSERT (extra); - - return bson_concat (&opts->extra, extra); -} - -void -mongoc_find_and_modify_opts_get_extra ( - const mongoc_find_and_modify_opts_t *opts, bson_t *extra) -{ - BSON_ASSERT (opts); - BSON_ASSERT (extra); - - bson_copy_to (&opts->extra, extra); -} - -/** - * mongoc_find_and_modify_opts_destroy: - * @opts: A mongoc_find_and_modify_opts_t. - * - * Releases a mongoc_find_and_modify_opts_t and all associated memory. - */ -void -mongoc_find_and_modify_opts_destroy (mongoc_find_and_modify_opts_t *opts) -{ - if (opts) { - bson_destroy (opts->sort); - bson_destroy (opts->update); - bson_destroy (opts->fields); - bson_destroy (&opts->extra); - bson_free (opts); - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify.h deleted file mode 100644 index 6a4f4e58827ca0f0f1a5eda8be61ac0dbb47db49..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-find-and-modify.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_FIND_AND_MODIFY_H -#define MONGOC_FIND_AND_MODIFY_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -typedef enum { - MONGOC_FIND_AND_MODIFY_NONE = 0, - MONGOC_FIND_AND_MODIFY_REMOVE = 1 << 0, - MONGOC_FIND_AND_MODIFY_UPSERT = 1 << 1, - MONGOC_FIND_AND_MODIFY_RETURN_NEW = 1 << 2, -} mongoc_find_and_modify_flags_t; - -typedef struct _mongoc_find_and_modify_opts_t mongoc_find_and_modify_opts_t; - -MONGOC_EXPORT (mongoc_find_and_modify_opts_t *) -mongoc_find_and_modify_opts_new (void); - -MONGOC_EXPORT (bool) -mongoc_find_and_modify_opts_set_sort (mongoc_find_and_modify_opts_t *opts, - const bson_t *sort); - -MONGOC_EXPORT (void) -mongoc_find_and_modify_opts_get_sort (const mongoc_find_and_modify_opts_t *opts, - bson_t *sort); - -MONGOC_EXPORT (bool) -mongoc_find_and_modify_opts_set_update (mongoc_find_and_modify_opts_t *opts, - const bson_t *update); - -MONGOC_EXPORT (void) -mongoc_find_and_modify_opts_get_update ( - const mongoc_find_and_modify_opts_t *opts, bson_t *update); - -MONGOC_EXPORT (bool) -mongoc_find_and_modify_opts_set_fields (mongoc_find_and_modify_opts_t *opts, - const bson_t *fields); - -MONGOC_EXPORT (void) -mongoc_find_and_modify_opts_get_fields ( - const mongoc_find_and_modify_opts_t *opts, bson_t *fields); - -MONGOC_EXPORT (bool) -mongoc_find_and_modify_opts_set_flags ( - mongoc_find_and_modify_opts_t *opts, - const mongoc_find_and_modify_flags_t flags); - -MONGOC_EXPORT (mongoc_find_and_modify_flags_t) -mongoc_find_and_modify_opts_get_flags ( - const mongoc_find_and_modify_opts_t *opts); - -MONGOC_EXPORT (bool) -mongoc_find_and_modify_opts_set_bypass_document_validation ( - mongoc_find_and_modify_opts_t *opts, bool bypass); - -MONGOC_EXPORT (bool) -mongoc_find_and_modify_opts_get_bypass_document_validation ( - const mongoc_find_and_modify_opts_t *opts); - -MONGOC_EXPORT (bool) -mongoc_find_and_modify_opts_set_max_time_ms ( - mongoc_find_and_modify_opts_t *opts, uint32_t max_time_ms); - -MONGOC_EXPORT (uint32_t) -mongoc_find_and_modify_opts_get_max_time_ms ( - const mongoc_find_and_modify_opts_t *opts); - -MONGOC_EXPORT (bool) -mongoc_find_and_modify_opts_append (mongoc_find_and_modify_opts_t *opts, - const bson_t *extra); - -MONGOC_EXPORT (void) -mongoc_find_and_modify_opts_get_extra ( - const mongoc_find_and_modify_opts_t *opts, bson_t *extra); - -MONGOC_EXPORT (void) -mongoc_find_and_modify_opts_destroy (mongoc_find_and_modify_opts_t *opts); - -BSON_END_DECLS - - -#endif /* MONGOC_FIND_AND_MODIFY_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-flags.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-flags.h deleted file mode 100644 index cd0ec34e44a96c65cbda0a282d3cd8e949b13da1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-flags.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_FLAGS_H -#define MONGOC_FLAGS_H - -#include <bson/bson.h> - - -BSON_BEGIN_DECLS - - -/** - * mongoc_delete_flags_t: - * @MONGOC_DELETE_NONE: Specify no delete flags. - * @MONGOC_DELETE_SINGLE_REMOVE: Only remove the first document matching the - * document selector. - * - * This type is only for use with deprecated functions and should not be - * used in new code. Use mongoc_remove_flags_t instead. - * - * #mongoc_delete_flags_t are used when performing a delete operation. - */ -typedef enum { - MONGOC_DELETE_NONE = 0, - MONGOC_DELETE_SINGLE_REMOVE = 1 << 0, -} mongoc_delete_flags_t; - - -/** - * mongoc_remove_flags_t: - * @MONGOC_REMOVE_NONE: Specify no delete flags. - * @MONGOC_REMOVE_SINGLE_REMOVE: Only remove the first document matching the - * document selector. - * - * #mongoc_remove_flags_t are used when performing a remove operation. - */ -typedef enum { - MONGOC_REMOVE_NONE = 0, - MONGOC_REMOVE_SINGLE_REMOVE = 1 << 0, -} mongoc_remove_flags_t; - - -/** - * mongoc_insert_flags_t: - * @MONGOC_INSERT_NONE: Specify no insert flags. - * @MONGOC_INSERT_CONTINUE_ON_ERROR: Continue inserting documents from - * the insertion set even if one fails. - * - * #mongoc_insert_flags_t are used when performing an insert operation. - */ -typedef enum { - MONGOC_INSERT_NONE = 0, - MONGOC_INSERT_CONTINUE_ON_ERROR = 1 << 0, -} mongoc_insert_flags_t; - - -#define MONGOC_INSERT_NO_VALIDATE (1U << 31) - - -/** - * mongoc_query_flags_t: - * @MONGOC_QUERY_NONE: No query flags supplied. - * @MONGOC_QUERY_TAILABLE_CURSOR: Cursor will not be closed when the last - * data is retrieved. You can resume this cursor later. - * @MONGOC_QUERY_SLAVE_OK: Allow query of replica slave. - * @MONGOC_QUERY_OPLOG_REPLAY: Used internally by Mongo. - * @MONGOC_QUERY_NO_CURSOR_TIMEOUT: The server normally times out idle - * cursors after an inactivity period (10 minutes). This prevents that. - * @MONGOC_QUERY_AWAIT_DATA: Use with %MONGOC_QUERY_TAILABLE_CURSOR. Block - * rather than returning no data. After a period, time out. - * @MONGOC_QUERY_EXHAUST: Stream the data down full blast in multiple - * "more" packages. Faster when you are pulling a lot of data and - * know you want to pull it all down. - * @MONGOC_QUERY_PARTIAL: Get partial results from mongos if some shards - * are down (instead of throwing an error). - * - * #mongoc_query_flags_t is used for querying a Mongo instance. - */ -typedef enum { - MONGOC_QUERY_NONE = 0, - MONGOC_QUERY_TAILABLE_CURSOR = 1 << 1, - MONGOC_QUERY_SLAVE_OK = 1 << 2, - MONGOC_QUERY_OPLOG_REPLAY = 1 << 3, - MONGOC_QUERY_NO_CURSOR_TIMEOUT = 1 << 4, - MONGOC_QUERY_AWAIT_DATA = 1 << 5, - MONGOC_QUERY_EXHAUST = 1 << 6, - MONGOC_QUERY_PARTIAL = 1 << 7, -} mongoc_query_flags_t; - - -/** - * mongoc_reply_flags_t: - * @MONGOC_REPLY_NONE: No flags set. - * @MONGOC_REPLY_CURSOR_NOT_FOUND: Cursor was not found. - * @MONGOC_REPLY_QUERY_FAILURE: Query failed, error document provided. - * @MONGOC_REPLY_SHARD_CONFIG_STALE: Shard configuration is stale. - * @MONGOC_REPLY_AWAIT_CAPABLE: Wait for data to be returned until timeout - * has passed. Used with %MONGOC_QUERY_TAILABLE_CURSOR. - * - * #mongoc_reply_flags_t contains flags supplied by the Mongo server in reply - * to a request. - */ -typedef enum { - MONGOC_REPLY_NONE = 0, - MONGOC_REPLY_CURSOR_NOT_FOUND = 1 << 0, - MONGOC_REPLY_QUERY_FAILURE = 1 << 1, - MONGOC_REPLY_SHARD_CONFIG_STALE = 1 << 2, - MONGOC_REPLY_AWAIT_CAPABLE = 1 << 3, -} mongoc_reply_flags_t; - - -/** - * mongoc_update_flags_t: - * @MONGOC_UPDATE_NONE: No update flags specified. - * @MONGOC_UPDATE_UPSERT: Perform an upsert. - * @MONGOC_UPDATE_MULTI_UPDATE: Continue updating after first match. - * - * #mongoc_update_flags_t is used when updating documents found in Mongo. - */ -typedef enum { - MONGOC_UPDATE_NONE = 0, - MONGOC_UPDATE_UPSERT = 1 << 0, - MONGOC_UPDATE_MULTI_UPDATE = 1 << 1, -} mongoc_update_flags_t; - - -#define MONGOC_UPDATE_NO_VALIDATE (1U << 31) - - -BSON_END_DECLS - - -#endif /* MONGOC_FLAGS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h deleted file mode 100644 index e02da8f6c70410e99664a786141c43e53bc1599c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_BUCKET_FILE_PRIVATE_H -#define MONGOC_GRIDFS_BUCKET_FILE_PRIVATE_H - -#include "bson/bson.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-gridfs-bucket.h" - -BSON_BEGIN_DECLS - -typedef struct { - /* corresponding bucket */ - mongoc_gridfs_bucket_t *bucket; - - /* file data */ - char *filename; - bson_value_t *file_id; - bson_t *metadata; - int32_t chunk_size; - int64_t length; - - /* fields for reading and writing */ - uint8_t *buffer; - size_t in_buffer; - int32_t curr_chunk; - - /* for writing */ - bool saved; - - /* for reading */ - mongoc_cursor_t *cursor; - int32_t bytes_read; - bool finished; - - /* Error */ - bson_error_t err; -} mongoc_gridfs_bucket_file_t; - -ssize_t -_mongoc_gridfs_bucket_file_writev (mongoc_gridfs_bucket_file_t *file, - const mongoc_iovec_t *iov, - size_t iovcnt); - -ssize_t -_mongoc_gridfs_bucket_file_readv (mongoc_gridfs_bucket_file_t *file, - mongoc_iovec_t *iov, - size_t iovcnt); - -bool -_mongoc_gridfs_bucket_file_save (mongoc_gridfs_bucket_file_t *file); - -void -_mongoc_gridfs_bucket_file_destroy (mongoc_gridfs_bucket_file_t *file); - -BSON_END_DECLS - -#endif /* MONGOC_GRIDFS_BUCKET_FILE_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c deleted file mode 100644 index 81c16eab8d2f621498ebf149b7b880bd2d1f2be1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc.h" -#include "mongoc-gridfs-bucket-file-private.h" -#include "mongoc-gridfs-bucket-private.h" -#include "mongoc-trace-private.h" -#include "mongoc-stream-gridfs-download-private.h" -#include "mongoc-stream-gridfs-upload-private.h" - -/* Returns the minimum of two numbers */ -static size_t -_mongoc_min (const size_t a, const size_t b) -{ - return a < b ? a : b; -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_create_index_if_not_present -- - * - * Creates an index in the given collection if it doesn't exist. - * - * Return: - * True if the index was already present or was successfully created. - * False if an error occurred while trying to create the index. - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_create_index_if_not_present (mongoc_collection_t *col, - const bson_t *index, - bool unique, - bson_error_t *error) -{ - mongoc_cursor_t *cursor; - bool index_exists; - bool r; - const bson_t *doc; - bson_iter_t iter; - bson_t inner_doc; - char *index_name; - bson_t index_command; - uint32_t data_len; - const uint8_t *data; - - BSON_ASSERT (col); - BSON_ASSERT (index); - - cursor = mongoc_collection_find_indexes_with_opts (col, NULL); - - index_exists = false; - - while (mongoc_cursor_next (cursor, &doc)) { - r = bson_iter_init_find (&iter, doc, "key"); - if (!r) { - continue; - } - bson_iter_document (&iter, &data_len, &data); - bson_init_static (&inner_doc, data, data_len); - if (bson_compare (&inner_doc, index) == 0) { - index_exists = true; - } - bson_destroy (&inner_doc); - } - - mongoc_cursor_destroy (cursor); - - if (index_exists) { - return true; - } - - index_name = mongoc_collection_keys_to_index_string (index); - bson_init (&index_command); - BCON_APPEND (&index_command, - "createIndexes", - BCON_UTF8 (mongoc_collection_get_name (col)), - "indexes", - "[", - "{", - "key", - BCON_DOCUMENT (index), - "name", - BCON_UTF8 (index_name), - "unique", - BCON_BOOL (unique), - "}", - "]"); - - r = mongoc_collection_write_command_with_opts ( - col, &index_command, NULL, NULL, error); - bson_destroy (&index_command); - bson_free (index_name); - if (!r) { - return false; - } - - - return true; -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_gridfs_bucket_create_indexes -- - * - * Creates the indexes needed for GridFS on the 'files' and 'chunks' - * collections. - * - * Return: - * True if creating the indexes was successful, otherwise returns - * false. - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_gridfs_bucket_create_indexes (mongoc_gridfs_bucket_t *bucket, - bson_error_t *error) -{ - mongoc_read_prefs_t *prefs; - bson_t filter; - bson_t opts; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t files_index; - bson_t chunks_index; - bool r; - - /* Check to see if there already exists a document in the files collection */ - bson_init (&filter); - bson_append_int32 (&filter, "_id", 3, 1); - bson_init (&opts); - bson_append_bool (&opts, "singleBatch", 11, true); - bson_append_int32 (&opts, "limit", 5, 1); - prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - cursor = - mongoc_collection_find_with_opts (bucket->files, &filter, &opts, prefs); - bson_destroy (&filter); - bson_destroy (&opts); - - r = mongoc_cursor_next (cursor, &doc); - - mongoc_read_prefs_destroy (prefs); - if (r) { - /* Files exist */ - mongoc_cursor_destroy (cursor); - return true; - } else if (mongoc_cursor_error (cursor, error)) { - mongoc_cursor_destroy (cursor); - return false; - } - mongoc_cursor_destroy (cursor); - - /* Create files index */ - bson_init (&files_index); - BSON_APPEND_INT32 (&files_index, "filename", 1); - BSON_APPEND_INT32 (&files_index, "uploadDate", 1); - r = _mongoc_create_index_if_not_present ( - bucket->files, &files_index, false, error); - bson_destroy (&files_index); - if (!r) { - return false; - } - - /* Create unique chunks index */ - bson_init (&chunks_index); - BSON_APPEND_INT32 (&chunks_index, "files_id", 1); - BSON_APPEND_INT32 (&chunks_index, "n", 1); - r = _mongoc_create_index_if_not_present ( - bucket->chunks, &chunks_index, true, error); - bson_destroy (&chunks_index); - if (!r) { - return false; - } - - return true; -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_gridfs_bucket_write_chunk -- - * - * Writes a chunk from the buffer into the chunks collection. - * - * Return: - * Returns true if the chunk was successfully written. Otherwise, - * returns false and sets an error on the bucket file. - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_gridfs_bucket_write_chunk (mongoc_gridfs_bucket_file_t *file) -{ - bson_t chunk; - bool r; - - BSON_ASSERT (file); - - bson_init (&chunk); - - BSON_APPEND_INT32 (&chunk, "n", file->curr_chunk); - BSON_APPEND_VALUE (&chunk, "files_id", file->file_id); - BSON_APPEND_BINARY (&chunk, - "data", - BSON_SUBTYPE_BINARY, - file->buffer, - (uint32_t) file->in_buffer); - - - r = mongoc_collection_insert_one (file->bucket->chunks, - &chunk, - NULL /* opts */, - NULL /* reply */, - &file->err); - bson_destroy (&chunk); - if (!r) { - return false; - } - - file->curr_chunk++; - file->in_buffer = 0; - return true; -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_gridfs_bucket_init_cursor -- - * - * Initializes the cursor at file->cursor for the given file. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_gridfs_bucket_init_cursor (mongoc_gridfs_bucket_file_t *file) -{ - bson_t filter; - bson_t opts; - bson_t sort; - - BSON_ASSERT (file); - - bson_init (&filter); - bson_init (&opts); - bson_init (&sort); - - BSON_APPEND_VALUE (&filter, "files_id", file->file_id); - BSON_APPEND_INT32 (&sort, "n", 1); - BSON_APPEND_DOCUMENT (&opts, "sort", &sort); - - file->cursor = mongoc_collection_find_with_opts ( - file->bucket->chunks, &filter, &opts, NULL); - - bson_destroy (&filter); - bson_destroy (&opts); - bson_destroy (&sort); -} - -/*-------------------------------------------------------------------------- - * - * _mongoc_gridfs_bucket_read_chunk -- - * - * Reads a chunk from the server and places it into the file's buffer - * - * Return: - * True if the buffer has been filled with any available data. - * Otherwise, false and sets the error on the bucket file. - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_gridfs_bucket_read_chunk (mongoc_gridfs_bucket_file_t *file) -{ - const bson_t *next; - bool r; - bson_iter_t iter; - int32_t n; - const uint8_t *data; - uint32_t data_len; - int64_t total_chunks; - int64_t expected_size; - - BSON_ASSERT (file); - - if (file->length == 0) { - /* This file has zero length */ - file->in_buffer = 0; - file->finished = true; - return true; - } - - /* Calculate the total number of chunks for this file */ - total_chunks = (file->length / file->chunk_size); - if (file->length % file->chunk_size != 0) { - total_chunks++; - } - - if (file->curr_chunk == total_chunks) { - /* All chunks have been read! */ - file->in_buffer = 0; - file->finished = true; - return true; - } - - if (file->cursor == NULL) { - _mongoc_gridfs_bucket_init_cursor (file); - } - - r = mongoc_cursor_next (file->cursor, &next); - - if (mongoc_cursor_error (file->cursor, &file->err)) { - return false; - } - - if (!r) { - bson_set_error (&file->err, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - "Missing chunk %d.", - file->curr_chunk); - return false; - } - - r = bson_iter_init_find (&iter, next, "n"); - if (!r) { - bson_set_error (&file->err, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CORRUPT, - "Chunk %d missing a required field 'n'.", - file->curr_chunk); - return false; - } - - n = bson_iter_int32 (&iter); - - if (n != file->curr_chunk) { - bson_set_error (&file->err, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - "Missing chunk %d.", - file->curr_chunk); - return false; - } - - r = bson_iter_init_find (&iter, next, "data"); - if (!r) { - bson_set_error (&file->err, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CORRUPT, - "Chunk %d missing a required field 'data'.", - file->curr_chunk); - return false; - } - - bson_iter_binary (&iter, NULL, &data_len, &data); - - /* Assert that the data is the correct length */ - if (file->curr_chunk != total_chunks - 1) { - expected_size = file->chunk_size; - } else { - expected_size = file->length - ((total_chunks - 1) * file->chunk_size); - } - - if (data_len != expected_size) { - bson_set_error (&file->err, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CORRUPT, - "Chunk %d expected to have size %" PRId64 - " but is size %d.", - file->curr_chunk, - expected_size, - data_len); - return false; - } - - memcpy (file->buffer, data, data_len); - file->in_buffer = data_len; - file->bytes_read = 0; - file->curr_chunk++; - - return true; -} - -ssize_t -_mongoc_gridfs_bucket_file_writev (mongoc_gridfs_bucket_file_t *file, - const mongoc_iovec_t *iov, - size_t iovcnt) -{ - uint32_t total; - size_t bytes_available; - size_t space_available; - int32_t written_this_iov; - size_t to_write; - size_t i; - bool r; - - BSON_ASSERT (file); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - total = 0; - - if (file->err.code) { - return -1; - } - - if (file->saved) { - bson_set_error (&file->err, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_PROTOCOL_ERROR, - "Cannot write after saving/aborting on a GridFS file."); - return -1; - } - - if (!file->bucket->indexed) { - r = _mongoc_gridfs_bucket_create_indexes (file->bucket, &file->err); - if (!r) { - /* Error is set on file. */ - return -1; - } else { - file->bucket->indexed = true; - } - } - - for (i = 0; i < iovcnt; i++) { - written_this_iov = 0; - - while (written_this_iov < iov[i].iov_len) { - bytes_available = iov[i].iov_len - written_this_iov; - space_available = file->chunk_size - file->in_buffer; - to_write = _mongoc_min (bytes_available, space_available); - memcpy (file->buffer + file->in_buffer, - iov[i].iov_base + written_this_iov, - to_write); - file->in_buffer += to_write; - written_this_iov += to_write; - total += to_write; - if (file->in_buffer == file->chunk_size) { - /* Buffer is filled, write the chunk */ - _mongoc_gridfs_bucket_write_chunk (file); - } - } - } - - return total; -} - -ssize_t -_mongoc_gridfs_bucket_file_readv (mongoc_gridfs_bucket_file_t *file, - mongoc_iovec_t *iov, - size_t iovcnt) -{ - uint32_t total; - size_t bytes_available; - size_t space_available; - int32_t read_this_iov; - size_t to_read; - bool r; - size_t i; - - BSON_ASSERT (file); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - total = 0; - - if (file->err.code) { - return -1; - } - - if (file->finished) { - return 0; - } - - for (i = 0; i < iovcnt; i++) { - read_this_iov = 0; - - while (read_this_iov < iov[i].iov_len) { - bytes_available = file->in_buffer - file->bytes_read; - space_available = iov[i].iov_len - read_this_iov; - to_read = _mongoc_min (bytes_available, space_available); - memcpy (iov[i].iov_base + read_this_iov, - file->buffer + file->bytes_read, - to_read); - file->bytes_read += to_read; - read_this_iov += to_read; - total += to_read; - if (file->bytes_read == file->in_buffer) { - /* Everything in the current chunk has been read, so read a new - * chunk */ - r = _mongoc_gridfs_bucket_read_chunk (file); - if (!r) { - /* an error occured while reading the chunk */ - return -1; - } - if (file->finished) { - /* There's nothing left to read */ - RETURN (total); - } - } - } - } - - RETURN (total); -} - - -/*-------------------------------------------------------------------------- - * - * _mongoc_gridfs_bucket_file_save -- - * - * Saves the file to the files collection in gridFS. This locks the - * file into GridFS, and no more chunks are allowed to be written. - * - * Return: - * True if saved or no-op. False otherwise, and sets the file error. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_gridfs_bucket_file_save (mongoc_gridfs_bucket_file_t *file) -{ - bson_t new_doc; - int64_t length; - bool r; - - BSON_ASSERT (file); - - if (file->saved) { - /* Already saved, or aborted. */ - return true; - } - - if (file->err.code) { - return false; - } - - length = ((int64_t) file->curr_chunk) * file->chunk_size; - - if (file->in_buffer != 0) { - length += file->in_buffer; - _mongoc_gridfs_bucket_write_chunk (file); - } - - file->length = length; - - bson_init (&new_doc); - BSON_APPEND_VALUE (&new_doc, "_id", file->file_id); - BSON_APPEND_INT64 (&new_doc, "length", file->length); - BSON_APPEND_INT32 (&new_doc, "chunkSize", file->chunk_size); - BSON_APPEND_DATE_TIME (&new_doc, "uploadDate", bson_get_monotonic_time ()); - BSON_APPEND_UTF8 (&new_doc, "filename", file->filename); - if (file->metadata) { - BSON_APPEND_DOCUMENT (&new_doc, "metadata", file->metadata); - } - - r = mongoc_collection_insert_one ( - file->bucket->files, &new_doc, NULL, NULL, &file->err); - bson_destroy (&new_doc); - file->saved = r; - return (file->err.code) ? false : true; -} - -void -_mongoc_gridfs_bucket_file_destroy (mongoc_gridfs_bucket_file_t *file) -{ - if (file) { - bson_value_destroy (file->file_id); - bson_free (file->file_id); - bson_destroy (file->metadata); - mongoc_cursor_destroy (file->cursor); - bson_free (file->buffer); - bson_free (file->filename); - bson_free (file); - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h deleted file mode 100644 index 613d3360c5a0a9b61b16855613e345d6ae512bbf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_BUCKET_PRIVATE_H -#define MONGOC_GRIDFS_BUCKET_PRIVATE_H - -#include "mongoc/mongoc-collection.h" - -BSON_BEGIN_DECLS - -struct _mongoc_gridfs_bucket_t { - mongoc_collection_t *chunks; - mongoc_collection_t *files; - int32_t chunk_size; - char *bucket_name; - bool indexed; -}; - -BSON_END_DECLS - -#endif /* MONGOC_GRIDFS_BUCKET_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket.c deleted file mode 100644 index 63dc93d3f6b8483788829a78a0d69c0b8adfe379..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright 2018-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 "bson/bson.h" -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-database-private.h" -#include "mongoc/mongoc-gridfs-bucket-private.h" -#include "mongoc/mongoc-gridfs-bucket-file-private.h" -#include "mongoc/mongoc-opts-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-stream-gridfs-download-private.h" -#include "mongoc/mongoc-stream-gridfs-upload-private.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-write-concern-private.h" - -/*-------------------------------------------------------------------------- - * - * _mongoc_gridfs_find_file_with_id -- - * - * Attempts to find the file corresponding to the given file_id in - * GridFS. - * - * Return: - * True on success and initializes file. Otherwise, returns false - * and sets error. - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_gridfs_find_file_with_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - bson_t *file, - bson_error_t *error) -{ - mongoc_cursor_t *cursor; - bson_t filter; - const bson_t *doc; - bool r; - - BSON_ASSERT (bucket); - BSON_ASSERT (file_id); - - bson_init (&filter); - - BSON_APPEND_VALUE (&filter, "_id", file_id); - - cursor = - mongoc_collection_find_with_opts (bucket->files, &filter, NULL, NULL); - bson_destroy (&filter); - - r = mongoc_cursor_next (cursor, &doc); - if (!r) { - if (!mongoc_cursor_error (cursor, error)) { - bson_set_error (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_BUCKET_FILE_NOT_FOUND, - "No file with given id exists"); - } - } else { - if (file) { - bson_copy_to (doc, file); - } - } - - mongoc_cursor_destroy (cursor); - return r; -} - -mongoc_gridfs_bucket_t * -mongoc_gridfs_bucket_new (mongoc_database_t *db, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) -{ - mongoc_gridfs_bucket_t *bucket; - char buf[128]; - mongoc_gridfs_bucket_opts_t gridfs_opts; - - BSON_ASSERT (db); - - if (!_mongoc_gridfs_bucket_opts_parse ( - db->client, opts, &gridfs_opts, error)) { - _mongoc_gridfs_bucket_opts_cleanup (&gridfs_opts); - return NULL; - } - - /* Initialize the bucket fields */ - if (strlen (gridfs_opts.bucketName) + strlen (".chunks") + 1 > - sizeof (buf)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "bucketName \"%s\" must have fewer than %d characters", - gridfs_opts.bucketName, - (int) (sizeof (buf) - (strlen (".chunks") + 1))); - } - - bucket = (mongoc_gridfs_bucket_t *) bson_malloc0 (sizeof *bucket); - - bson_snprintf (buf, sizeof (buf), "%s.chunks", gridfs_opts.bucketName); - bucket->chunks = mongoc_database_get_collection (db, buf); - - bson_snprintf (buf, sizeof (buf), "%s.files", gridfs_opts.bucketName); - bucket->files = mongoc_database_get_collection (db, buf); - - if (gridfs_opts.writeConcern) { - mongoc_collection_set_write_concern (bucket->chunks, - gridfs_opts.writeConcern); - mongoc_collection_set_write_concern (bucket->files, - gridfs_opts.writeConcern); - } - - if (gridfs_opts.readConcern) { - mongoc_collection_set_read_concern (bucket->chunks, - gridfs_opts.readConcern); - mongoc_collection_set_read_concern (bucket->files, - gridfs_opts.readConcern); - } - - if (read_prefs) { - mongoc_collection_set_read_prefs (bucket->chunks, read_prefs); - mongoc_collection_set_read_prefs (bucket->files, read_prefs); - } - - bucket->chunk_size = gridfs_opts.chunkSizeBytes; - bucket->bucket_name = bson_strdup (gridfs_opts.bucketName); - - _mongoc_gridfs_bucket_opts_cleanup (&gridfs_opts); - - return bucket; -} - - -mongoc_stream_t * -mongoc_gridfs_bucket_open_upload_stream_with_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - const char *filename, - const bson_t *opts, - bson_error_t *error) -{ - mongoc_gridfs_bucket_file_t *file; - size_t len; - mongoc_gridfs_bucket_upload_opts_t gridfs_opts; - - BSON_ASSERT (bucket); - BSON_ASSERT (file_id); - BSON_ASSERT (filename); - - if (!_mongoc_gridfs_bucket_upload_opts_parse ( - NULL /* not needed. */, opts, &gridfs_opts, error)) { - _mongoc_gridfs_bucket_upload_opts_cleanup (&gridfs_opts); - return NULL; - } - - /* default to bucket's chunk size. */ - if (!gridfs_opts.chunkSizeBytes) { - gridfs_opts.chunkSizeBytes = bucket->chunk_size; - } - - /* Initialize the file's fields */ - len = strlen (filename); - - file = (mongoc_gridfs_bucket_file_t *) bson_malloc0 (sizeof *file); - - file->filename = bson_malloc0 (len + 1); - bson_strncpy (file->filename, filename, len + 1); - - file->file_id = (bson_value_t *) bson_malloc0 (sizeof *(file->file_id)); - bson_value_copy (file_id, file->file_id); - - file->bucket = bucket; - file->chunk_size = gridfs_opts.chunkSizeBytes; - file->metadata = bson_copy (&gridfs_opts.metadata); - file->buffer = bson_malloc ((size_t) gridfs_opts.chunkSizeBytes); - file->in_buffer = 0; - - _mongoc_gridfs_bucket_upload_opts_cleanup (&gridfs_opts); - return _mongoc_upload_stream_gridfs_new (file); -} - -mongoc_stream_t * -mongoc_gridfs_bucket_open_upload_stream (mongoc_gridfs_bucket_t *bucket, - const char *filename, - const bson_t *opts, - bson_value_t *file_id /* OUT */, - bson_error_t *error) -{ - mongoc_stream_t *stream; - bson_oid_t object_id; - bson_value_t val; - - BSON_ASSERT (bucket); - BSON_ASSERT (filename); - - /* Create an objectId to use as the file's id */ - bson_oid_init (&object_id, NULL); - val.value_type = BSON_TYPE_OID; - val.value.v_oid = object_id; - - stream = mongoc_gridfs_bucket_open_upload_stream_with_id ( - bucket, &val, filename, opts, error); - - if (!stream) { - return NULL; - } - - if (file_id) { - bson_value_copy (&val, file_id); - } - - return stream; -} - -bool -mongoc_gridfs_bucket_upload_from_stream_with_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - const char *filename, - mongoc_stream_t *source, - const bson_t *opts, - bson_error_t *error) -{ - mongoc_stream_t *upload_stream; - ssize_t bytes_read; - ssize_t bytes_written; - char buf[512]; - - BSON_ASSERT (bucket); - BSON_ASSERT (file_id); - BSON_ASSERT (filename); - BSON_ASSERT (source); - - upload_stream = mongoc_gridfs_bucket_open_upload_stream_with_id ( - bucket, file_id, filename, opts, error); - - if (!upload_stream) { - return false; - } - - while ((bytes_read = mongoc_stream_read (source, buf, 512, 1, 0)) > 0) { - bytes_written = mongoc_stream_write (upload_stream, buf, bytes_read, 0); - if (bytes_written < 0) { - BSON_ASSERT (mongoc_gridfs_bucket_stream_error (upload_stream, error)); - mongoc_gridfs_bucket_abort_upload (upload_stream); - mongoc_stream_destroy (upload_stream); - return false; - } - } - - if (bytes_read < 0) { - mongoc_gridfs_bucket_abort_upload (upload_stream); - bson_set_error (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_BUCKET_STREAM, - "Error occurred on the provided stream."); - mongoc_stream_destroy (upload_stream); - return false; - } else { - mongoc_stream_destroy (upload_stream); - return true; - } -} - -bool -mongoc_gridfs_bucket_upload_from_stream (mongoc_gridfs_bucket_t *bucket, - const char *filename, - mongoc_stream_t *source, - const bson_t *opts, - bson_value_t *file_id /* OUT */, - bson_error_t *error) -{ - bool r; - bson_oid_t object_id; - bson_value_t val; - - BSON_ASSERT (bucket); - BSON_ASSERT (filename); - BSON_ASSERT (source); - - /* Create an objectId to use as the file's id */ - bson_oid_init (&object_id, bson_context_get_default ()); - val.value_type = BSON_TYPE_OID; - val.value.v_oid = object_id; - - r = mongoc_gridfs_bucket_upload_from_stream_with_id ( - bucket, &val, filename, source, opts, error); - - if (!r) { - return false; - } - - if (file_id) { - bson_value_copy (&val, file_id); - } - - return true; -} - - -mongoc_stream_t * -mongoc_gridfs_bucket_open_download_stream (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - bson_error_t *error) -{ - mongoc_gridfs_bucket_file_t *file; - bson_t file_doc; - const char *key; - bson_iter_t iter; - uint32_t data_len; - const uint8_t *data; - bool r; - - BSON_ASSERT (bucket); - BSON_ASSERT (file_id); - - r = _mongoc_gridfs_find_file_with_id (bucket, file_id, &file_doc, error); - if (!r) { - /* Error should already be set. */ - return NULL; - } - - if (!bson_iter_init (&iter, &file_doc)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "File document malformed"); - return NULL; - } - - file = (mongoc_gridfs_bucket_file_t *) bson_malloc0 (sizeof *file); - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - if (strcmp (key, "length") == 0) { - file->length = bson_iter_as_int64 (&iter); - } else if (strcmp (key, "chunkSize") == 0) { - file->chunk_size = bson_iter_int32 (&iter); - } else if (strcmp (key, "filename") == 0) { - file->filename = bson_strdup (bson_iter_utf8 (&iter, NULL)); - } else if (strcmp (key, "metadata") == 0) { - bson_iter_document (&iter, &data_len, &data); - file->metadata = bson_new_from_data (data, data_len); - } - } - - bson_destroy (&file_doc); - - file->file_id = (bson_value_t *) bson_malloc0 (sizeof *(file->file_id)); - bson_value_copy (file_id, file->file_id); - file->bucket = bucket; - file->buffer = bson_malloc0 ((size_t) file->chunk_size); - - BSON_ASSERT (file->file_id); - - return _mongoc_download_stream_gridfs_new (file); -} - -bool -mongoc_gridfs_bucket_download_to_stream (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - mongoc_stream_t *destination, - bson_error_t *error) -{ - mongoc_stream_t *download_stream; - ssize_t bytes_read; - ssize_t bytes_written; - char buf[512]; - - BSON_ASSERT (bucket); - BSON_ASSERT (file_id); - BSON_ASSERT (destination); - - /* Make the download stream */ - download_stream = - mongoc_gridfs_bucket_open_download_stream (bucket, file_id, error); - - while ((bytes_read = mongoc_stream_read (download_stream, buf, 256, 1, 0)) > - 0) { - bytes_written = mongoc_stream_write (destination, buf, bytes_read, 0); - if (bytes_written < 0) { - bson_set_error (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_BUCKET_STREAM, - "Error occurred on the provided stream."); - mongoc_stream_destroy (download_stream); - return false; - } - } - - mongoc_stream_destroy (download_stream); - return bytes_read != -1; -} - -bool -mongoc_gridfs_bucket_delete_by_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - bson_error_t *error) -{ - bson_t files_selector; - bson_t chunks_selector; - bson_t reply; - bson_iter_t iter; - bool r; - - BSON_ASSERT (bucket); - BSON_ASSERT (file_id); - - bson_init (&files_selector); - - BSON_APPEND_VALUE (&files_selector, "_id", file_id); - - r = mongoc_collection_delete_one ( - bucket->files, &files_selector, NULL, &reply, error); - bson_destroy (&files_selector); - if (!r) { - bson_destroy (&reply); - return false; - } - - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "deletedCount")); - - if (bson_iter_as_int64 (&iter) != 1) { - bson_set_error (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_BUCKET_FILE_NOT_FOUND, - "File not found"); - bson_destroy (&reply); - return false; - } - - bson_destroy (&reply); - - bson_init (&chunks_selector); - - BSON_APPEND_VALUE (&chunks_selector, "files_id", file_id); - - r = mongoc_collection_delete_many ( - bucket->chunks, &chunks_selector, NULL, NULL, error); - bson_destroy (&chunks_selector); - if (!r) { - return false; - } - - return true; -} - -mongoc_cursor_t * -mongoc_gridfs_bucket_find (mongoc_gridfs_bucket_t *bucket, - const bson_t *filter, - const bson_t *opts) -{ - mongoc_cursor_t *cursor; - BSON_ASSERT (bucket); - BSON_ASSERT (filter); - - cursor = - mongoc_collection_find_with_opts (bucket->files, filter, NULL, NULL); - if (!cursor->error.code && bson_has_field (opts, "sessionId")) { - bson_set_error (&cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot pass sessionId as an option"); - } - return cursor; -} - -bool -mongoc_gridfs_bucket_stream_error (mongoc_stream_t *stream, bson_error_t *error) -{ - bson_error_t *stream_err; - BSON_ASSERT (stream); - BSON_ASSERT (error); - - - if (stream->type == MONGOC_STREAM_GRIDFS_UPLOAD) { - stream_err = &((mongoc_gridfs_upload_stream_t *) stream)->file->err; - } else if (stream->type == MONGOC_STREAM_GRIDFS_DOWNLOAD) { - stream_err = &((mongoc_gridfs_download_stream_t *) stream)->file->err; - } else { - return false; - } - - if (stream_err->code) { - memcpy (error, stream_err, sizeof (*stream_err)); - return true; - } else { - return false; - } -} - -void -mongoc_gridfs_bucket_destroy (mongoc_gridfs_bucket_t *bucket) -{ - if (bucket) { - mongoc_collection_destroy (bucket->chunks); - mongoc_collection_destroy (bucket->files); - bson_free (bucket->bucket_name); - bson_free (bucket); - } -} - -bool -mongoc_gridfs_bucket_abort_upload (mongoc_stream_t *stream) -{ - mongoc_gridfs_bucket_file_t *file; - bson_t chunks_selector; - bool r; - - BSON_ASSERT (stream); - BSON_ASSERT (stream->type == MONGOC_STREAM_GRIDFS_UPLOAD); - - file = ((mongoc_gridfs_upload_stream_t *) stream)->file; - - /* Pretend we've already saved. This way we won't add an entry to the files - * collection when the stream is closed */ - file->saved = true; - - bson_init (&chunks_selector); - BSON_APPEND_VALUE (&chunks_selector, "files_id", file->file_id); - - r = mongoc_collection_delete_many ( - file->bucket->chunks, &chunks_selector, NULL, NULL, &file->err); - bson_destroy (&chunks_selector); - return r; -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket.h deleted file mode 100644 index c28cd9040917e10c24542481c044343d53883211..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-bucket.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_BUCKET_H -#define MONGOC_GRIDFS_BUCKET_H - -#include "bson/bson.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-database.h" -#include "mongoc/mongoc-stream.h" - -BSON_BEGIN_DECLS - -typedef struct _mongoc_gridfs_bucket_t mongoc_gridfs_bucket_t; - -MONGOC_EXPORT (mongoc_gridfs_bucket_t *) -mongoc_gridfs_bucket_new (mongoc_database_t *db, - const bson_t *opts, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error); - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_gridfs_bucket_open_upload_stream (mongoc_gridfs_bucket_t *bucket, - const char *filename, - const bson_t *opts, - bson_value_t *file_id, - bson_error_t *error); - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_gridfs_bucket_open_upload_stream_with_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - const char *filename, - const bson_t *opts, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_gridfs_bucket_upload_from_stream (mongoc_gridfs_bucket_t *bucket, - const char *filename, - mongoc_stream_t *source, - const bson_t *opts, - bson_value_t *file_id, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_gridfs_bucket_upload_from_stream_with_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - const char *filename, - mongoc_stream_t *source, - const bson_t *opts, - bson_error_t *error); - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_gridfs_bucket_open_download_stream (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_gridfs_bucket_download_to_stream (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - mongoc_stream_t *destination, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_gridfs_bucket_delete_by_id (mongoc_gridfs_bucket_t *bucket, - const bson_value_t *file_id, - bson_error_t *error); - -MONGOC_EXPORT (mongoc_cursor_t *) -mongoc_gridfs_bucket_find (mongoc_gridfs_bucket_t *bucket, - const bson_t *filter, - const bson_t *opts); - -MONGOC_EXPORT (bool) -mongoc_gridfs_bucket_stream_error (mongoc_stream_t *stream, - bson_error_t *error); - -MONGOC_EXPORT (void) -mongoc_gridfs_bucket_destroy (mongoc_gridfs_bucket_t *bucket); - -MONGOC_EXPORT (bool) -mongoc_gridfs_bucket_abort_upload (mongoc_stream_t *stream); - -BSON_END_DECLS - -#endif /* MONGOC_GRIDFS_BUCKET_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h deleted file mode 100644 index 5d70310f26bdd8c2bd0aecad252844f9c2373702..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_FILE_LIST_PRIVATE_H -#define MONGOC_GRIDFS_FILE_LIST_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-gridfs.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-cursor.h" - - -BSON_BEGIN_DECLS - - -struct _mongoc_gridfs_file_list_t { - mongoc_gridfs_t *gridfs; - mongoc_cursor_t *cursor; - bson_error_t error; -}; - - -mongoc_gridfs_file_list_t * -_mongoc_gridfs_file_list_new (mongoc_gridfs_t *gridfs, - const bson_t *query, - uint32_t limit); -mongoc_gridfs_file_list_t * -_mongoc_gridfs_file_list_new_with_opts (mongoc_gridfs_t *gridfs, - const bson_t *filter, - const bson_t *opts); - - -BSON_END_DECLS - - -#endif /* MONGOC_GRIDFS_FILE_LIST_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list.c deleted file mode 100644 index b279e2b964e3b996ce36854330ec24b5e236c81f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2013 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 <limits.h> - -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-gridfs.h" -#include "mongoc/mongoc-gridfs-private.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-gridfs-file-private.h" -#include "mongoc/mongoc-gridfs-file-list.h" -#include "mongoc/mongoc-gridfs-file-list-private.h" -#include "mongoc/mongoc-trace-private.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "gridfs_file_list" - - -mongoc_gridfs_file_list_t * -_mongoc_gridfs_file_list_new (mongoc_gridfs_t *gridfs, - const bson_t *query, - uint32_t limit) -{ - mongoc_gridfs_file_list_t *list; - mongoc_cursor_t *cursor; - bool use_unwrapped; - bson_t opts; - bson_t unwrapped; - bson_error_t error; - bson_init (&opts); - use_unwrapped = _mongoc_cursor_translate_dollar_query_opts ( - query, &opts, &unwrapped, &error); - - - cursor = _mongoc_cursor_find_new (gridfs->client, - gridfs->files->ns, - use_unwrapped ? &unwrapped : query, - &opts, - NULL, - gridfs->files->read_prefs, - gridfs->files->read_concern); - BSON_ASSERT (cursor); - bson_destroy (&opts); - if (limit) { - (void) mongoc_cursor_set_limit (cursor, limit); - } - bson_destroy (&unwrapped); - if (error.domain) { - memcpy (&cursor->error, &error, sizeof (bson_error_t)); - } - - list = (mongoc_gridfs_file_list_t *) bson_malloc0 (sizeof *list); - - list->cursor = cursor; - list->gridfs = gridfs; - - return list; -} - - -mongoc_gridfs_file_list_t * -_mongoc_gridfs_file_list_new_with_opts (mongoc_gridfs_t *gridfs, - const bson_t *filter, - const bson_t *opts) -{ - mongoc_gridfs_file_list_t *list; - mongoc_cursor_t *cursor; - - cursor = mongoc_collection_find_with_opts ( - gridfs->files, filter, opts, NULL /* read prefs */); - - BSON_ASSERT (cursor); - - list = (mongoc_gridfs_file_list_t *) bson_malloc0 (sizeof *list); - - list->cursor = cursor; - list->gridfs = gridfs; - - return list; -} - - -mongoc_gridfs_file_t * -mongoc_gridfs_file_list_next (mongoc_gridfs_file_list_t *list) -{ - const bson_t *bson; - - BSON_ASSERT (list); - - if (mongoc_cursor_next (list->cursor, &bson)) { - return _mongoc_gridfs_file_new_from_bson (list->gridfs, bson); - } else { - return NULL; - } -} - - -bool -mongoc_gridfs_file_list_error (mongoc_gridfs_file_list_t *list, - bson_error_t *error) -{ - return mongoc_cursor_error (list->cursor, error); -} - - -void -mongoc_gridfs_file_list_destroy (mongoc_gridfs_file_list_t *list) -{ - if (!list) { - return; - } - - mongoc_cursor_destroy (list->cursor); - bson_free (list); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list.h deleted file mode 100644 index 8ad72f90db1c3f81df4d596271559d3a62f5b412..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-list.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_FILE_LIST_H -#define MONGOC_GRIDFS_FILE_LIST_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-gridfs-file.h" - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_gridfs_file_list_t mongoc_gridfs_file_list_t; - - -MONGOC_EXPORT (mongoc_gridfs_file_t *) -mongoc_gridfs_file_list_next (mongoc_gridfs_file_list_t *list); -MONGOC_EXPORT (void) -mongoc_gridfs_file_list_destroy (mongoc_gridfs_file_list_t *list); -MONGOC_EXPORT (bool) -mongoc_gridfs_file_list_error (mongoc_gridfs_file_list_t *list, - bson_error_t *error); - - -BSON_END_DECLS - - -#endif /* MONGOC_GRIDFS_FILE_LIST_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h deleted file mode 100644 index eabfd90ef7c6ee89fde84f9162d8fa7bd2561e54..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_FILE_PAGE_PRIVATE_H -#define MONGOC_GRIDFS_FILE_PAGE_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-gridfs-file.h" - - -BSON_BEGIN_DECLS - - -struct _mongoc_gridfs_file_page_t { - const uint8_t *read_buf; - uint8_t *buf; - uint32_t len; - uint32_t chunk_size; - uint32_t offset; -}; - - -mongoc_gridfs_file_page_t * -_mongoc_gridfs_file_page_new (const uint8_t *data, - uint32_t len, - uint32_t chunk_size); -void -_mongoc_gridfs_file_page_destroy (mongoc_gridfs_file_page_t *page); -bool -_mongoc_gridfs_file_page_seek (mongoc_gridfs_file_page_t *page, - uint32_t offset); -int32_t -_mongoc_gridfs_file_page_read (mongoc_gridfs_file_page_t *page, - void *dst, - uint32_t len); -int32_t -_mongoc_gridfs_file_page_write (mongoc_gridfs_file_page_t *page, - const void *src, - uint32_t len); -uint32_t -_mongoc_gridfs_file_page_memset0 (mongoc_gridfs_file_page_t *page, - uint32_t len); -uint32_t -_mongoc_gridfs_file_page_tell (mongoc_gridfs_file_page_t *page); -const uint8_t * -_mongoc_gridfs_file_page_get_data (mongoc_gridfs_file_page_t *page); -uint32_t -_mongoc_gridfs_file_page_get_len (mongoc_gridfs_file_page_t *page); -bool -_mongoc_gridfs_file_page_is_dirty (mongoc_gridfs_file_page_t *page); - - -BSON_END_DECLS - - -#endif /* MONGOC_GRIDFS_FILE_PAGE_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page.c deleted file mode 100644 index e63a4d28c51413df8d9187a7956a15d59fb42162..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2013 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. - */ - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "gridfs_file_page" - -#include "mongoc/mongoc-gridfs-file-page.h" -#include "mongoc/mongoc-gridfs-file-page-private.h" - -#include "mongoc/mongoc-trace-private.h" - - -/** create a new page from a buffer - * - * The buffer should stick around for the life of the page - */ -mongoc_gridfs_file_page_t * -_mongoc_gridfs_file_page_new (const uint8_t *data, - uint32_t len, - uint32_t chunk_size) -{ - mongoc_gridfs_file_page_t *page; - - ENTRY; - - BSON_ASSERT (data); - BSON_ASSERT (len <= chunk_size); - - page = (mongoc_gridfs_file_page_t *) bson_malloc0 (sizeof *page); - - page->chunk_size = chunk_size; - page->read_buf = data; - page->len = len; - - RETURN (page); -} - - -bool -_mongoc_gridfs_file_page_seek (mongoc_gridfs_file_page_t *page, uint32_t offset) -{ - ENTRY; - - BSON_ASSERT (page); - - page->offset = offset; - - RETURN (1); -} - - -int32_t -_mongoc_gridfs_file_page_read (mongoc_gridfs_file_page_t *page, - void *dst, - uint32_t len) -{ - int bytes_read; - const uint8_t *src; - - ENTRY; - - BSON_ASSERT (page); - BSON_ASSERT (dst); - - bytes_read = BSON_MIN (len, page->len - page->offset); - - src = page->read_buf ? page->read_buf : page->buf; - - memcpy (dst, src + page->offset, bytes_read); - - page->offset += bytes_read; - - RETURN (bytes_read); -} - - -/** - * _mongoc_gridfs_file_page_write: - * - * Write to a page. - * -* Writes are copy-on-write with regards to the buffer that was passed to the - * mongoc_gridfs_file_page_t during construction. In other words, the first - * write allocates a large enough buffer for file->chunk_size, which becomes - * authoritative from then on. - * - * A write of zero bytes will trigger the copy-on-write mechanism. - */ -int32_t -_mongoc_gridfs_file_page_write (mongoc_gridfs_file_page_t *page, - const void *src, - uint32_t len) -{ - int bytes_written; - - ENTRY; - - BSON_ASSERT (page); - BSON_ASSERT (src); - - bytes_written = BSON_MIN (len, page->chunk_size - page->offset); - - if (!page->buf) { - page->buf = (uint8_t *) bson_malloc (page->chunk_size); - memcpy ( - page->buf, page->read_buf, BSON_MIN (page->chunk_size, page->len)); - } - - /* Copy bytes and adjust the page position */ - memcpy (page->buf + page->offset, src, bytes_written); - page->offset += bytes_written; - page->len = BSON_MAX (page->offset, page->len); - - /* Don't use the old read buffer, which is no longer current */ - page->read_buf = page->buf; - - RETURN (bytes_written); -} - - -/** - * _mongoc_gridfs_file_page_memset0: - * - * Write zeros to a page, starting from the page's current position. Up to - * `len` bytes will be set to zero or until the page is full, whichever - * comes first. - * - * Like _mongoc_gridfs_file_page_write, operations are copy-on-write with - * regards to the page buffer. - * - * Returns: - * Number of bytes set. - */ -uint32_t -_mongoc_gridfs_file_page_memset0 (mongoc_gridfs_file_page_t *page, uint32_t len) -{ - uint32_t bytes_set; - - ENTRY; - - BSON_ASSERT (page); - - bytes_set = BSON_MIN (page->chunk_size - page->offset, len); - - if (!page->buf) { - page->buf = (uint8_t *) bson_malloc0 (page->chunk_size); - memcpy ( - page->buf, page->read_buf, BSON_MIN (page->chunk_size, page->len)); - } - - /* Set bytes and adjust the page position */ - memset (page->buf + page->offset, '\0', bytes_set); - page->offset += bytes_set; - page->len = BSON_MAX (page->offset, page->len); - - /* Don't use the old read buffer, which is no longer current */ - page->read_buf = page->buf; - - RETURN (bytes_set); -} - - -const uint8_t * -_mongoc_gridfs_file_page_get_data (mongoc_gridfs_file_page_t *page) -{ - ENTRY; - - BSON_ASSERT (page); - - RETURN (page->buf ? page->buf : page->read_buf); -} - - -uint32_t -_mongoc_gridfs_file_page_get_len (mongoc_gridfs_file_page_t *page) -{ - ENTRY; - - BSON_ASSERT (page); - - RETURN (page->len); -} - - -uint32_t -_mongoc_gridfs_file_page_tell (mongoc_gridfs_file_page_t *page) -{ - ENTRY; - - BSON_ASSERT (page); - - RETURN (page->offset); -} - - -bool -_mongoc_gridfs_file_page_is_dirty (mongoc_gridfs_file_page_t *page) -{ - ENTRY; - - BSON_ASSERT (page); - - RETURN (page->buf ? 1 : 0); -} - - -void -_mongoc_gridfs_file_page_destroy (mongoc_gridfs_file_page_t *page) -{ - ENTRY; - - if (page->buf) { - bson_free (page->buf); - } - - bson_free (page); - - EXIT; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page.h deleted file mode 100644 index dc1ff9f2251dee36abe94ba742257bb0dfe60c4d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-page.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_FILE_PAGE_H -#define MONGOC_GRIDFS_FILE_PAGE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-gridfs-file-list.h" - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_gridfs_file_page_t mongoc_gridfs_file_page_t; - - -BSON_END_DECLS - - -#endif /* MONGOC_GRIDFS_FILE_PAGE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-private.h deleted file mode 100644 index 2fe3e85c5273d7f225924a8d12676ef6d88eee4f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file-private.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_FILE_PRIVATE_H -#define MONGOC_GRIDFS_FILE_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-gridfs.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-gridfs-file-page.h" -#include "mongoc/mongoc-cursor.h" - - -BSON_BEGIN_DECLS - - -struct _mongoc_gridfs_file_t { - mongoc_gridfs_t *gridfs; - bson_t bson; - mongoc_gridfs_file_page_t *page; - uint64_t pos; - int32_t n; - bson_error_t error; - mongoc_cursor_t *cursor; - uint32_t cursor_range[2]; /* current chunk, # of chunks */ - bool is_dirty; - - bson_value_t files_id; - int64_t length; - int32_t chunk_size; - int64_t upload_date; - - char *md5; - char *filename; - char *content_type; - bson_t aliases; - bson_t metadata; - const char *bson_md5; - const char *bson_filename; - const char *bson_content_type; - bson_t bson_aliases; - bson_t bson_metadata; -}; - - -mongoc_gridfs_file_t * -_mongoc_gridfs_file_new_from_bson (mongoc_gridfs_t *gridfs, const bson_t *data); -mongoc_gridfs_file_t * -_mongoc_gridfs_file_new (mongoc_gridfs_t *gridfs, - mongoc_gridfs_file_opt_t *opt); - - -BSON_END_DECLS - - -#endif /* MONGOC_GRIDFS_FILE_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file.c deleted file mode 100644 index 893a76ba1f566f6f9744177a762d75958c94c560..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* - * Copyright 2013 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. - */ - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "gridfs_file" - -#include <limits.h> -#include <time.h> -#include <errno.h> - -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-gridfs.h" -#include "mongoc/mongoc-gridfs-private.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-gridfs-file-private.h" -#include "mongoc/mongoc-gridfs-file-page.h" -#include "mongoc/mongoc-gridfs-file-page-private.h" -#include "mongoc/mongoc-iovec.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-error.h" - -static bool -_mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file); - -static bool -_mongoc_gridfs_file_flush_page (mongoc_gridfs_file_t *file); - -static ssize_t -_mongoc_gridfs_file_extend (mongoc_gridfs_file_t *file); - - -/***************************************************************** - * Magic accessor generation - * - * We need some accessors to get and set properties on files, to handle memory - * ownership and to determine dirtiness. These macros produce the getters and - * setters we need - *****************************************************************/ - -#define MONGOC_GRIDFS_FILE_STR_ACCESSOR(name) \ - const char *mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t *file) \ - { \ - return file->name ? file->name : file->bson_##name; \ - } \ - void mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t *file, \ - const char *str) \ - { \ - if (file->name) { \ - bson_free (file->name); \ - } \ - file->name = bson_strdup (str); \ - file->is_dirty = 1; \ - } - -#define MONGOC_GRIDFS_FILE_BSON_ACCESSOR(name) \ - const bson_t *mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t *file) \ - { \ - if (file->name.len) { \ - return &file->name; \ - } else if (file->bson_##name.len) { \ - return &file->bson_##name; \ - } else { \ - return NULL; \ - } \ - } \ - void mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t *file, \ - const bson_t *bson) \ - { \ - if (file->name.len) { \ - bson_destroy (&file->name); \ - } \ - bson_copy_to (bson, &(file->name)); \ - file->is_dirty = 1; \ - } - -MONGOC_GRIDFS_FILE_STR_ACCESSOR (md5) -MONGOC_GRIDFS_FILE_STR_ACCESSOR (filename) -MONGOC_GRIDFS_FILE_STR_ACCESSOR (content_type) -MONGOC_GRIDFS_FILE_BSON_ACCESSOR (aliases) -MONGOC_GRIDFS_FILE_BSON_ACCESSOR (metadata) - -/** - * mongoc_gridfs_file_set_id: - * - * the user can set the files_id to an id of any type. Must be called before - * mongoc_gridfs_file_save. - * - */ - -bool -mongoc_gridfs_file_set_id (mongoc_gridfs_file_t *file, - const bson_value_t *id, - bson_error_t *error) -{ - if (!file->is_dirty) { - bson_set_error (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_PROTOCOL_ERROR, - "Cannot set file id after saving file."); - return false; - } - bson_value_copy (id, &file->files_id); - return true; -} - -/** save a gridfs file */ -bool -mongoc_gridfs_file_save (mongoc_gridfs_file_t *file) -{ - bson_t *selector, *update, child; - const char *md5; - const char *filename; - const char *content_type; - const bson_t *aliases; - const bson_t *metadata; - bool r; - - ENTRY; - - if (!file->is_dirty) { - return 1; - } - - if (file->page && _mongoc_gridfs_file_page_is_dirty (file->page)) { - if (!_mongoc_gridfs_file_flush_page (file)) { - RETURN (false); - } - } - - md5 = mongoc_gridfs_file_get_md5 (file); - filename = mongoc_gridfs_file_get_filename (file); - content_type = mongoc_gridfs_file_get_content_type (file); - aliases = mongoc_gridfs_file_get_aliases (file); - metadata = mongoc_gridfs_file_get_metadata (file); - - selector = bson_new (); - bson_append_value (selector, "_id", -1, &file->files_id); - - update = bson_new (); - bson_append_document_begin (update, "$set", -1, &child); - bson_append_int64 (&child, "length", -1, file->length); - bson_append_int32 (&child, "chunkSize", -1, file->chunk_size); - bson_append_date_time (&child, "uploadDate", -1, file->upload_date); - - if (md5) { - bson_append_utf8 (&child, "md5", -1, md5, -1); - } - - if (filename) { - bson_append_utf8 (&child, "filename", -1, filename, -1); - } - - if (content_type) { - bson_append_utf8 (&child, "contentType", -1, content_type, -1); - } - - if (aliases) { - bson_append_array (&child, "aliases", -1, aliases); - } - - if (metadata) { - bson_append_document (&child, "metadata", -1, metadata); - } - - bson_append_document_end (update, &child); - - r = mongoc_collection_update (file->gridfs->files, - MONGOC_UPDATE_UPSERT, - selector, - update, - NULL, - &file->error); - - bson_destroy (selector); - bson_destroy (update); - - file->is_dirty = 0; - - RETURN (r); -} - - -/** - * _mongoc_gridfs_file_new_from_bson: - * - * creates a gridfs file from a bson object - * - * This is only really useful for instantiating a gridfs file from a server - * side object - */ -mongoc_gridfs_file_t * -_mongoc_gridfs_file_new_from_bson (mongoc_gridfs_t *gridfs, const bson_t *data) -{ - mongoc_gridfs_file_t *file; - const bson_value_t *value; - const char *key; - bson_iter_t iter; - const uint8_t *buf; - uint32_t buf_len; - - ENTRY; - - BSON_ASSERT (gridfs); - BSON_ASSERT (data); - - file = (mongoc_gridfs_file_t *) bson_malloc0 (sizeof *file); - - file->gridfs = gridfs; - bson_copy_to (data, &file->bson); - - if (!bson_iter_init (&iter, &file->bson)) { - GOTO (failure); - } - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - - if (0 == strcmp (key, "_id")) { - value = bson_iter_value (&iter); - bson_value_copy (value, &file->files_id); - } else if (0 == strcmp (key, "length")) { - if (!BSON_ITER_HOLDS_NUMBER (&iter)) { - GOTO (failure); - } - file->length = bson_iter_as_int64 (&iter); - } else if (0 == strcmp (key, "chunkSize")) { - if (!BSON_ITER_HOLDS_NUMBER (&iter)) { - GOTO (failure); - } - if (bson_iter_as_int64 (&iter) > INT32_MAX) { - GOTO (failure); - } - file->chunk_size = (int32_t) bson_iter_as_int64 (&iter); - } else if (0 == strcmp (key, "uploadDate")) { - if (!BSON_ITER_HOLDS_DATE_TIME (&iter)) { - GOTO (failure); - } - file->upload_date = bson_iter_date_time (&iter); - } else if (0 == strcmp (key, "md5")) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) { - GOTO (failure); - } - file->bson_md5 = bson_iter_utf8 (&iter, NULL); - } else if (0 == strcmp (key, "filename")) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) { - GOTO (failure); - } - file->bson_filename = bson_iter_utf8 (&iter, NULL); - } else if (0 == strcmp (key, "contentType")) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) { - GOTO (failure); - } - file->bson_content_type = bson_iter_utf8 (&iter, NULL); - } else if (0 == strcmp (key, "aliases")) { - if (!BSON_ITER_HOLDS_ARRAY (&iter)) { - GOTO (failure); - } - bson_iter_array (&iter, &buf_len, &buf); - if (!bson_init_static (&file->bson_aliases, buf, buf_len)) { - GOTO (failure); - } - } else if (0 == strcmp (key, "metadata")) { - if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { - GOTO (failure); - } - bson_iter_document (&iter, &buf_len, &buf); - if (!bson_init_static (&file->bson_metadata, buf, buf_len)) { - GOTO (failure); - } - } - } - - /* TODO: is there are a minimal object we should be verifying that we - * actually have here? */ - - RETURN (file); - -failure: - bson_destroy (&file->bson); - - RETURN (NULL); -} - - -/** - * _mongoc_gridfs_file_new: - * - * Create a new empty gridfs file - */ -mongoc_gridfs_file_t * -_mongoc_gridfs_file_new (mongoc_gridfs_t *gridfs, mongoc_gridfs_file_opt_t *opt) -{ - mongoc_gridfs_file_t *file; - mongoc_gridfs_file_opt_t default_opt = {0}; - - ENTRY; - - BSON_ASSERT (gridfs); - - if (!opt) { - opt = &default_opt; - } - - file = (mongoc_gridfs_file_t *) bson_malloc0 (sizeof *file); - - file->gridfs = gridfs; - file->is_dirty = 1; - - if (opt->chunk_size) { - file->chunk_size = opt->chunk_size; - } else { - /* - * The default chunk size is now 255kb. This used to be 256k but has been - * reduced to allow for them to fit within power of two sizes in mongod. - * - * See CDRIVER-322. - */ - file->chunk_size = (1 << 18) - 1024; - } - - file->files_id.value_type = BSON_TYPE_OID; - bson_oid_init (&file->files_id.value.v_oid, NULL); - - file->upload_date = ((int64_t) time (NULL)) * 1000; - - if (opt->md5) { - file->md5 = bson_strdup (opt->md5); - } - - if (opt->filename) { - file->filename = bson_strdup (opt->filename); - } - - if (opt->content_type) { - file->content_type = bson_strdup (opt->content_type); - } - - if (opt->aliases) { - bson_copy_to (opt->aliases, &(file->aliases)); - } - - if (opt->metadata) { - bson_copy_to (opt->metadata, &(file->metadata)); - } - - file->pos = 0; - file->n = 0; - - RETURN (file); -} - -void -mongoc_gridfs_file_destroy (mongoc_gridfs_file_t *file) -{ - ENTRY; - - if (!file) { - EXIT; - } - - if (file->page) { - _mongoc_gridfs_file_page_destroy (file->page); - } - - if (file->bson.len) { - bson_destroy (&file->bson); - } - - if (file->cursor) { - mongoc_cursor_destroy (file->cursor); - } - - if (file->files_id.value_type) { - bson_value_destroy (&file->files_id); - } - - if (file->md5) { - bson_free (file->md5); - } - - if (file->filename) { - bson_free (file->filename); - } - - if (file->content_type) { - bson_free (file->content_type); - } - - if (file->aliases.len) { - bson_destroy (&file->aliases); - } - - if (file->bson_aliases.len) { - bson_destroy (&file->bson_aliases); - } - - if (file->metadata.len) { - bson_destroy (&file->metadata); - } - - if (file->bson_metadata.len) { - bson_destroy (&file->bson_metadata); - } - - bson_free (file); - - EXIT; -} - - -/** readv against a gridfs file - * timeout_msec is unused */ -ssize_t -mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - uint32_t timeout_msec) -{ - uint32_t bytes_read = 0; - int32_t r; - size_t i; - uint32_t iov_pos; - - ENTRY; - - BSON_ASSERT (file); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - /* Reading when positioned past the end does nothing */ - if (file->pos >= file->length) { - return 0; - } - - /* Try to get the current chunk */ - if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { - return -1; - } - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - for (;;) { - r = _mongoc_gridfs_file_page_read ( - file->page, - (uint8_t *) iov[i].iov_base + iov_pos, - (uint32_t) (iov[i].iov_len - iov_pos)); - BSON_ASSERT (r >= 0); - - iov_pos += r; - file->pos += r; - bytes_read += r; - - if (iov_pos == iov[i].iov_len) { - /* filled a bucket, keep going */ - break; - } else if (file->length == file->pos) { - /* we're at the end of the file. So we're done */ - RETURN (bytes_read); - } else if (bytes_read >= min_bytes) { - /* we need a new page, but we've read enough bytes to stop */ - RETURN (bytes_read); - } else if (!_mongoc_gridfs_file_refresh_page (file)) { - return -1; - } - } - } - - RETURN (bytes_read); -} - - -/** writev against a gridfs file - * timeout_msec is unused */ -ssize_t -mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, - const mongoc_iovec_t *iov, - size_t iovcnt, - uint32_t timeout_msec) -{ - uint32_t bytes_written = 0; - int32_t r; - size_t i; - uint32_t iov_pos; - - ENTRY; - - BSON_ASSERT (file); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - /* Pull in the correct page */ - if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { - return -1; - } - - /* When writing past the end-of-file, fill the gap with zeros */ - if (file->pos > file->length && !_mongoc_gridfs_file_extend (file)) { - return -1; - } - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - for (;;) { - if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { - return -1; - } - - /* write bytes until an iov is exhausted or the page is full */ - r = _mongoc_gridfs_file_page_write ( - file->page, - (uint8_t *) iov[i].iov_base + iov_pos, - (uint32_t) (iov[i].iov_len - iov_pos)); - BSON_ASSERT (r >= 0); - - iov_pos += r; - file->pos += r; - bytes_written += r; - - file->length = BSON_MAX (file->length, (int64_t) file->pos); - - if (iov_pos == iov[i].iov_len) { - /** filled a bucket, keep going */ - break; - } else { - /** flush the buffer, the next pass through will bring in a new page - */ - if (!_mongoc_gridfs_file_flush_page (file)) { - return -1; - } - } - } - } - - file->is_dirty = 1; - - RETURN (bytes_written); -} - - -/** - * _mongoc_gridfs_file_extend: - * - * Extend a GridFS file to the current position pointer. Zeros will be - * appended to the end of the file until file->length is even with - * file->pos. - * - * If file->length >= file->pos, the function exits successfully with no - * operation performed. - * - * Parameters: - * @file: A mongoc_gridfs_file_t. - * - * Returns: - * The number of zero bytes written, or -1 on failure. - */ -static ssize_t -_mongoc_gridfs_file_extend (mongoc_gridfs_file_t *file) -{ - int64_t target_length; - ssize_t diff; - - ENTRY; - - BSON_ASSERT (file); - - if (file->length >= file->pos) { - RETURN (0); - } - - diff = (ssize_t) (file->pos - file->length); - target_length = file->pos; - if (-1 == mongoc_gridfs_file_seek (file, 0, SEEK_END)) { - RETURN (-1); - } - - while (true) { - if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { - RETURN (-1); - } - - /* Set bytes until we reach the limit or fill a page */ - file->pos += _mongoc_gridfs_file_page_memset0 (file->page, - target_length - file->pos); - - if (file->pos == target_length) { - /* We're done */ - break; - } else if (!_mongoc_gridfs_file_flush_page (file)) { - /* We tried to flush a full buffer, but an error occurred */ - RETURN (-1); - } - } - - file->length = target_length; - file->is_dirty = true; - - RETURN (diff); -} - - -/** - * _mongoc_gridfs_file_flush_page: - * - * Unconditionally flushes the file's current page to the database. - * The page to flush is determined by page->n. - * - * Side Effects: - * - * On success, file->page is properly destroyed and set to NULL. - * - * Returns: - * - * True on success; false otherwise. - */ -static bool -_mongoc_gridfs_file_flush_page (mongoc_gridfs_file_t *file) -{ - bson_t *selector, *update; - bool r; - const uint8_t *buf; - uint32_t len; - - ENTRY; - BSON_ASSERT (file); - BSON_ASSERT (file->page); - - buf = _mongoc_gridfs_file_page_get_data (file->page); - len = _mongoc_gridfs_file_page_get_len (file->page); - - selector = bson_new (); - - bson_append_value (selector, "files_id", -1, &file->files_id); - bson_append_int32 (selector, "n", -1, file->n); - - update = bson_sized_new (file->chunk_size + 100); - - bson_append_value (update, "files_id", -1, &file->files_id); - bson_append_int32 (update, "n", -1, file->n); - bson_append_binary (update, "data", -1, BSON_SUBTYPE_BINARY, buf, len); - - r = mongoc_collection_update (file->gridfs->chunks, - MONGOC_UPDATE_UPSERT, - selector, - update, - NULL, - &file->error); - - bson_destroy (selector); - bson_destroy (update); - - if (r) { - _mongoc_gridfs_file_page_destroy (file->page); - file->page = NULL; - r = mongoc_gridfs_file_save (file); - } - - RETURN (r); -} - - -/** - * _mongoc_gridfs_file_keep_cursor: - * - * After a seek, decide if the next read should use the current cursor or - * start a new query. - * - * Preconditions: - * - * file has a cursor and cursor range. - * - * Side Effects: - * - * None. - */ -static bool -_mongoc_gridfs_file_keep_cursor (mongoc_gridfs_file_t *file) -{ - uint32_t chunk_no; - uint32_t chunks_per_batch; - - if (file->n < 0 || file->chunk_size <= 0) { - return false; - } - - chunk_no = (uint32_t) file->n; - /* server returns roughly 4 MB batches by default */ - chunks_per_batch = (4 * 1024 * 1024) / (uint32_t) file->chunk_size; - - return ( - /* cursor is on or before the desired chunk */ - file->cursor_range[0] <= chunk_no && - /* chunk_no is before end of file */ - chunk_no <= file->cursor_range[1] && - /* desired chunk is in this batch or next one */ - chunk_no < file->cursor_range[0] + 2 * chunks_per_batch); -} - - -static int64_t -divide_round_up (int64_t num, int64_t denom) -{ - return (num + denom - 1) / denom; -} - - -static void -missing_chunk (mongoc_gridfs_file_t *file) -{ - bson_set_error (&file->error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - "missing chunk number %" PRId32, - file->n); - - if (file->cursor) { - mongoc_cursor_destroy (file->cursor); - file->cursor = NULL; - } -} - - -/** - * _mongoc_gridfs_file_refresh_page: - * - * Refresh a GridFS file's underlying page. This recalculates the current - * page number based on the file's stream position, then fetches that page - * from the database. - * - * Note that this fetch is unconditional and the page is queried from the - * database even if the current page covers the same theoretical chunk. - * - * - * Side Effects: - * - * file->page is loaded with the appropriate buffer, fetched from the - * database. If the file position is at the end of the file and on a new - * chunk boundary, a new page is created. If the position is far past the - * end of the file, _mongoc_gridfs_file_extend is responsible for creating - * chunks to file the gap. - * - * file->n is set based on file->pos. file->error is set on error. - */ -static bool -_mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file) -{ - bson_t query; - bson_t child; - bson_t opts; - const bson_t *chunk; - const char *key; - bson_iter_t iter; - int64_t existing_chunks; - int64_t required_chunks; - - const uint8_t *data = NULL; - uint32_t len; - - ENTRY; - - BSON_ASSERT (file); - - file->n = (int32_t) (file->pos / file->chunk_size); - - if (file->page) { - _mongoc_gridfs_file_page_destroy (file->page); - file->page = NULL; - } - - /* if the file pointer is past the end of the current file (i.e. pointing to - * a new chunk), we'll pass the page constructor a new empty page. */ - existing_chunks = divide_round_up (file->length, file->chunk_size); - required_chunks = divide_round_up (file->pos + 1, file->chunk_size); - if (required_chunks > existing_chunks) { - data = (uint8_t *) ""; - len = 0; - } else { - /* if we have a cursor, but the cursor doesn't have the chunk we're going - * to need, destroy it (we'll grab a new one immediately there after) */ - if (file->cursor && !_mongoc_gridfs_file_keep_cursor (file)) { - mongoc_cursor_destroy (file->cursor); - file->cursor = NULL; - } - - if (!file->cursor) { - bson_init (&query); - BSON_APPEND_VALUE (&query, "files_id", &file->files_id); - BSON_APPEND_DOCUMENT_BEGIN (&query, "n", &child); - BSON_APPEND_INT32 (&child, "$gte", file->n); - bson_append_document_end (&query, &child); - - bson_init (&opts); - BSON_APPEND_DOCUMENT_BEGIN (&opts, "sort", &child); - BSON_APPEND_INT32 (&child, "n", 1); - bson_append_document_end (&opts, &child); - - BSON_APPEND_DOCUMENT_BEGIN (&opts, "projection", &child); - BSON_APPEND_INT32 (&child, "n", 1); - BSON_APPEND_INT32 (&child, "data", 1); - BSON_APPEND_INT32 (&child, "_id", 0); - bson_append_document_end (&opts, &child); - - /* find all chunks greater than or equal to our current file pos */ - file->cursor = mongoc_collection_find_with_opts ( - file->gridfs->chunks, &query, &opts, NULL); - - file->cursor_range[0] = file->n; - file->cursor_range[1] = (uint32_t) (file->length / file->chunk_size); - - bson_destroy (&query); - bson_destroy (&opts); - - BSON_ASSERT (file->cursor); - } - - /* we might have had a cursor before, then seeked ahead past a chunk. - * iterate until we're on the right chunk */ - while (file->cursor_range[0] <= file->n) { - if (!mongoc_cursor_next (file->cursor, &chunk)) { - /* copy cursor error; if there's none, we're missing a chunk */ - if (!mongoc_cursor_error (file->cursor, &file->error)) { - missing_chunk (file); - } - - RETURN (0); - } - - file->cursor_range[0]++; - } - - BSON_ASSERT (bson_iter_init (&iter, chunk)); - - /* grab out what we need from the chunk */ - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - - if (strcmp (key, "n") == 0) { - if (file->n != bson_iter_int32 (&iter)) { - missing_chunk (file); - RETURN (0); - } - } else if (strcmp (key, "data") == 0) { - bson_iter_binary (&iter, NULL, &len, &data); - } else { - /* Unexpected key. This should never happen */ - RETURN (0); - } - } - - if (file->n != file->pos / file->chunk_size) { - return 0; - } - } - - if (!data) { - bson_set_error (&file->error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - "corrupt chunk number %" PRId32, - file->n); - RETURN (0); - } - - if (len > file->chunk_size) { - bson_set_error (&file->error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CORRUPT, - "corrupt chunk number %" PRId32 ": bad size", - file->n); - RETURN (0); - } - - file->page = _mongoc_gridfs_file_page_new (data, len, file->chunk_size); - - /* seek in the page towards wherever we're supposed to be */ - RETURN ( - _mongoc_gridfs_file_page_seek (file->page, file->pos % file->chunk_size)); -} - - -/** - * mongoc_gridfs_file_seek: - * - * Adjust the file position pointer in `file` by `delta`, starting from the - * position `whence`. The `whence` argument is interpreted as in fseek(2): - * - * SEEK_SET Set the position relative to the start of the file. - * SEEK_CUR Move `delta` from the current file position. - * SEEK_END Move `delta` from the end-of-file. - * - * Parameters: - * - * @file: A mongoc_gridfs_file_t. - * @delta: The amount to move. May be positive or negative. - * @whence: One of SEEK_SET, SEEK_CUR or SEEK_END. - * - * Errors: - * - * [EINVAL] `whence` is not one of SEEK_SET, SEEK_CUR or SEEK_END. - * [EINVAL] Resulting file position would be negative. - * - * Side Effects: - * - * On success, the file's underlying position pointer is set appropriately. - * On failure, the file position is NOT changed and errno is set. - * - * Returns: - * - * 0 on success. - * -1 on error, and errno set to indicate the error. - */ -int -mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, int64_t delta, int whence) -{ - int64_t offset; - - BSON_ASSERT (file); - - switch (whence) { - case SEEK_SET: - offset = delta; - break; - case SEEK_CUR: - offset = file->pos + delta; - break; - case SEEK_END: - offset = file->length + delta; - break; - default: - errno = EINVAL; - return -1; - - break; - } - - if (offset < 0) { - errno = EINVAL; - return -1; - } - - if (offset / file->chunk_size != file->n) { - /** no longer on the same page */ - - if (file->page) { - if (_mongoc_gridfs_file_page_is_dirty (file->page)) { - if (!_mongoc_gridfs_file_flush_page (file)) { - return -1; - } - } else { - _mongoc_gridfs_file_page_destroy (file->page); - file->page = NULL; - } - } - - /** we'll pick up the seek when we fetch a page on the next action. We - * lazily load */ - } else if (file->page) { - BSON_ASSERT ( - _mongoc_gridfs_file_page_seek (file->page, offset % file->chunk_size)); - } - - file->pos = offset; - file->n = file->pos / file->chunk_size; - - return 0; -} - -uint64_t -mongoc_gridfs_file_tell (mongoc_gridfs_file_t *file) -{ - BSON_ASSERT (file); - - return file->pos; -} - -bool -mongoc_gridfs_file_error (mongoc_gridfs_file_t *file, bson_error_t *error) -{ - BSON_ASSERT (file); - BSON_ASSERT (error); - - if (BSON_UNLIKELY (file->error.domain)) { - bson_set_error (error, - file->error.domain, - file->error.code, - "%s", - file->error.message); - RETURN (true); - } - - RETURN (false); -} - -const bson_value_t * -mongoc_gridfs_file_get_id (mongoc_gridfs_file_t *file) -{ - BSON_ASSERT (file); - - return &file->files_id; -} - -int64_t -mongoc_gridfs_file_get_length (mongoc_gridfs_file_t *file) -{ - BSON_ASSERT (file); - - return file->length; -} - -int32_t -mongoc_gridfs_file_get_chunk_size (mongoc_gridfs_file_t *file) -{ - BSON_ASSERT (file); - - return file->chunk_size; -} - -int64_t -mongoc_gridfs_file_get_upload_date (mongoc_gridfs_file_t *file) -{ - BSON_ASSERT (file); - - return file->upload_date; -} - -bool -mongoc_gridfs_file_remove (mongoc_gridfs_file_t *file, bson_error_t *error) -{ - bson_t sel = BSON_INITIALIZER; - bool ret = false; - - BSON_ASSERT (file); - - BSON_APPEND_VALUE (&sel, "_id", &file->files_id); - - if (!mongoc_collection_delete_one ( - file->gridfs->files, &sel, NULL, NULL, error)) { - goto cleanup; - } - - bson_reinit (&sel); - BSON_APPEND_VALUE (&sel, "files_id", &file->files_id); - - if (!mongoc_collection_delete_many ( - file->gridfs->chunks, &sel, NULL, NULL, error)) { - goto cleanup; - } - - ret = true; - -cleanup: - bson_destroy (&sel); - - return ret; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file.h deleted file mode 100644 index 18d96e74cac388e5b2216c5866099b97f4f88844..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-file.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_FILE_H -#define MONGOC_GRIDFS_FILE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-socket.h" - -BSON_BEGIN_DECLS - - -#define MONGOC_GRIDFS_FILE_STR_HEADER(name) \ - MONGOC_EXPORT (const char *) \ - mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t *file); \ - MONGOC_EXPORT (void) \ - mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t *file, const char *str); - - -#define MONGOC_GRIDFS_FILE_BSON_HEADER(name) \ - MONGOC_EXPORT (const bson_t *) \ - mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t *file); \ - MONGOC_EXPORT (void) \ - mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t *file, \ - const bson_t *bson); - - -typedef struct _mongoc_gridfs_file_t mongoc_gridfs_file_t; -typedef struct _mongoc_gridfs_file_opt_t mongoc_gridfs_file_opt_t; - - -struct _mongoc_gridfs_file_opt_t { - const char *md5; - const char *filename; - const char *content_type; - const bson_t *aliases; - const bson_t *metadata; - uint32_t chunk_size; -}; - - -MONGOC_GRIDFS_FILE_STR_HEADER (md5) -MONGOC_GRIDFS_FILE_STR_HEADER (filename) -MONGOC_GRIDFS_FILE_STR_HEADER (content_type) -MONGOC_GRIDFS_FILE_BSON_HEADER (aliases) -MONGOC_GRIDFS_FILE_BSON_HEADER (metadata) - - -MONGOC_EXPORT (const bson_value_t *) -mongoc_gridfs_file_get_id (mongoc_gridfs_file_t *file); - -MONGOC_EXPORT (int64_t) -mongoc_gridfs_file_get_length (mongoc_gridfs_file_t *file); - -MONGOC_EXPORT (int32_t) -mongoc_gridfs_file_get_chunk_size (mongoc_gridfs_file_t *file); - -MONGOC_EXPORT (int64_t) -mongoc_gridfs_file_get_upload_date (mongoc_gridfs_file_t *file); - -MONGOC_EXPORT (ssize_t) -mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, - const mongoc_iovec_t *iov, - size_t iovcnt, - uint32_t timeout_msec); -MONGOC_EXPORT (ssize_t) -mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - uint32_t timeout_msec); -MONGOC_EXPORT (int) -mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, int64_t delta, int whence); - -MONGOC_EXPORT (uint64_t) -mongoc_gridfs_file_tell (mongoc_gridfs_file_t *file); - -MONGOC_EXPORT (bool) -mongoc_gridfs_file_set_id (mongoc_gridfs_file_t *file, - const bson_value_t *id, - bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_gridfs_file_save (mongoc_gridfs_file_t *file); - -MONGOC_EXPORT (void) -mongoc_gridfs_file_destroy (mongoc_gridfs_file_t *file); - -MONGOC_EXPORT (bool) -mongoc_gridfs_file_error (mongoc_gridfs_file_t *file, bson_error_t *error); - -MONGOC_EXPORT (bool) -mongoc_gridfs_file_remove (mongoc_gridfs_file_t *file, bson_error_t *error); - -BSON_END_DECLS - -#endif /* MONGOC_GRIDFS_FILE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-private.h deleted file mode 100644 index 2f75810af83c484e75d666f21b6d1eba863bfb75..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs-private.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_PRIVATE_H -#define MONGOC_GRIDFS_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-client.h" - - -BSON_BEGIN_DECLS - - -struct _mongoc_gridfs_t { - mongoc_client_t *client; - mongoc_collection_t *files; - mongoc_collection_t *chunks; -}; - - -mongoc_gridfs_t * -_mongoc_gridfs_new (mongoc_client_t *client, - const char *db, - const char *prefix, - bson_error_t *error); - - -BSON_END_DECLS - - -#endif /* MONGOC_GRIDFS_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs.c deleted file mode 100644 index f755a32614e0d05ca536a6acae002057ad7f3ede..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright 2013 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. - */ - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "gridfs" - -#include "mongoc/mongoc-bulk-operation.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-index.h" -#include "mongoc/mongoc-gridfs.h" -#include "mongoc/mongoc-gridfs-private.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-gridfs-file-private.h" -#include "mongoc/mongoc-gridfs-file-list.h" -#include "mongoc/mongoc-gridfs-file-list-private.h" -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-util-private.h" - -#define MONGOC_GRIDFS_STREAM_CHUNK 4096 - - -/** - * _mongoc_gridfs_ensure_index: - * - * ensure gridfs indexes - * - * Ensure fast searches for chunks via [ files_id, n ] - * Ensure fast searches for files via [ filename ] - */ -static bool -_mongoc_gridfs_ensure_index (mongoc_gridfs_t *gridfs, bson_error_t *error) -{ - bson_t keys; - mongoc_index_opt_t opt; - bool r; - - ENTRY; - - bson_init (&keys); - - bson_append_int32 (&keys, "files_id", -1, 1); - bson_append_int32 (&keys, "n", -1, 1); - - mongoc_index_opt_init (&opt); - opt.unique = 1; - - BEGIN_IGNORE_DEPRECATIONS - r = mongoc_collection_create_index (gridfs->chunks, &keys, &opt, error); - END_IGNORE_DEPRECATIONS - - bson_destroy (&keys); - - if (!r) { - RETURN (r); - } - - bson_init (&keys); - - bson_append_int32 (&keys, "filename", -1, 1); - bson_append_int32 (&keys, "uploadDate", -1, 1); - opt.unique = 0; - - BEGIN_IGNORE_DEPRECATIONS - r = mongoc_collection_create_index (gridfs->files, &keys, &opt, error); - END_IGNORE_DEPRECATIONS - bson_destroy (&keys); - - if (!r) { - RETURN (r); - } - - RETURN (1); -} - - -mongoc_gridfs_t * -_mongoc_gridfs_new (mongoc_client_t *client, - const char *db, - const char *prefix, - bson_error_t *error) -{ - mongoc_gridfs_t *gridfs; - char buf[128]; - bool r; - uint32_t prefix_len; - - ENTRY; - - BSON_ASSERT (client); - BSON_ASSERT (db); - - if (!prefix) { - prefix = "fs"; - } - - /* make sure prefix is short enough to bucket the chunks and files - * collections - */ - prefix_len = (uint32_t) strlen (prefix); - BSON_ASSERT (prefix_len + sizeof (".chunks") < sizeof (buf)); - - gridfs = (mongoc_gridfs_t *) bson_malloc0 (sizeof *gridfs); - - gridfs->client = client; - - bson_snprintf (buf, sizeof (buf), "%s.chunks", prefix); - gridfs->chunks = mongoc_client_get_collection (client, db, buf); - - bson_snprintf (buf, sizeof (buf), "%s.files", prefix); - gridfs->files = mongoc_client_get_collection (client, db, buf); - - r = _mongoc_gridfs_ensure_index (gridfs, error); - - if (!r) { - mongoc_gridfs_destroy (gridfs); - RETURN (NULL); - } - - RETURN (gridfs); -} - - -bool -mongoc_gridfs_drop (mongoc_gridfs_t *gridfs, bson_error_t *error) -{ - bool r; - - ENTRY; - - r = mongoc_collection_drop (gridfs->files, error); - if (!r) { - RETURN (0); - } - - r = mongoc_collection_drop (gridfs->chunks, error); - if (!r) { - RETURN (0); - } - - RETURN (1); -} - - -void -mongoc_gridfs_destroy (mongoc_gridfs_t *gridfs) -{ - ENTRY; - - if (!gridfs) { - EXIT; - } - - mongoc_collection_destroy (gridfs->files); - mongoc_collection_destroy (gridfs->chunks); - - bson_free (gridfs); - - EXIT; -} - - -/** find all matching gridfs files */ -mongoc_gridfs_file_list_t * -mongoc_gridfs_find (mongoc_gridfs_t *gridfs, const bson_t *query) -{ - return _mongoc_gridfs_file_list_new (gridfs, query, 0); -} - - -/** find a single gridfs file */ -mongoc_gridfs_file_t * -mongoc_gridfs_find_one (mongoc_gridfs_t *gridfs, - const bson_t *query, - bson_error_t *error) -{ - mongoc_gridfs_file_list_t *list; - mongoc_gridfs_file_t *file; - - ENTRY; - - list = _mongoc_gridfs_file_list_new (gridfs, query, 1); - - file = mongoc_gridfs_file_list_next (list); - if (!mongoc_gridfs_file_list_error (list, error) && error) { - /* no error, but an error out-pointer was provided - clear it */ - memset (error, 0, sizeof (*error)); - } - - mongoc_gridfs_file_list_destroy (list); - - RETURN (file); -} - - -/** find all matching gridfs files */ -mongoc_gridfs_file_list_t * -mongoc_gridfs_find_with_opts (mongoc_gridfs_t *gridfs, - const bson_t *filter, - const bson_t *opts) -{ - return _mongoc_gridfs_file_list_new_with_opts (gridfs, filter, opts); -} - - -/** find a single gridfs file */ -mongoc_gridfs_file_t * -mongoc_gridfs_find_one_with_opts (mongoc_gridfs_t *gridfs, - const bson_t *filter, - const bson_t *opts, - bson_error_t *error) -{ - mongoc_gridfs_file_list_t *list; - mongoc_gridfs_file_t *file; - bson_t new_opts; - - ENTRY; - - bson_init (&new_opts); - - if (opts) { - bson_copy_to_excluding_noinit (opts, &new_opts, "limit", (char *) NULL); - } - - BSON_APPEND_INT32 (&new_opts, "limit", 1); - - list = _mongoc_gridfs_file_list_new_with_opts (gridfs, filter, &new_opts); - file = mongoc_gridfs_file_list_next (list); - - if (!mongoc_gridfs_file_list_error (list, error) && error) { - /* no error, but an error out-pointer was provided - clear it */ - memset (error, 0, sizeof (*error)); - } - - mongoc_gridfs_file_list_destroy (list); - bson_destroy (&new_opts); - - RETURN (file); -} - - -/** find a single gridfs file by filename */ -mongoc_gridfs_file_t * -mongoc_gridfs_find_one_by_filename (mongoc_gridfs_t *gridfs, - const char *filename, - bson_error_t *error) -{ - mongoc_gridfs_file_t *file; - - bson_t filter; - - bson_init (&filter); - - bson_append_utf8 (&filter, "filename", -1, filename, -1); - - file = mongoc_gridfs_find_one_with_opts (gridfs, &filter, NULL, error); - - bson_destroy (&filter); - - return file; -} - - -/** create a gridfs file from a stream - * - * The stream is fully consumed in creating the file - */ -mongoc_gridfs_file_t * -mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t *gridfs, - mongoc_stream_t *stream, - mongoc_gridfs_file_opt_t *opt) -{ - mongoc_gridfs_file_t *file; - ssize_t r; - uint8_t buf[MONGOC_GRIDFS_STREAM_CHUNK]; - mongoc_iovec_t iov; - int timeout; - - ENTRY; - - BSON_ASSERT (gridfs); - BSON_ASSERT (stream); - - iov.iov_base = (void *) buf; - iov.iov_len = 0; - - file = _mongoc_gridfs_file_new (gridfs, opt); - timeout = gridfs->client->cluster.sockettimeoutms; - - for (;;) { - r = mongoc_stream_read ( - stream, iov.iov_base, MONGOC_GRIDFS_STREAM_CHUNK, 0, timeout); - - if (r > 0) { - iov.iov_len = r; - if (mongoc_gridfs_file_writev (file, &iov, 1, timeout) < 0) { - MONGOC_ERROR ("%s", file->error.message); - mongoc_gridfs_file_destroy (file); - RETURN (NULL); - } - } else if (r == 0) { - break; - } else { - MONGOC_ERROR ("Error reading from GridFS file source stream"); - mongoc_gridfs_file_destroy (file); - RETURN (NULL); - } - } - - mongoc_stream_failed (stream); - - if (-1 == mongoc_gridfs_file_seek (file, 0, SEEK_SET)) { - MONGOC_ERROR ("%s", file->error.message); - mongoc_gridfs_file_destroy (file); - RETURN (NULL); - } - - RETURN (file); -} - - -/** create an empty gridfs file */ -mongoc_gridfs_file_t * -mongoc_gridfs_create_file (mongoc_gridfs_t *gridfs, - mongoc_gridfs_file_opt_t *opt) -{ - mongoc_gridfs_file_t *file; - - ENTRY; - - BSON_ASSERT (gridfs); - - file = _mongoc_gridfs_file_new (gridfs, opt); - - RETURN (file); -} - -/** accessor functions for collections */ -mongoc_collection_t * -mongoc_gridfs_get_files (mongoc_gridfs_t *gridfs) -{ - BSON_ASSERT (gridfs); - - return gridfs->files; -} - -mongoc_collection_t * -mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs) -{ - BSON_ASSERT (gridfs); - - return gridfs->chunks; -} - - -bool -mongoc_gridfs_remove_by_filename (mongoc_gridfs_t *gridfs, - const char *filename, - bson_error_t *error) -{ - mongoc_bulk_operation_t *bulk_files = NULL; - mongoc_bulk_operation_t *bulk_chunks = NULL; - mongoc_cursor_t *cursor = NULL; - bson_error_t files_error; - bson_error_t chunks_error; - const bson_t *doc; - const char *key; - char keybuf[16]; - int count = 0; - bool chunks_ret; - bool files_ret; - bool ret = false; - bson_iter_t iter; - bson_t *files_q = NULL; - bson_t *chunks_q = NULL; - bson_t find_filter = BSON_INITIALIZER; - bson_t find_opts = BSON_INITIALIZER; - bson_t find_opts_project; - bson_t ar = BSON_INITIALIZER; - bson_t opts = BSON_INITIALIZER; - - BSON_ASSERT (gridfs); - - if (!filename) { - bson_set_error (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_INVALID_FILENAME, - "A non-NULL filename must be specified."); - return false; - } - - /* - * Find all files matching this filename. Hopefully just one, but not - * strictly required! - */ - - BSON_APPEND_UTF8 (&find_filter, "filename", filename); - BSON_APPEND_DOCUMENT_BEGIN (&find_opts, "projection", &find_opts_project); - BSON_APPEND_INT32 (&find_opts_project, "_id", 1); - bson_append_document_end (&find_opts, &find_opts_project); - - cursor = _mongoc_cursor_find_new (gridfs->client, - gridfs->files->ns, - &find_filter, - &find_opts, - NULL /* user_prefs */, - NULL /* default_prefs */, - NULL /* read_concern */); - - BSON_ASSERT (cursor); - - while (mongoc_cursor_next (cursor, &doc)) { - if (bson_iter_init_find (&iter, doc, "_id")) { - const bson_value_t *value = bson_iter_value (&iter); - - bson_uint32_to_string (count, &key, keybuf, sizeof keybuf); - BSON_APPEND_VALUE (&ar, key, value); - } - } - - if (mongoc_cursor_error (cursor, error)) { - goto failure; - } - - bson_append_bool (&opts, "ordered", 7, false); - bulk_files = - mongoc_collection_create_bulk_operation_with_opts (gridfs->files, &opts); - bulk_chunks = - mongoc_collection_create_bulk_operation_with_opts (gridfs->chunks, &opts); - - bson_destroy (&opts); - - files_q = BCON_NEW ("_id", "{", "$in", BCON_ARRAY (&ar), "}"); - chunks_q = BCON_NEW ("files_id", "{", "$in", BCON_ARRAY (&ar), "}"); - - mongoc_bulk_operation_remove (bulk_files, files_q); - mongoc_bulk_operation_remove (bulk_chunks, chunks_q); - - files_ret = mongoc_bulk_operation_execute (bulk_files, NULL, &files_error); - chunks_ret = - mongoc_bulk_operation_execute (bulk_chunks, NULL, &chunks_error); - - if (error) { - if (!files_ret) { - memcpy (error, &files_error, sizeof *error); - } else if (!chunks_ret) { - memcpy (error, &chunks_error, sizeof *error); - } - } - - ret = (files_ret && chunks_ret); - -failure: - if (cursor) { - mongoc_cursor_destroy (cursor); - } - if (bulk_files) { - mongoc_bulk_operation_destroy (bulk_files); - } - if (bulk_chunks) { - mongoc_bulk_operation_destroy (bulk_chunks); - } - bson_destroy (&find_filter); - bson_destroy (&find_opts); - bson_destroy (&ar); - if (files_q) { - bson_destroy (files_q); - } - if (chunks_q) { - bson_destroy (chunks_q); - } - - return ret; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs.h deleted file mode 100644 index 5ad6bcef67ad334236dc587217638c31bff6085f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-gridfs.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_GRIDFS_H -#define MONGOC_GRIDFS_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-gridfs-file-list.h" - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_gridfs_t mongoc_gridfs_t; - - -MONGOC_EXPORT (mongoc_gridfs_file_t *) -mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t *gridfs, - mongoc_stream_t *stream, - mongoc_gridfs_file_opt_t *opt); -MONGOC_EXPORT (mongoc_gridfs_file_t *) -mongoc_gridfs_create_file (mongoc_gridfs_t *gridfs, - mongoc_gridfs_file_opt_t *opt); -MONGOC_EXPORT (mongoc_gridfs_file_list_t *) -mongoc_gridfs_find (mongoc_gridfs_t *gridfs, const bson_t *query) - BSON_GNUC_DEPRECATED_FOR (mongoc_gridfs_find_with_opts); -MONGOC_EXPORT (mongoc_gridfs_file_t *) -mongoc_gridfs_find_one (mongoc_gridfs_t *gridfs, - const bson_t *query, - bson_error_t *error) - BSON_GNUC_DEPRECATED_FOR (mongoc_gridfs_find_one_with_opts); -MONGOC_EXPORT (mongoc_gridfs_file_list_t *) -mongoc_gridfs_find_with_opts (mongoc_gridfs_t *gridfs, - const bson_t *filter, - const bson_t *opts) BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (mongoc_gridfs_file_t *) -mongoc_gridfs_find_one_with_opts (mongoc_gridfs_t *gridfs, - const bson_t *filter, - const bson_t *opts, - bson_error_t *error) - BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (mongoc_gridfs_file_t *) -mongoc_gridfs_find_one_by_filename (mongoc_gridfs_t *gridfs, - const char *filename, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_gridfs_drop (mongoc_gridfs_t *gridfs, bson_error_t *error); -MONGOC_EXPORT (void) -mongoc_gridfs_destroy (mongoc_gridfs_t *gridfs); -MONGOC_EXPORT (mongoc_collection_t *) -mongoc_gridfs_get_files (mongoc_gridfs_t *gridfs); -MONGOC_EXPORT (mongoc_collection_t *) -mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs); -MONGOC_EXPORT (bool) -mongoc_gridfs_remove_by_filename (mongoc_gridfs_t *gridfs, - const char *filename, - bson_error_t *error); - - -BSON_END_DECLS - - -#endif /* MONGOC_GRIDFS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h deleted file mode 100644 index 0f65e8850b317746336625509bb8f440ef7665d9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" -#ifndef MONGOC_HANDSHAKE_COMPILER_PRIVATE_H -#define MONGOC_HANDSHAKE_COMPILER_PRIVATE_H - -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-util-private.h" - -/* - * Thanks to: - * http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros - */ - -#if defined(__clang__) -#define MONGOC_COMPILER "clang" -#define MONGOC_COMPILER_VERSION __clang_version__ -#elif defined(__ICC) || defined(__INTEL_COMPILER) -#define MONGOC_COMPILER "ICC" -#define MONGOC_COMPILER_VERSION __VERSION__ -#elif defined(__GNUC__) || defined(__GNUG__) -#define MONGOC_COMPILER "GCC" -#define MONGOC_COMPILER_VERSION __VERSION__ -#elif defined(__HP_cc) || defined(__HP_aCC) -#define MONGOC_COMPILER "aCC" -#define MONGOC_COMPILER_VERSION MONGOC_EVALUATE_STR (__HP_cc) -#elif defined(__IBMC__) || defined(__IBMCPP__) -#define MONGOC_COMPILER "xlc" -#define MONGOC_COMPILER_VERSION __xlc__ -#elif defined(_MSC_VER) -#define MONGOC_COMPILER "MSVC" -#define MONGOC_COMPILER_VERSION MONGOC_EVALUATE_STR (_MSC_VER) -#elif defined(__PGI) -#define MONGOC_COMPILER "Portland PGCC" -#define MONGOC_COMPILER_VERSION \ - MONGOC_EVALUATE_STR (__PGIC__) \ - "." MONGOC_EVALUATE_STR (__PGIC_MINOR) "." MONGOC_EVALUATE_STR ( \ - __PGIC_PATCHLEVEL__) -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -#define MONGOC_COMPILER "Solaris Studio" -#define MONGOC_COMPILER_VERSION MONGOC_EVALUATE_STR (__SUNPRO_C) -#elif defined(__PCC__) -/* Portable C Compiler. Version may not be available */ -#define MONGOC_COMPILER "PCC" -#else -#define MONGOC_COMPILER MONGOC_EVALUATE_STR (MONGOC_CC) -/* Not defining COMPILER_VERSION. We'll fall back to values set at - * configure-time */ -#endif - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-os-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-os-private.h deleted file mode 100644 index 6e966fddfbb64959585b8559bb1bd2f00064dffa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-os-private.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_HANDSHAKE_OS_PRIVATE -#define MONGOC_HANDSHAKE_OS_PRIVATE - -/* Based on tables from - * http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system - */ - -#if defined(_WIN32) || defined(__CYGWIN__) -#define MONGOC_OS_TYPE "Windows" -#if defined(__CYGWIN__) -#define MONGOC_OS_NAME "Cygwin" -#else -#define MONGOC_OS_NAME "Windows" -#endif - -/* osx and iphone defines __APPLE__ and __MACH__, but not __unix__ */ -#elif defined(__APPLE__) && defined(__MACH__) && !defined(__unix__) -#define MONGOC_OS_TYPE "Darwin" -#include <TargetConditionals.h> -#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR == 1 -#define MONGOC_OS_NAME "iOS Simulator" -#elif defined(TARGET_OS_IOS) && TARGET_OS_IOS == 1 -#define MONGOC_OS_NAME "iOS" -#elif defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1 -#define MONGOC_OS_NAME "macOS" -#elif defined(TARGET_OS_TV) && TARGET_OS_TV == 1 -#define MONGOC_OS_NAME "tvOS" -#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 -#define MONGOC_OS_NAME "watchOS" -#else -/* Fall back to uname () */ -#endif - -/* Need to check if __unix is defined since sun and hpux always have __unix, - * but not necessarily __unix__ defined. */ -#elif defined(__unix__) || defined(__unix) -#include <sys/param.h> -#if defined(__linux__) -#define MONGOC_OS_IS_LINUX -#if defined(__ANDROID__) -#define MONGOC_OS_TYPE "Linux (Android)" -#else -#define MONGOC_OS_TYPE "Linux" -#endif -/* Don't define OS_NAME. We'll scan the file system to determine distro. */ -#elif defined(BSD) -#define MONGOC_OS_TYPE "BSD" -#if defined(__FreeBSD__) -#define MONGOC_OS_NAME "FreeBSD" -#elif defined(__NetBSD__) -#define MONGOC_OS_NAME "NetBSD" -#elif defined(__OpenBSD__) -#define MONGOC_OS_NAME "OpenBSD" -#elif defined(__DragonFly__) -#define MONGOC_OS_NAME "DragonFlyBSD" -#else -/* Don't define OS_NAME. We'll use uname to figure it out. */ -#endif -#else -#define MONGOC_OS_TYPE "Unix" -#if defined(_AIX) -#define MONGOC_OS_NAME "AIX" -#elif defined(__sun) && defined(__SVR4) -#define MONGOC_OS_NAME "Solaris" -#elif defined(__hpux) -#define MONGOC_OS_NAME "HP-UX" -#else -/* Don't set OS name. We'll just fall back to uname. */ -#endif -#endif - -#endif - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-private.h deleted file mode 100644 index 0f5ab8a522658b98203bd2f9cefe7633578c3c0d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake-private.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_HANDSHAKE_PRIVATE_H -#define MONGOC_HANDSHAKE_PRIVATE_H - -#include <mongoc/mongoc.h> - -BSON_BEGIN_DECLS - -#define HANDSHAKE_FIELD "client" -#define HANDSHAKE_PLATFORM_FIELD "platform" - -#define HANDSHAKE_MAX_SIZE 512 - -#define HANDSHAKE_OS_TYPE_MAX 32 -#define HANDSHAKE_OS_NAME_MAX 32 -#define HANDSHAKE_OS_VERSION_MAX 32 -#define HANDSHAKE_OS_ARCHITECTURE_MAX 32 -#define HANDSHAKE_DRIVER_NAME_MAX 64 -#define HANDSHAKE_DRIVER_VERSION_MAX 32 -/* platform has no fixed max size. It can just occupy the remaining - * available space in the document. */ - -/* When adding a new field to mongoc-config.h.in, update this! */ -typedef enum { - /* The bit position (from the RHS) of each config flag. Do not reorder. */ - MONGOC_MD_FLAG_ENABLE_CRYPTO = 0, - MONGOC_MD_FLAG_ENABLE_CRYPTO_CNG, - MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO, - MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO, - MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE, - MONGOC_MD_FLAG_ENABLE_SASL, - MONGOC_MD_FLAG_ENABLE_SSL, - MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL, - MONGOC_MD_FLAG_ENABLE_SSL_SECURE_CHANNEL, - MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT, - MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES, - MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE, - MONGOC_MD_FLAG_HAVE_WEAK_SYMBOLS, - MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS, - MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL, - MONGOC_MD_FLAG_ENABLE_SASL_CYRUS, - MONGOC_MD_FLAG_ENABLE_SASL_SSPI, - MONGOC_MD_FLAG_HAVE_SOCKLEN, - MONGOC_MD_FLAG_ENABLE_COMPRESSION, - MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY, - MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB, - MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI_UNUSED, /* CDRIVER-2654 removed this . */ - MONGOC_MD_FLAG_ENABLE_RES_NSEARCH, - MONGOC_MD_FLAG_ENABLE_RES_NDESTROY, - MONGOC_MD_FLAG_ENABLE_RES_NCLOSE, - MONGOC_MD_FLAG_ENABLE_RES_SEARCH, - MONGOC_MD_FLAG_ENABLE_DNSAPI, - MONGOC_MD_FLAG_ENABLE_RDTSCP, - MONGOC_MD_FLAG_HAVE_SCHED_GETCPU, - MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS, - MONGOC_MD_FLAG_TRACE, - MONGOC_MD_FLAG_ENABLE_ICU, - MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION, - /* Add additional config flags here, above LAST_MONGOC_MD_FLAG. */ - LAST_MONGOC_MD_FLAG -} mongoc_handshake_config_flag_bit_t; - - -typedef struct _mongoc_handshake_t { - char *os_type; - char *os_name; - char *os_version; - char *os_architecture; - - char *driver_name; - char *driver_version; - char *platform; - char *compiler_info; - char *flags; - - bool frozen; -} mongoc_handshake_t; - -void -_mongoc_handshake_init (void); - -void -_mongoc_handshake_cleanup (void); - -bool -_mongoc_handshake_build_doc_with_application (bson_t *doc, - const char *application); - -void -_mongoc_handshake_freeze (void); - -mongoc_handshake_t * -_mongoc_handshake_get (void); - -bool -_mongoc_handshake_appname_is_valid (const char *appname); - -typedef struct { - bool scram_sha_256; - bool scram_sha_1; -} mongoc_handshake_sasl_supported_mechs_t; - -void -_mongoc_handshake_append_sasl_supported_mechs (const mongoc_uri_t *uri, - bson_t *ismaster); - -void -_mongoc_handshake_parse_sasl_supported_mechs ( - const bson_t *ismaster, - mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs); - -BSON_END_DECLS - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake.c deleted file mode 100644 index 50e7d772eb4b229038b4325beeca3f1b2ed10ad6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake.c +++ /dev/null @@ -1,704 +0,0 @@ -/* - * Copyright 2016 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 <bson/bson.h> - -#ifdef _POSIX_VERSION -#include <sys/utsname.h> -#endif - -#ifdef _WIN32 -#include <windows.h> -#endif - -#include "mongoc/mongoc-linux-distro-scanner-private.h" -#include "mongoc/mongoc-handshake.h" -#include "mongoc/mongoc-handshake-compiler-private.h" -#include "mongoc/mongoc-handshake-os-private.h" -#include "mongoc/mongoc-handshake-private.h" -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-version.h" -#include "mongoc/mongoc-util-private.h" - -/* - * Global handshake data instance. Initialized at startup from mongoc_init - * - * Can be modified by calls to mongoc_handshake_data_append - */ -static mongoc_handshake_t gMongocHandshake; - -/* - * Used for thread-safety in mongoc_handshake_data_append - */ -static bson_mutex_t gHandshakeLock; - -static void -_set_bit (uint8_t *bf, uint32_t byte_count, uint32_t bit) -{ - uint32_t byte = bit / 8; - uint32_t bit_of_byte = (bit) % 8; - /* byte 0 is the last location in bf. */ - bf[(byte_count - 1) - byte] |= 1u << bit_of_byte; -} - -/* returns a hex string for all config flag bits, which must be freed. */ -char * -_mongoc_handshake_get_config_hex_string (void) -{ - uint32_t byte_count; - uint8_t *bf; - bson_string_t *str; - int i; - - byte_count = (LAST_MONGOC_MD_FLAG + 7) / 8; /* ceil (num_bits / 8) */ - /* allocate enough bytes to fit all config bits. */ - bf = (uint8_t *) bson_malloc0 (byte_count); - -#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL - _set_bit (bf, byte_count, MONGOC_ENABLE_SSL_SECURE_CHANNEL); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO_CNG - _set_bit (bf, byte_count, MONGOC_ENABLE_CRYPTO_CNG); -#endif - -#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO); -#endif - -#ifdef MONGOC_ENABLE_SSL_OPENSSL - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO); -#endif - -#ifdef MONGOC_ENABLE_SSL - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SSL); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CRYPTO); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE); -#endif - -#ifdef MONGOC_ENABLE_SASL - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SASL); -#endif - -#ifdef MONGOC_HAVE_SASL_CLIENT_DONE - _set_bit (bf, byte_count, MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE); -#endif - -#ifdef MONGOC_NO_AUTOMATIC_GLOBALS - _set_bit (bf, byte_count, MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS); -#endif - -#ifdef MONGOC_EXPERIMENTAL_FEATURES - _set_bit (bf, byte_count, MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES); -#endif - -#ifdef MONGOC_ENABLE_SSL_LIBRESSL - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL); -#endif - -#ifdef MONGOC_ENABLE_SASL_CYRUS - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SASL_CYRUS); -#endif - -#ifdef MONGOC_ENABLE_SASL_SSPI - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SASL_SSPI); -#endif - -#ifdef MONGOC_HAVE_SOCKLEN - _set_bit (bf, byte_count, MONGOC_MD_FLAG_HAVE_SOCKLEN); -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_COMPRESSION); -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY); -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB); -#endif - -#ifdef MONGOC_HAVE_RES_NSEARCH - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RES_NSEARCH); -#endif - -#ifdef MONGOC_HAVE_RES_NDESTROY - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RES_NDESTROY); -#endif - -#ifdef MONGOC_HAVE_RES_NCLOSE - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RES_NCLOSE); -#endif - -#ifdef MONGOC_HAVE_RES_SEARCH - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RES_SEARCH); -#endif - -#ifdef MONGOC_HAVE_DNSAPI - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_DNSAPI); -#endif - -#ifdef MONGOC_HAVE_RDTSCP - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_RDTSCP); -#endif - -#ifdef MONGOC_HAVE_SCHED_GETCPU - _set_bit (bf, byte_count, MONGOC_MD_FLAG_HAVE_SCHED_GETCPU); -#endif - -#ifdef MONGOC_ENABLE_SHM_COUNTERS - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS); -#endif - -#ifdef MONGOC_TRACE - _set_bit (bf, byte_count, MONGOC_MD_FLAG_TRACE); -#endif - -#ifdef MONGOC_ENABLE_ICU - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_ICU); -#endif - -#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION - _set_bit (bf, byte_count, MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION); -#endif - - str = bson_string_new ("0x"); - for (i = 0; i < byte_count; i++) { - bson_string_append_printf (str, "%02x", bf[i]); - } - bson_free (bf); - /* free the bson_string_t, but keep the underlying char* alive. */ - return bson_string_free (str, false); -} - -static char * -_get_os_type (void) -{ -#ifdef MONGOC_OS_TYPE - return bson_strndup (MONGOC_OS_TYPE, HANDSHAKE_OS_TYPE_MAX); -#else - return bson_strndup ("unknown", HANDSHAKE_OS_TYPE_MAX); -#endif -} - -static char * -_get_os_architecture (void) -{ - const char *ret = NULL; - -#ifdef _WIN32 - SYSTEM_INFO system_info; - DWORD arch; - GetSystemInfo (&system_info); - - arch = system_info.wProcessorArchitecture; - - switch (arch) { - case PROCESSOR_ARCHITECTURE_AMD64: - ret = "x86_64"; - break; - case PROCESSOR_ARCHITECTURE_ARM: - ret = "ARM"; - break; - case PROCESSOR_ARCHITECTURE_IA64: - ret = "IA64"; - break; - case PROCESSOR_ARCHITECTURE_INTEL: - ret = "x86"; - break; - case PROCESSOR_ARCHITECTURE_UNKNOWN: - ret = "Unknown"; - break; - default: - ret = "Other"; - break; - } - -#elif defined(_POSIX_VERSION) - struct utsname system_info; - - if (uname (&system_info) >= 0) { - ret = system_info.machine; - } - -#endif - - if (ret) { - return bson_strndup (ret, HANDSHAKE_OS_ARCHITECTURE_MAX); - } - - return NULL; -} - -#ifndef MONGOC_OS_IS_LINUX -static char * -_get_os_name (void) -{ -#ifdef MONGOC_OS_NAME - return bson_strndup (MONGOC_OS_NAME, HANDSHAKE_OS_NAME_MAX); -#elif defined(_POSIX_VERSION) - struct utsname system_info; - - if (uname (&system_info) >= 0) { - return bson_strndup (system_info.sysname, HANDSHAKE_OS_NAME_MAX); - } - -#endif - - return NULL; -} - -static char * -_get_os_version (void) -{ - char *ret = bson_malloc (HANDSHAKE_OS_VERSION_MAX); - bool found = false; - -#ifdef _WIN32 - OSVERSIONINFO osvi; - ZeroMemory (&osvi, sizeof (OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - - if (GetVersionEx (&osvi)) { - bson_snprintf (ret, - HANDSHAKE_OS_VERSION_MAX, - "%lu.%lu (%lu)", - osvi.dwMajorVersion, - osvi.dwMinorVersion, - osvi.dwBuildNumber); - found = true; - } else { - MONGOC_WARNING ("Error with GetVersionEx(): %lu", GetLastError ()); - } - -#elif defined(_POSIX_VERSION) - struct utsname system_info; - - if (uname (&system_info) >= 0) { - bson_strncpy (ret, system_info.release, HANDSHAKE_OS_VERSION_MAX); - found = true; - } else { - MONGOC_WARNING ("Error with uname(): %d", errno); - } - -#endif - - if (!found) { - bson_free (ret); - ret = NULL; - } - - return ret; -} -#endif - -static void -_get_system_info (mongoc_handshake_t *handshake) -{ - handshake->os_type = _get_os_type (); - -#ifdef MONGOC_OS_IS_LINUX - _mongoc_linux_distro_scanner_get_distro (&handshake->os_name, - &handshake->os_version); -#else - handshake->os_name = _get_os_name (); - handshake->os_version = _get_os_version (); -#endif - - handshake->os_architecture = _get_os_architecture (); -} - -static void -_free_system_info (mongoc_handshake_t *handshake) -{ - bson_free (handshake->os_type); - bson_free (handshake->os_name); - bson_free (handshake->os_version); - bson_free (handshake->os_architecture); -} - -static void -_get_driver_info (mongoc_handshake_t *handshake) -{ - handshake->driver_name = bson_strndup ("mongoc", HANDSHAKE_DRIVER_NAME_MAX); - handshake->driver_version = - bson_strndup (MONGOC_VERSION_S, HANDSHAKE_DRIVER_VERSION_MAX); -} - -static void -_free_driver_info (mongoc_handshake_t *handshake) -{ - bson_free (handshake->driver_name); - bson_free (handshake->driver_version); -} - -static void -_set_platform_string (mongoc_handshake_t *handshake) -{ - bson_string_t *str; - - str = bson_string_new (""); - - handshake->platform = bson_string_free (str, false); -} - -static void -_set_compiler_info (mongoc_handshake_t *handshake) -{ - bson_string_t *str; - char *config_str; - - str = bson_string_new (""); - - config_str = _mongoc_handshake_get_config_hex_string (); - bson_string_append_printf (str, "cfg=%s", config_str); - bson_free (config_str); - -#ifdef _POSIX_VERSION - bson_string_append_printf (str, " posix=%ld", _POSIX_VERSION); -#endif - -#ifdef __STDC_VERSION__ - bson_string_append_printf (str, " stdc=%ld", __STDC_VERSION__); -#endif - - bson_string_append_printf (str, " CC=%s", MONGOC_COMPILER); - -#ifdef MONGOC_COMPILER_VERSION - bson_string_append_printf (str, " %s", MONGOC_COMPILER_VERSION); -#endif - handshake->compiler_info = bson_string_free (str, false); -} - -static void -_set_flags (mongoc_handshake_t *handshake) -{ - bson_string_t *str; - - str = bson_string_new (""); - - if (strlen (MONGOC_EVALUATE_STR (MONGOC_USER_SET_CFLAGS)) > 0) { - bson_string_append_printf ( - str, " CFLAGS=%s", MONGOC_EVALUATE_STR (MONGOC_USER_SET_CFLAGS)); - } - - if (strlen (MONGOC_EVALUATE_STR (MONGOC_USER_SET_LDFLAGS)) > 0) { - bson_string_append_printf ( - str, " LDFLAGS=%s", MONGOC_EVALUATE_STR (MONGOC_USER_SET_LDFLAGS)); - } - - handshake->flags = bson_string_free (str, false); -} - -static void -_free_platform_string (mongoc_handshake_t *handshake) -{ - bson_free (handshake->platform); - bson_free (handshake->compiler_info); - bson_free (handshake->flags); -} - -void -_mongoc_handshake_init (void) -{ - _get_system_info (_mongoc_handshake_get ()); - _get_driver_info (_mongoc_handshake_get ()); - _set_platform_string (_mongoc_handshake_get ()); - _set_compiler_info (_mongoc_handshake_get ()); - _set_flags (_mongoc_handshake_get ()); - - _mongoc_handshake_get ()->frozen = false; - bson_mutex_init (&gHandshakeLock); -} - -void -_mongoc_handshake_cleanup (void) -{ - _free_system_info (_mongoc_handshake_get ()); - _free_driver_info (_mongoc_handshake_get ()); - _free_platform_string (_mongoc_handshake_get ()); - - bson_mutex_destroy (&gHandshakeLock); -} - -static void -_append_platform_field (bson_t *doc, const char *platform) -{ - int max_platform_str_size; - - char *compiler_info = _mongoc_handshake_get ()->compiler_info; - char *flags = _mongoc_handshake_get ()->flags; - bson_string_t *combined_platform = bson_string_new (platform); - - /* Compute space left for platform field */ - max_platform_str_size = - HANDSHAKE_MAX_SIZE - ((int) doc->len + - /* 1 byte for utf8 tag */ - 1 + - - /* key size */ - (int) strlen (HANDSHAKE_PLATFORM_FIELD) + - 1 + - - /* 4 bytes for length of string */ - 4); - - if (max_platform_str_size <= 0) { - return; - } - - /* We opt to drop compiler info and flags if they can't fit, while the - * platform information is truncated - * Try to drop flags first, and if there is still not enough space also drop - * compiler info */ - if (max_platform_str_size > - combined_platform->len + strlen (compiler_info) + 1) { - bson_string_append (combined_platform, compiler_info); - } - if (max_platform_str_size > combined_platform->len + strlen (flags) + 1) { - bson_string_append (combined_platform, flags); - } - - /* We use the flags_index field to check if the CLAGS/LDFLAGS need to be - * truncated, and if so we drop them altogether */ - bson_append_utf8 ( - doc, - HANDSHAKE_PLATFORM_FIELD, - -1, - combined_platform->str, - BSON_MIN (max_platform_str_size - 1, combined_platform->len)); - - bson_string_free (combined_platform, true); - BSON_ASSERT (doc->len <= HANDSHAKE_MAX_SIZE); -} - -/* - * Return true if we build the document, and it's not too big - * false if there's no way to prevent the doc from being too big. In this - * case, the caller shouldn't include it with isMaster - */ -bool -_mongoc_handshake_build_doc_with_application (bson_t *doc, const char *appname) -{ - const mongoc_handshake_t *md = _mongoc_handshake_get (); - bson_t child; - - if (appname) { - BSON_APPEND_DOCUMENT_BEGIN (doc, "application", &child); - BSON_APPEND_UTF8 (&child, "name", appname); - bson_append_document_end (doc, &child); - } - - BSON_APPEND_DOCUMENT_BEGIN (doc, "driver", &child); - BSON_APPEND_UTF8 (&child, "name", md->driver_name); - BSON_APPEND_UTF8 (&child, "version", md->driver_version); - bson_append_document_end (doc, &child); - - BSON_APPEND_DOCUMENT_BEGIN (doc, "os", &child); - - BSON_ASSERT (md->os_type); - BSON_APPEND_UTF8 (&child, "type", md->os_type); - - if (md->os_name) { - BSON_APPEND_UTF8 (&child, "name", md->os_name); - } - - if (md->os_version) { - BSON_APPEND_UTF8 (&child, "version", md->os_version); - } - - if (md->os_architecture) { - BSON_APPEND_UTF8 (&child, "architecture", md->os_architecture); - } - - bson_append_document_end (doc, &child); - - if (doc->len > HANDSHAKE_MAX_SIZE) { - /* We've done all we can possibly do to ensure the current - * document is below the maxsize, so if it overflows there is - * nothing else we can do, so we fail */ - return false; - } - - if (md->platform) { - _append_platform_field (doc, md->platform); - } - - return true; -} - -void -_mongoc_handshake_freeze (void) -{ - _mongoc_handshake_get ()->frozen = true; -} - -/* - * free (*s) and make *s point to *s concated with suffix. - * If *s is NULL it's treated like it's an empty string. - * If suffix is NULL, nothing happens. - */ -static void -_append_and_truncate (char **s, const char *suffix, int max_len) -{ - char *old_str = *s; - char *prefix; - const int delim_len = (int) strlen (" / "); - int space_for_suffix; - - BSON_ASSERT (s); - - prefix = old_str ? old_str : ""; - - if (!suffix) { - return; - } - - space_for_suffix = max_len - (int) strlen (prefix) - delim_len; - - if (space_for_suffix <= 0) { - /* the old string already takes the whole allotted space */ - return; - } - - *s = bson_strdup_printf ("%s / %.*s", prefix, space_for_suffix, suffix); - BSON_ASSERT (strlen (*s) <= max_len); - - bson_free (old_str); -} - - -/* - * Set some values in our global handshake struct. These values will be sent - * to the server as part of the initial connection handshake (isMaster). - * If this function is called more than once, or after we've connected to a - * mongod, then it will do nothing and return false. It will return true if it - * successfully sets the values. - * - * All arguments are optional. - */ -bool -mongoc_handshake_data_append (const char *driver_name, - const char *driver_version, - const char *platform) -{ - int platform_space; - - bson_mutex_lock (&gHandshakeLock); - - if (_mongoc_handshake_get ()->frozen) { - bson_mutex_unlock (&gHandshakeLock); - return false; - } - - /* allow practically any size for "platform", we'll trim it down in - * _mongoc_handshake_build_doc_with_application */ - platform_space = - HANDSHAKE_MAX_SIZE - (int) strlen (_mongoc_handshake_get ()->platform); - - /* we check for an empty string as a special case to avoid an unnecessary - * delimiter being added in front of the string by _append_and_truncate */ - if (strcmp (_mongoc_handshake_get ()->platform, "") == 0) { - bson_free (_mongoc_handshake_get ()->platform); - _mongoc_handshake_get ()->platform = - bson_strdup_printf ("%.*s", platform_space, platform); - } else { - _append_and_truncate ( - &_mongoc_handshake_get ()->platform, platform, HANDSHAKE_MAX_SIZE); - } - - _append_and_truncate (&_mongoc_handshake_get ()->driver_name, - driver_name, - HANDSHAKE_DRIVER_NAME_MAX); - - _append_and_truncate (&_mongoc_handshake_get ()->driver_version, - driver_version, - HANDSHAKE_DRIVER_VERSION_MAX); - - _mongoc_handshake_freeze (); - bson_mutex_unlock (&gHandshakeLock); - - return true; -} - -mongoc_handshake_t * -_mongoc_handshake_get (void) -{ - return &gMongocHandshake; -} - -bool -_mongoc_handshake_appname_is_valid (const char *appname) -{ - return strlen (appname) <= MONGOC_HANDSHAKE_APPNAME_MAX; -} - -void -_mongoc_handshake_append_sasl_supported_mechs (const mongoc_uri_t *uri, - bson_t *cmd) -{ - const char *username; - char *db_user; - username = mongoc_uri_get_username (uri); - db_user = - bson_strdup_printf ("%s.%s", mongoc_uri_get_auth_source (uri), username); - bson_append_utf8 (cmd, "saslSupportedMechs", 18, db_user, -1); - bson_free (db_user); -} - -void -_mongoc_handshake_parse_sasl_supported_mechs ( - const bson_t *ismaster, - mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs) -{ - bson_iter_t iter; - memset (sasl_supported_mechs, 0, sizeof (*sasl_supported_mechs)); - if (bson_iter_init_find (&iter, ismaster, "saslSupportedMechs")) { - bson_iter_t array_iter; - if (BSON_ITER_HOLDS_ARRAY (&iter) && - bson_iter_recurse (&iter, &array_iter)) { - while (bson_iter_next (&array_iter)) { - if (BSON_ITER_HOLDS_UTF8 (&array_iter)) { - const char *mechanism_name = bson_iter_utf8 (&array_iter, NULL); - if (0 == strcmp (mechanism_name, "SCRAM-SHA-256")) { - sasl_supported_mechs->scram_sha_256 = true; - } else if (0 == strcmp (mechanism_name, "SCRAM-SHA-1")) { - sasl_supported_mechs->scram_sha_1 = true; - } - } - } - } - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake.h deleted file mode 100644 index 469b199d1fa307bdc549387b1c919a0048684f42..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-handshake.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_HANDSHAKE_H -#define MONGOC_HANDSHAKE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -#define MONGOC_HANDSHAKE_APPNAME_MAX 128 - -/** - * mongoc_handshake_data_append: - * - * This function is intended for use by drivers which wrap the C Driver. - * Calling this function will store the given strings as handshake data about - * the system and driver by appending them to the handshake data for the - * underlying C Driver. These values, along with other handshake data collected - * during mongoc_init will be sent to the server as part of the initial - * connection handshake in the "client" document. This function cannot be - * called more than once, or after a handshake has been initiated. - * - * The passed in strings are copied, and don't have to remain valid after the - * call to mongoc_handshake_data_append(). The driver may store truncated - * versions of the passed in strings. - * - * Note: - * This function allocates memory, and therefore caution should be used when - * using this in conjunction with bson_mem_set_vtable. If this function is - * called before bson_mem_set_vtable, then bson_mem_restore_vtable must be - * called before calling mongoc_cleanup. Failure to do so will result in - * memory being freed by the wrong allocator. - * - * - * @driver_name: An optional string storing the name of the wrapping driver - * @driver_version: An optional string storing the version of the wrapping - * driver. - * @platform: An optional string storing any information about the current - * platform, for example configure options or compile flags. - * - * - * Returns true if the given fields are set successfully. Otherwise, it returns - * false and logs an error. - * - * The default handshake data the driver sends with "isMaster" looks something - * like: - * client: { - * driver: { - * name: "mongoc", - * version: "1.5.0" - * }, - * os: {...}, - * platform: "CC=gcc CFLAGS=-Wall -pedantic" - * } - * - * If we call - * mongoc_handshake_data_append ("phongo", "1.1.8", "CC=clang") - * and it returns true, the driver sends handshake data like: - * client: { - * driver: { - * name: "mongoc / phongo", - * version: "1.5.0 / 1.1.8" - * }, - * os: {...}, - * platform: "CC=gcc CFLAGS=-Wall -pedantic / CC=clang" - * } - * - */ -MONGOC_EXPORT (bool) -mongoc_handshake_data_append (const char *driver_name, - const char *driver_version, - const char *platform); - -BSON_END_DECLS - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list-private.h deleted file mode 100644 index 69faf418b9458726245d6b30d8b987458b196597..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list-private.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_HOST_LIST_PRIVATE_H -#define MONGOC_HOST_LIST_PRIVATE_H - -#include "mongoc/mongoc-host-list.h" - - -BSON_BEGIN_DECLS - -mongoc_host_list_t * -_mongoc_host_list_push (const char *host, - uint16_t port, - int family, - mongoc_host_list_t *next); - -void -_mongoc_host_list_upsert (mongoc_host_list_t **list, - mongoc_host_list_t *new_host); - -mongoc_host_list_t * -_mongoc_host_list_copy (const mongoc_host_list_t *src, - mongoc_host_list_t *next); - -bool -_mongoc_host_list_from_string (mongoc_host_list_t *host_list, - const char *host_and_port); - -bool -_mongoc_host_list_from_string_with_err (mongoc_host_list_t *host_list, - const char *host_and_port, - bson_error_t *error); - -bool -_mongoc_host_list_from_hostport_with_err (mongoc_host_list_t *host_list, - const char *host, - uint16_t port, - bson_error_t *error); - -int -_mongoc_host_list_length (mongoc_host_list_t *list); - -bool -_mongoc_host_list_equal (const mongoc_host_list_t *host_a, - const mongoc_host_list_t *host_b); - -void -_mongoc_host_list_remove_host (mongoc_host_list_t **phosts, - const char *host, - uint16_t port); - -void -_mongoc_host_list_destroy_all (mongoc_host_list_t *host); - -BSON_END_DECLS - - -#endif /* MONGOC_HOST_LIST_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list.c deleted file mode 100644 index f2433161d588a6fe0dc6a5bd2938070a4fbdab2b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-host-list-private.h" -/* strcasecmp on windows */ -#include "mongoc/mongoc-util-private.h" -#include "mongoc/utlist.h" - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_host_list_push -- - * - * Add a host to the front of the list and return it. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -mongoc_host_list_t * -_mongoc_host_list_push (const char *host, - uint16_t port, - int family, - mongoc_host_list_t *next) -{ - mongoc_host_list_t *h; - - BSON_ASSERT (host); - - h = bson_malloc0 (sizeof (mongoc_host_list_t)); - bson_strncpy (h->host, host, sizeof h->host); - h->port = port; - bson_snprintf ( - h->host_and_port, sizeof h->host_and_port, "%s:%hu", host, port); - - h->family = family; - h->next = next; - - return h; -} - -static mongoc_host_list_t * -_mongoc_host_list_find_host_and_port (mongoc_host_list_t *hosts, - const char *host_and_port) -{ - mongoc_host_list_t *iter; - LL_FOREACH (hosts, iter) - { - BSON_ASSERT (iter); - - if (strcmp (iter->host_and_port, host_and_port) == 0) { - return iter; - } - } - - return NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_host_list_upsert -- - * - * If new_host is not already in list, add it to the end of list. - * - * Returns: - * Nothing. - * - * Side effects: - * Modifies new_host->next when inserting. - * - *-------------------------------------------------------------------------- - */ -void -_mongoc_host_list_upsert (mongoc_host_list_t **list, - mongoc_host_list_t *new_host) -{ - mongoc_host_list_t *link = NULL; - - BSON_ASSERT (list); - if (!new_host) { - return; - } - - link = _mongoc_host_list_find_host_and_port (*list, new_host->host_and_port); - - if (!link) { - link = bson_malloc0 (sizeof (mongoc_host_list_t)); - LL_APPEND (*list, link); - } else { - /* Make sure linking is preserved when copying data into final. */ - new_host->next = link->next; - } - - memcpy (link, new_host, sizeof (mongoc_host_list_t)); -} - - -/* Duplicates the elements of {src}, creating a new chain, - * optionally prepended to an existing chain {next}. - * - * Note that as a side-effect of the implementation, - * this reverses the order of src's copy in the destination. - */ -mongoc_host_list_t * -_mongoc_host_list_copy (const mongoc_host_list_t *src, mongoc_host_list_t *next) -{ - mongoc_host_list_t *h = NULL; - const mongoc_host_list_t *src_iter; - - LL_FOREACH (src, src_iter) - { - h = bson_malloc0 (sizeof (mongoc_host_list_t)); - memcpy (h, src_iter, sizeof (mongoc_host_list_t)); - - LL_PREPEND (next, h); - } - - return h; -} - -int -_mongoc_host_list_length (mongoc_host_list_t *list) -{ - mongoc_host_list_t *tmp; - int counter = 0; - - tmp = list; - while (tmp) { - tmp = tmp->next; - counter++; - } - - return counter; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_host_list_equal -- - * - * Check two hosts have the same domain (case-insensitive), port, - * and address family. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_host_list_equal (const mongoc_host_list_t *host_a, - const mongoc_host_list_t *host_b) -{ - return (!strcasecmp (host_a->host_and_port, host_b->host_and_port) && - host_a->family == host_b->family); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_host_list_destroy_all -- - * - * Destroy whole linked list of hosts. - * - *-------------------------------------------------------------------------- - */ -void -_mongoc_host_list_destroy_all (mongoc_host_list_t *host) -{ - mongoc_host_list_t *tmp; - - while (host) { - tmp = host->next; - bson_free (host); - host = tmp; - } -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_host_list_from_string -- - * - * Populate a mongoc_host_list_t from a fully qualified address - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_host_list_from_string (mongoc_host_list_t *link_, const char *address) -{ - bson_error_t error = {0}; - bool r = _mongoc_host_list_from_string_with_err (link_, address, &error); - if (!r) { - MONGOC_ERROR ("Could not parse address %s: %s", address, error.message); - return false; - } - return true; -} - -bool -_mongoc_host_list_from_string_with_err (mongoc_host_list_t *link_, - const char *address, - bson_error_t *error) -{ - char *close_bracket; - char *sport; - uint16_t port; - char *host; - bool ret; - bool ipv6 = false; - - close_bracket = strchr (address, ']'); - - /* if this is an ipv6 address. */ - if (close_bracket) { - /* if present, the port should immediately follow after ] */ - sport = strchr (close_bracket, ':'); - if (sport > close_bracket + 1) { - return false; - } - - /* otherwise ] should be the last char. */ - if (!sport && *(close_bracket + 1) != '\0') { - return false; - } - - if (*address != '[') { - return false; - } - - ipv6 = true; - } - /* otherwise, just find the first : */ - else { - sport = strchr (address, ':'); - } - - /* like "example.com:27019" or "[fe80::1]:27019", but not "[fe80::1]" */ - if (sport) { - if (sport == address) { - /* bad address like ":27017" */ - return false; - } - - if (!mongoc_parse_port (&port, sport + 1)) { - return false; - } - - /* if this is an ipv6 address, strip the [ and ] */ - if (ipv6) { - host = bson_strndup (address + 1, close_bracket - address - 1); - } else { - host = bson_strndup (address, sport - address); - } - } else { - /* if this is an ipv6 address, strip the [ and ] */ - if (ipv6) { - host = bson_strndup (address + 1, close_bracket - address - 1); - } else { - host = bson_strdup (address); - } - port = MONGOC_DEFAULT_PORT; - } - - ret = _mongoc_host_list_from_hostport_with_err (link_, host, port, error); - - bson_free (host); - - return ret; -} - -bool -_mongoc_host_list_from_hostport_with_err (mongoc_host_list_t *link_, - const char *host, - uint16_t port, - bson_error_t *error) -{ - size_t host_len = strlen (host); - link_->port = port; - - if (host_len == 0) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NAME_RESOLUTION, - "Empty hostname in URI"); - return false; - } - - if (host_len > BSON_HOST_NAME_MAX) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NAME_RESOLUTION, - "Hostname provided in URI is too long, max is %d chars", - BSON_HOST_NAME_MAX); - return false; - } - - bson_strncpy (link_->host, host, host_len + 1); - - /* like "fe80::1" or "::1" */ - if (strchr (host, ':')) { - link_->family = AF_INET6; - - mongoc_lowercase (link_->host, link_->host); - bson_snprintf (link_->host_and_port, - sizeof link_->host_and_port, - "[%s]:%hu", - link_->host, - link_->port); - - } else if (strchr (host, '/') && strstr (host, ".sock")) { - link_->family = AF_UNIX; - bson_strncpy (link_->host_and_port, link_->host, host_len + 1); - } else { - /* This is either an IPv4 or hostname. */ - link_->family = AF_UNSPEC; - - mongoc_lowercase (link_->host, link_->host); - bson_snprintf (link_->host_and_port, - sizeof link_->host_and_port, - "%s:%hu", - link_->host, - link_->port); - } - - link_->next = NULL; - return true; -} - -void -_mongoc_host_list_remove_host (mongoc_host_list_t **hosts, - const char *host, - uint16_t port) -{ - mongoc_host_list_t *current; - mongoc_host_list_t *prev = NULL; - - for (current = *hosts; current; prev = current, current = current->next) { - if ((current->port == port) && (strcmp (current->host, host) == 0)) { - /* Node found, unlink. */ - if (prev) { - prev->next = current->next; - } else { - /* No previous, unlinking at head. */ - *hosts = current->next; - } - bson_free (current); - break; - } - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list.h deleted file mode 100644 index 6280fac9f898c8a407dcf71fa528ccc15392894f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-host-list.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_HOST_LIST_H -#define MONGOC_HOST_LIST_H - -#include <bson/bson.h> - - -BSON_BEGIN_DECLS - - -#ifdef _POSIX_HOST_NAME_MAX -#define BSON_HOST_NAME_MAX _POSIX_HOST_NAME_MAX -#else -#define BSON_HOST_NAME_MAX 255 -#endif - - -typedef struct _mongoc_host_list_t mongoc_host_list_t; - - -struct _mongoc_host_list_t { - mongoc_host_list_t *next; - char host[BSON_HOST_NAME_MAX + 1]; - char host_and_port[BSON_HOST_NAME_MAX + 7]; - uint16_t port; - int family; - void *padding[4]; -}; - -BSON_END_DECLS - - -#endif /* MONGOC_HOST_LIST_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-index.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-index.c deleted file mode 100644 index 10bb6ea1f2a451dae0353b32161591540e7c4ba6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-index.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-index.h" -#include "mongoc/mongoc-trace-private.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "gridfs_index" - - -static mongoc_index_opt_t gMongocIndexOptDefault = { - 1, /* is_initialized */ - 0, /* background */ - 0, /* unique */ - NULL, /* name */ - 0, /* drop_dups */ - 0, /* sparse */ - -1, /* expire_after_seconds */ - -1, /* v */ - NULL, /* weights */ - NULL, /* default_language */ - NULL, /* language_override */ - NULL, /* mongoc_index_opt_geo_t geo_options */ - NULL, /* mongoc_index_opt_storage_t storage_options */ - NULL, /* partial_filter_expression */ - NULL, /* collation */ - {NULL} /* struct padding */ -}; - -static mongoc_index_opt_geo_t gMongocIndexOptGeoDefault = { - 26, /* twod_sphere_version */ - -90, /* twod_bits_precision */ - 90, /* twod_location_min */ - -1, /* twod_location_max */ - 2, /* haystack_bucket_size */ - {NULL} /* struct padding */ -}; - -static mongoc_index_opt_wt_t gMongocIndexOptWTDefault = { - {MONGOC_INDEX_STORAGE_OPT_WIREDTIGER}, /* mongoc_index_opt_storage_t */ - "", /* config_str */ - {NULL} /* struct padding */ -}; - -const mongoc_index_opt_t * -mongoc_index_opt_get_default (void) -{ - return &gMongocIndexOptDefault; -} - -const mongoc_index_opt_geo_t * -mongoc_index_opt_geo_get_default (void) -{ - return &gMongocIndexOptGeoDefault; -} - -const mongoc_index_opt_wt_t * -mongoc_index_opt_wt_get_default (void) -{ - return &gMongocIndexOptWTDefault; -} - -void -mongoc_index_opt_init (mongoc_index_opt_t *opt) -{ - BSON_ASSERT (opt); - - memcpy (opt, &gMongocIndexOptDefault, sizeof *opt); -} - -void -mongoc_index_opt_geo_init (mongoc_index_opt_geo_t *opt) -{ - BSON_ASSERT (opt); - - memcpy (opt, &gMongocIndexOptGeoDefault, sizeof *opt); -} - -void -mongoc_index_opt_wt_init (mongoc_index_opt_wt_t *opt) -{ - BSON_ASSERT (opt); - - memcpy (opt, &gMongocIndexOptWTDefault, sizeof *opt); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-index.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-index.h deleted file mode 100644 index 37bce83c93902ace60ea93b73b49bc5fa99626b0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-index.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_INDEX_H -#define MONGOC_INDEX_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - - -BSON_BEGIN_DECLS - -typedef struct { - uint8_t twod_sphere_version; - uint8_t twod_bits_precision; - double twod_location_min; - double twod_location_max; - double haystack_bucket_size; - uint8_t *padding[32]; -} mongoc_index_opt_geo_t; - -typedef struct { - int type; -} mongoc_index_opt_storage_t; - -typedef enum { - MONGOC_INDEX_STORAGE_OPT_MMAPV1, - MONGOC_INDEX_STORAGE_OPT_WIREDTIGER, -} mongoc_index_storage_opt_type_t; - -typedef struct { - mongoc_index_opt_storage_t base; - const char *config_str; - void *padding[8]; -} mongoc_index_opt_wt_t; - -typedef struct { - bool is_initialized; - bool background; - bool unique; - const char *name; - bool drop_dups; - bool sparse; - int32_t expire_after_seconds; - int32_t v; - const bson_t *weights; - const char *default_language; - const char *language_override; - mongoc_index_opt_geo_t *geo_options; - mongoc_index_opt_storage_t *storage_options; - const bson_t *partial_filter_expression; - const bson_t *collation; - void *padding[4]; -} mongoc_index_opt_t; - - -MONGOC_EXPORT (const mongoc_index_opt_t *) -mongoc_index_opt_get_default (void) BSON_GNUC_PURE; -MONGOC_EXPORT (const mongoc_index_opt_geo_t *) -mongoc_index_opt_geo_get_default (void) BSON_GNUC_PURE; -MONGOC_EXPORT (const mongoc_index_opt_wt_t *) -mongoc_index_opt_wt_get_default (void) BSON_GNUC_PURE; -MONGOC_EXPORT (void) -mongoc_index_opt_init (mongoc_index_opt_t *opt); -MONGOC_EXPORT (void) -mongoc_index_opt_geo_init (mongoc_index_opt_geo_t *opt); -MONGOC_EXPORT (void) -mongoc_index_opt_wt_init (mongoc_index_opt_wt_t *opt); - -BSON_END_DECLS - - -#endif /* MONGOC_INDEX_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-init.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-init.c deleted file mode 100644 index ec0b7384c9992f07951d250edbe6ad6978cc3edc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-init.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2013 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 <bson/bson.h> - -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-init.h" - -#include "mongoc/mongoc-handshake-private.h" - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -#include "mongoc/mongoc-openssl-private.h" -#elif defined(MONGOC_ENABLE_SSL_LIBRESSL) -#include "tls.h" -#endif -#include "mongoc/mongoc-thread-private.h" -#include "common-b64-private.h" -#if defined(MONGOC_ENABLE_CRYPTO_CNG) -#include "mongoc/mongoc-crypto-private.h" -#include "mongoc/mongoc-crypto-cng-private.h" -#endif - -#ifndef MONGOC_NO_AUTOMATIC_GLOBALS -#pragma message( \ - "Configure the driver with ENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF.\ - Automatic cleanup is deprecated and will be removed in version 2.0.") -#endif - -#ifdef MONGOC_ENABLE_SASL_CYRUS -#include <sasl/sasl.h> - -static void * -mongoc_cyrus_mutex_alloc (void) -{ - bson_mutex_t *mutex; - - mutex = (bson_mutex_t *) bson_malloc0 (sizeof (bson_mutex_t)); - bson_mutex_init (mutex); - - return (void *) mutex; -} - - -static int -mongoc_cyrus_mutex_lock (void *mutex) -{ - bson_mutex_lock ((bson_mutex_t *) mutex); - - return SASL_OK; -} - - -static int -mongoc_cyrus_mutex_unlock (void *mutex) -{ - bson_mutex_unlock ((bson_mutex_t *) mutex); - - return SASL_OK; -} - - -static void -mongoc_cyrus_mutex_free (void *mutex) -{ - bson_mutex_destroy ((bson_mutex_t *) mutex); - bson_free (mutex); -} - -#endif /* MONGOC_ENABLE_SASL_CYRUS */ - - -static BSON_ONCE_FUN (_mongoc_do_init) -{ -#ifdef MONGOC_ENABLE_SASL_CYRUS - int status; -#endif -#ifdef MONGOC_ENABLE_SSL_OPENSSL - _mongoc_openssl_init (); -#elif defined(MONGOC_ENABLE_SSL_LIBRESSL) - tls_init (); -#endif - -#ifdef MONGOC_ENABLE_SASL_CYRUS - /* The following functions should not use tracing, as they may be invoked - * before mongoc_log_set_handler() can complete. */ - sasl_set_mutex (mongoc_cyrus_mutex_alloc, - mongoc_cyrus_mutex_lock, - mongoc_cyrus_mutex_unlock, - mongoc_cyrus_mutex_free); - - status = sasl_client_init (NULL); - BSON_ASSERT (status == SASL_OK); -#endif - - _mongoc_counters_init (); - -#ifdef _WIN32 - { - WORD wVersionRequested; - WSADATA wsaData; - int err; - - wVersionRequested = MAKEWORD (2, 2); - - err = WSAStartup (wVersionRequested, &wsaData); - - /* check the version perhaps? */ - - BSON_ASSERT (err == 0); - } -#endif - -#if defined(MONGOC_ENABLE_CRYPTO_CNG) - mongoc_crypto_cng_init (); -#endif - - _mongoc_handshake_init (); - - BSON_ONCE_RETURN; -} - -void -mongoc_init (void) -{ - static bson_once_t once = BSON_ONCE_INIT; - bson_once (&once, _mongoc_do_init); -} - -static BSON_ONCE_FUN (_mongoc_do_cleanup) -{ -#ifdef MONGOC_ENABLE_SSL_OPENSSL - _mongoc_openssl_cleanup (); -#endif - -#ifdef MONGOC_ENABLE_SASL_CYRUS -#ifdef MONGOC_HAVE_SASL_CLIENT_DONE - sasl_client_done (); -#else - /* fall back to deprecated function */ - sasl_done (); -#endif -#endif - -#ifdef _WIN32 - WSACleanup (); -#endif - -#if defined(MONGOC_ENABLE_CRYPTO_CNG) - mongoc_crypto_cng_cleanup (); -#endif - - _mongoc_counters_cleanup (); - - _mongoc_handshake_cleanup (); - - BSON_ONCE_RETURN; -} - -void -mongoc_cleanup (void) -{ - static bson_once_t once = BSON_ONCE_INIT; - bson_once (&once, _mongoc_do_cleanup); -} - -/* - * On GCC, just use __attribute__((constructor)) to perform initialization - * automatically for the application. - */ -#if defined(__GNUC__) && !defined(MONGOC_NO_AUTOMATIC_GLOBALS) -static void -_mongoc_init_ctor (void) __attribute__ ((constructor)); -static void -_mongoc_init_ctor (void) -{ - mongoc_init (); -} - -static void -_mongoc_init_dtor (void) __attribute__ ((destructor)); -static void -_mongoc_init_dtor (void) -{ - bson_mem_restore_vtable (); - mongoc_cleanup (); -} -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-init.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-init.h deleted file mode 100644 index e792f2b5e50b27daf3f06f0697b91e206c95d6ec..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-init.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_INIT_H -#define MONGOC_INIT_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - - -MONGOC_EXPORT (void) -mongoc_init (void); -MONGOC_EXPORT (void) -mongoc_cleanup (void); - - -BSON_END_DECLS - - -#endif /* MONGOC_INIT_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-iovec.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-iovec.h deleted file mode 100644 index 34c5f25e4bcd6a95b514126c330c7da99a39d423..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-iovec.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_IOVEC_H -#define MONGOC_IOVEC_H - - -#include <bson/bson.h> - -#ifdef _WIN32 -#include <stddef.h> -#else -#include <sys/uio.h> -#endif - -BSON_BEGIN_DECLS - - -#ifdef _WIN32 -typedef struct { - size_t iov_len; - char *iov_base; -} mongoc_iovec_t; - -BSON_STATIC_ASSERT2 (sizeof_iovect_t, - sizeof (mongoc_iovec_t) == sizeof (WSABUF)); -BSON_STATIC_ASSERT2 (offsetof_iovec_base, - offsetof (mongoc_iovec_t, iov_base) == - offsetof (WSABUF, buf)); -BSON_STATIC_ASSERT2 (offsetof_iovec_len, - offsetof (mongoc_iovec_t, iov_len) == - offsetof (WSABUF, len)); - -#else -typedef struct iovec mongoc_iovec_t; -#endif - - -BSON_END_DECLS - - -#endif /* MONGOC_IOVEC_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-libressl-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-libressl-private.h deleted file mode 100644 index 1bf586ad09922217f287f50195c6ad3a42ae3d6a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-libressl-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_LIBRESSL_PRIVATE_H -#define MONGOC_LIBRESSL_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-stream-tls-libressl-private.h" -#include <tls.h> - - -BSON_BEGIN_DECLS - - -bool -mongoc_libressl_setup_ca (mongoc_stream_tls_libressl_t *libressl, - mongoc_ssl_opt_t *opt); -bool -mongoc_libressl_setup_certificate (mongoc_stream_tls_libressl_t *libressl, - mongoc_ssl_opt_t *opt); - -BSON_END_DECLS - - -#endif /* MONGOC_LIBRESSL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-libressl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-libressl.c deleted file mode 100644 index 96c2cfd86d4d5b0bdf919dea73ebeef758a9ec62..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-libressl.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_LIBRESSL - -#include <bson/bson.h> - -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-libressl-private.h" -#include "mongoc/mongoc-stream-tls-libressl-private.h" - -#include <tls.h> - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-libressl" - - -bool -mongoc_libressl_setup_certificate (mongoc_stream_tls_libressl_t *libressl, - mongoc_ssl_opt_t *opt) -{ - uint8_t *file; - size_t file_len; - - if (!opt->pem_file) { - return false; - } - - file = tls_load_file (opt->pem_file, &file_len, (char *) opt->pem_pwd); - if (!file) { - MONGOC_ERROR ("Cannot load private key: '%s'", opt->pem_file); - return false; - } - - if (tls_config_set_keypair_mem ( - libressl->config, file, file_len, file, file_len) == -1) { - MONGOC_ERROR ("%s", tls_config_error (libressl->config)); - return false; - } - - return true; -} - -bool -mongoc_libressl_setup_ca (mongoc_stream_tls_libressl_t *libressl, - mongoc_ssl_opt_t *opt) -{ - if (opt->ca_file) { - tls_config_set_ca_file (libressl->config, opt->ca_file); - } - if (opt->ca_dir) { - tls_config_set_ca_path (libressl->config, opt->ca_dir); - } - - - return true; -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h deleted file mode 100644 index 1c082d8af5dbd552a34da10d10c6eded361efacb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_LINUX_DISTRO_SCANNER_PRIVATE_H -#define MONGOC_LINUX_DISTRO_SCANNER_PRIVATE_H - -#include "mongoc/mongoc-handshake-os-private.h" - -#ifdef MONGOC_OS_IS_LINUX - -BSON_BEGIN_DECLS - -bool -_mongoc_linux_distro_scanner_get_distro (char **name, char **version); - -/* These functions are exposed so we can test them separately. */ -void -_mongoc_linux_distro_scanner_read_key_value_file (const char *path, - const char *name_key, - ssize_t name_key_len, - char **name, - const char *version_key, - ssize_t version_key_len, - char **version); -void -_mongoc_linux_distro_scanner_read_generic_release_file (const char **paths, - char **name, - char **version); -void -_mongoc_linux_distro_scanner_split_line_by_release (const char *line, - ssize_t line_len, - char **name, - char **version); -BSON_END_DECLS - -#endif - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c deleted file mode 100644 index 06241f82b357f87a64c88c73764c7c75601a5fe9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-handshake-os-private.h" - -#ifdef MONGOC_OS_IS_LINUX - -#include <stdio.h> -#include <sys/utsname.h> - -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-linux-distro-scanner-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-handshake-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-version.h" - -#define LINE_BUFFER_SIZE 1024 - -/* - * fgets() wrapper which removes '\n' at the end of the string - * Return 0 on failure or EOF. - */ -static size_t -_fgets_wrapper (char *buffer, size_t buffer_size, FILE *f) -{ - char *fgets_res; - size_t len; - - fgets_res = fgets (buffer, buffer_size, f); - - if (!fgets_res) { - /* Didn't read anything. Empty file or error. */ - if (ferror (f)) { - TRACE ("fgets() failed with error %d", errno); - } - - return 0; - } - - /* Chop off trailing \n */ - len = strlen (buffer); - - if (len > 0 && buffer[len - 1] == '\n') { - buffer[len - 1] = '\0'; - len--; - } else if (len == buffer_size - 1) { - /* We read buffer_size bytes without hitting a newline - * therefore the line is super long, so we say this file is invalid. - * This is important since if we are in this situation, the NEXT call to - * fgets() will keep reading where we left off. - * - * This protects us from files like: - * aaaaa...DISTRIB_ID=nasal demons - */ - TRACE ("Found line of length %ld, bailing out", len); - return 0; - } - - return len; -} - -static void -_process_line (const char *name_key, - size_t name_key_len, - char **name, - const char *version_key, - size_t version_key_len, - char **version, - const char *line, - size_t line_len) -{ - size_t key_len; - const char *equal_sign; - const char *value; - const char *needle = "="; - size_t value_len = 0; - - ENTRY; - - /* Figure out where = is. Everything before is the key, - * and everything after is the value */ - equal_sign = strstr (line, needle); - - if (equal_sign == NULL) { - TRACE ("Encountered malformed line: %s", line); - /* This line is malformed/incomplete, so skip it */ - EXIT; - } - - /* Should never happen since we null terminated this line */ - BSON_ASSERT (equal_sign < line + line_len); - - key_len = equal_sign - line; - value = equal_sign + strlen (needle); - value_len = strlen (value); - if (value_len > 2 && value[0] == '"' && value[value_len - 1] == '"') { - value_len -= 2; - value++; - } - - /* If we find two copies of either key, the *name == NULL check will fail - * so we will just keep the first value encountered. */ - if (name_key_len == key_len && strncmp (line, name_key, key_len) == 0 && - !(*name)) { - *name = bson_strndup (value, value_len); - TRACE ("Found name: %s", *name); - } else if (version_key_len == key_len && - strncmp (line, version_key, key_len) == 0 && !(*version)) { - *version = bson_strndup (value, value_len); - TRACE ("Found version: %s", *version); - } - - EXIT; -} - - -/* - * Parse a file of the form: - * KEY=VALUE - * Looking for name_key and version_key, and storing - * their values into *name and *version. - * The values in *name and *version must be freed with bson_free. - */ -void -_mongoc_linux_distro_scanner_read_key_value_file (const char *path, - const char *name_key, - ssize_t name_key_len, - char **name, - const char *version_key, - ssize_t version_key_len, - char **version) -{ - const int max_lines = 100; - int lines_read = 0; - char buffer[LINE_BUFFER_SIZE]; - size_t buflen; - FILE *f; - - ENTRY; - - *name = NULL; - *version = NULL; - - if (name_key_len < 0) { - name_key_len = strlen (name_key); - } - - if (version_key_len < 0) { - version_key_len = strlen (version_key); - } - - if (access (path, R_OK)) { - TRACE ("No permission to read from %s: errno: %d", path, errno); - EXIT; - } - - f = fopen (path, "r"); - - if (!f) { - TRACE ("fopen failed on %s: %d", path, errno); - EXIT; - } - - while (lines_read < max_lines) { - buflen = _fgets_wrapper (buffer, sizeof (buffer), f); - - if (buflen == 0) { - /* Error or eof */ - break; - } - - _process_line (name_key, - name_key_len, - name, - version_key, - version_key_len, - version, - buffer, - buflen); - - if (*version && *name) { - /* No point in reading any more */ - break; - } - - lines_read++; - } - - fclose (f); - EXIT; -} - -/* - * Find the first string in a list which is a valid file. Assumes - * passed in list is NULL terminated! - */ -const char * -_get_first_existing (const char **paths) -{ - const char **p = &paths[0]; - - ENTRY; - - for (; *p != NULL; p++) { - if (access (*p, F_OK)) { - /* Just doesn't exist */ - continue; - } - - if (access (*p, R_OK)) { - TRACE ("file %s exists, but cannot be read: error %d", *p, errno); - continue; - } - - RETURN (*p); - } - - RETURN (NULL); -} - - -/* - * Given a line of text, split it by the word "release." For example: - * Ubuntu release 14.04 => - * *name = Ubuntu - * *version = 14.04 - * If the word "release" isn't found then we put the whole string into *name - * (even if the string is empty). - */ -void -_mongoc_linux_distro_scanner_split_line_by_release (const char *line, - ssize_t line_len, - char **name, - char **version) -{ - const char *needle_loc; - const char *const needle = " release "; - const char *version_string; - - *name = NULL; - *version = NULL; - - if (line_len < 0) { - line_len = strlen (line); - } - - needle_loc = strstr (line, needle); - - if (!needle_loc) { - *name = bson_strdup (line); - return; - } else if (needle_loc == line) { - /* The file starts with the word " release " - * This file is weird enough we will just abandon it. */ - return; - } - - *name = bson_strndup (line, needle_loc - line); - - version_string = needle_loc + strlen (needle); - - if (version_string == line + line_len) { - /* Weird. The file just ended with "release " */ - return; - } - - *version = bson_strdup (version_string); -} - -/* - * Search for a *-release file, and read its contents. - */ -void -_mongoc_linux_distro_scanner_read_generic_release_file (const char **paths, - char **name, - char **version) -{ - const char *path; - size_t buflen; - char buffer[LINE_BUFFER_SIZE]; - FILE *f; - - ENTRY; - - *name = NULL; - *version = NULL; - - path = _get_first_existing (paths); - - if (!path) { - EXIT; - } - - f = fopen (path, "r"); - - if (!f) { - TRACE ("Found %s exists and readable but couldn't open: %d", path, errno); - EXIT; - } - - /* Read the first line of the file, look for the word "release" */ - buflen = _fgets_wrapper (buffer, sizeof (buffer), f); - - if (buflen > 0) { - TRACE ("Trying to split buffer with contents %s", buffer); - /* Try splitting the string. If we can't it'll store everything in - * *name. */ - _mongoc_linux_distro_scanner_split_line_by_release ( - buffer, buflen, name, version); - } - - fclose (f); - - EXIT; -} - -static void -_get_kernel_version_from_uname (char **version) -{ - struct utsname system_info; - - if (uname (&system_info) >= 0) { - *version = bson_strdup_printf ("kernel %s", system_info.release); - } else { - *version = NULL; - } -} - -/* - * Some boilerplate logic that tries to set *name and *version to new_name - * and new_version if it's not already set. Values of new_name and new_version - * should not be used after this call. - */ -static bool -_set_name_and_version_if_needed (char **name, - char **version, - char *new_name, - char *new_version) -{ - if (new_name && !(*name)) { - *name = new_name; - } else { - bson_free (new_name); - } - - if (new_version && !(*version)) { - *version = new_version; - } else { - bson_free (new_version); - } - - return (*name) && (*version); -} - -bool -_mongoc_linux_distro_scanner_get_distro (char **name, char **version) -{ - /* In case we decide to try looking up name/version again */ - char *new_name; - char *new_version; - const char *generic_release_paths[] = { - "/etc/redhat-release", - "/etc/novell-release", - "/etc/gentoo-release", - "/etc/SuSE-release", - "/etc/SUSE-release", - "/etc/sles-release", - "/etc/debian_release", - "/etc/slackware-version", - "/etc/centos-release", - NULL, - }; - - ENTRY; - - *name = NULL; - *version = NULL; - - _mongoc_linux_distro_scanner_read_key_value_file ( - "/etc/os-release", "NAME", -1, name, "VERSION_ID", -1, version); - - if (*name && *version) { - RETURN (true); - } - - _mongoc_linux_distro_scanner_read_key_value_file ("/etc/lsb-release", - "DISTRIB_ID", - -1, - &new_name, - "DISTRIB_RELEASE", - -1, - &new_version); - - if (_set_name_and_version_if_needed (name, version, new_name, new_version)) { - RETURN (true); - } - - /* Try to read from a generic release file */ - _mongoc_linux_distro_scanner_read_generic_release_file ( - generic_release_paths, &new_name, &new_version); - - if (_set_name_and_version_if_needed (name, version, new_name, new_version)) { - RETURN (true); - } - - if (*version == NULL) { - _get_kernel_version_from_uname (version); - } - - if (*name && *version) { - RETURN (true); - } - - bson_free (*name); - bson_free (*version); - - *name = NULL; - *version = NULL; - - RETURN (false); -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-list-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-list-private.h deleted file mode 100644 index 04a7e18dea6680ca3840e5c5c50f5b6710e1ff49..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-list-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_LIST_H -#define MONGOC_LIST_H - -#include <bson/bson.h> - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_list_t mongoc_list_t; - - -struct _mongoc_list_t { - mongoc_list_t *next; - void *data; -}; - - -mongoc_list_t * -_mongoc_list_append (mongoc_list_t *list, void *data); -mongoc_list_t * -_mongoc_list_prepend (mongoc_list_t *list, void *data); -mongoc_list_t * -_mongoc_list_remove (mongoc_list_t *list, void *data); -void -_mongoc_list_foreach (mongoc_list_t *list, - void (*func) (void *data, void *user_data), - void *user_data); -void -_mongoc_list_destroy (mongoc_list_t *list); - - -BSON_END_DECLS - - -#endif /* MONGOC_LIST_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-list.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-list.c deleted file mode 100644 index 60ba3e4c181163e3265144f803d8f02b61f31b66..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-list.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-list-private.h" - - -/** - * mongoc_list_append: - * @list: A list to append to, or NULL. - * @data: Data to append to @list. - * - * Appends a new link onto the linked list. - * - * Returns: @list or a new list if @list is NULL. - */ -mongoc_list_t * -_mongoc_list_append (mongoc_list_t *list, void *data) -{ - mongoc_list_t *item; - mongoc_list_t *iter; - - item = (mongoc_list_t *) bson_malloc0 (sizeof *item); - item->data = (void *) data; - if (!list) { - return item; - } - - for (iter = list; iter->next; iter = iter->next) { - } - iter->next = item; - - return list; -} - - -/** - * mongoc_list_prepend: - * @list: A mongoc_list_t or NULL. - * @data: data to prepend to the list. - * - * Prepends to @list a new link containing @data. - * - * Returns: A new link containing data with @list following. - */ -mongoc_list_t * -_mongoc_list_prepend (mongoc_list_t *list, void *data) -{ - mongoc_list_t *item; - - item = (mongoc_list_t *) bson_malloc0 (sizeof *item); - item->data = (void *) data; - item->next = list; - - return item; -} - - -/** - * mongoc_list_remove: - * @list: A mongoc_list_t. - * @data: Data to remove from @list. - * - * Removes the link containing @data from @list. - * - * Returns: @list with the link containing @data removed. - */ -mongoc_list_t * -_mongoc_list_remove (mongoc_list_t *list, void *data) -{ - mongoc_list_t *iter; - mongoc_list_t *prev = NULL; - mongoc_list_t *ret = list; - - BSON_ASSERT (list); - - for (iter = list; iter; iter = iter->next) { - if (iter->data == data) { - if (iter != list) { - prev->next = iter->next; - } else { - ret = iter->next; - } - bson_free (iter); - break; - } - prev = iter; - } - - return ret; -} - - -/** - * mongoc_list_foreach: - * @list: A mongoc_list_t or NULL. - * @func: A func to call for each link in @list. - * @user_data: User data for @func. - * - * Calls @func for each item in @list. - */ -void -_mongoc_list_foreach (mongoc_list_t *list, - void (*func) (void *data, void *user_data), - void *user_data) -{ - mongoc_list_t *iter; - - BSON_ASSERT (func); - - for (iter = list; iter; iter = iter->next) { - func (iter->data, user_data); - } -} - - -/** - * mongoc_list_destroy: - * @list: A mongoc_list_t. - * - * Destroys @list and releases any resources. - */ -void -_mongoc_list_destroy (mongoc_list_t *list) -{ - mongoc_list_t *tmp = list; - - while (list) { - tmp = list->next; - bson_free (list); - list = tmp; - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-log-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-log-private.h deleted file mode 100644 index b464da10ca0165c886bd836ba91cc6419b3a46c8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-log-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_LOG_PRIVATE_H -#define MONGOC_LOG_PRIVATE_H - -#include "mongoc/mongoc-iovec.h" - -/* just for testing */ -void -_mongoc_log_get_handler (mongoc_log_func_t *log_func, void **user_data); - -bool -_mongoc_log_trace_is_enabled (void); - -void -mongoc_log_trace_bytes (const char *domain, const uint8_t *_b, size_t _l); - -void -mongoc_log_trace_iovec (const char *domain, - const mongoc_iovec_t *_iov, - size_t _iovcnt); - -#endif /* MONGOC_LOG_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-log.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-log.c deleted file mode 100644 index 8722e0b942a0406e0cfbb02507fa61cdf47b7629..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-log.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright 2013 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. - */ - - -#if defined(__linux__) -#include <sys/syscall.h> -#elif defined(_WIN32) -#include <process.h> -#elif defined(__FreeBSD__) -#include <sys/thr.h> -#else -#include <unistd.h> -#endif -#include <stdarg.h> -#include <time.h> - -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-log-private.h" -#include "mongoc/mongoc-thread-private.h" - - -static bson_once_t once = BSON_ONCE_INIT; -static bson_mutex_t gLogMutex; -static mongoc_log_func_t gLogFunc = mongoc_log_default_handler; -#ifdef MONGOC_TRACE -static bool gLogTrace = true; -#endif -static void *gLogData; - -static BSON_ONCE_FUN (_mongoc_ensure_mutex_once) -{ - bson_mutex_init (&gLogMutex); - - BSON_ONCE_RETURN; -} - -void -mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data) -{ - bson_once (&once, &_mongoc_ensure_mutex_once); - - bson_mutex_lock (&gLogMutex); - gLogFunc = log_func; - gLogData = user_data; - bson_mutex_unlock (&gLogMutex); -} - - -/* just for testing */ -void -_mongoc_log_get_handler (mongoc_log_func_t *log_func, void **user_data) -{ - *log_func = gLogFunc; - *user_data = gLogData; -} - - -void -mongoc_log (mongoc_log_level_t log_level, - const char *log_domain, - const char *format, - ...) -{ - va_list args; - char *message; - int stop_logging; - - bson_once (&once, &_mongoc_ensure_mutex_once); - - stop_logging = !gLogFunc; -#ifdef MONGOC_TRACE - stop_logging = - stop_logging || (log_level == MONGOC_LOG_LEVEL_TRACE && !gLogTrace); -#endif - if (stop_logging) { - return; - } - - BSON_ASSERT (format); - - va_start (args, format); - message = bson_strdupv_printf (format, args); - va_end (args); - - bson_mutex_lock (&gLogMutex); - gLogFunc (log_level, log_domain, message, gLogData); - bson_mutex_unlock (&gLogMutex); - - bson_free (message); -} - - -const char * -mongoc_log_level_str (mongoc_log_level_t log_level) -{ - switch (log_level) { - case MONGOC_LOG_LEVEL_ERROR: - return "ERROR"; - case MONGOC_LOG_LEVEL_CRITICAL: - return "CRITICAL"; - case MONGOC_LOG_LEVEL_WARNING: - return "WARNING"; - case MONGOC_LOG_LEVEL_MESSAGE: - return "MESSAGE"; - case MONGOC_LOG_LEVEL_INFO: - return "INFO"; - case MONGOC_LOG_LEVEL_DEBUG: - return "DEBUG"; - case MONGOC_LOG_LEVEL_TRACE: - return "TRACE"; - default: - return "UNKNOWN"; - } -} - - -void -mongoc_log_default_handler (mongoc_log_level_t log_level, - const char *log_domain, - const char *message, - void *user_data) -{ - struct timeval tv; - struct tm tt; - time_t t; - FILE *stream; - char nowstr[32]; - int pid; - - bson_gettimeofday (&tv); - t = tv.tv_sec; - -#ifdef _WIN32 -#ifdef _MSC_VER - localtime_s (&tt, &t); -#else - tt = *(localtime (&t)); -#endif -#else - localtime_r (&t, &tt); -#endif - - strftime (nowstr, sizeof nowstr, "%Y/%m/%d %H:%M:%S", &tt); - - switch (log_level) { - case MONGOC_LOG_LEVEL_ERROR: - case MONGOC_LOG_LEVEL_CRITICAL: - case MONGOC_LOG_LEVEL_WARNING: - stream = stderr; - break; - case MONGOC_LOG_LEVEL_MESSAGE: - case MONGOC_LOG_LEVEL_INFO: - case MONGOC_LOG_LEVEL_DEBUG: - case MONGOC_LOG_LEVEL_TRACE: - default: - stream = stdout; - } - -#ifdef __linux__ - pid = syscall (SYS_gettid); -#elif defined(_WIN32) - pid = (int) _getpid (); -#elif defined(__FreeBSD__) - long tid; - thr_self (&tid); - pid = (int) tid; -#elif defined(__OpenBSD__) - pid = (int) getthrid (); -#else - pid = (int) getpid (); -#endif - - fprintf (stream, - "%s.%04ld: [%5d]: %8s: %12s: %s\n", - nowstr, - tv.tv_usec / 1000L, - pid, - mongoc_log_level_str (log_level), - log_domain, - message); -} - -bool -_mongoc_log_trace_is_enabled (void) -{ -#ifdef MONGOC_TRACE - return gLogTrace; -#else - return false; -#endif -} - -void -mongoc_log_trace_enable (void) -{ -#ifdef MONGOC_TRACE - gLogTrace = true; -#endif -} - -void -mongoc_log_trace_disable (void) -{ -#ifdef MONGOC_TRACE - gLogTrace = false; -#endif -} - -void -mongoc_log_trace_bytes (const char *domain, const uint8_t *_b, size_t _l) -{ - bson_string_t *str, *astr; - int32_t _i; - uint8_t _v; - -#ifdef MONGOC_TRACE - if (!gLogTrace) { - return; - } -#endif - - str = bson_string_new (NULL); - astr = bson_string_new (NULL); - for (_i = 0; _i < _l; _i++) { - _v = *(_b + _i); - - if ((_i % 16) == 0) { - bson_string_append_printf (str, "%05x: ", _i); - } - - bson_string_append_printf (str, " %02x", _v); - if (isprint (_v)) { - bson_string_append_printf (astr, " %c", _v); - } else { - bson_string_append (astr, " ."); - } - - if ((_i % 16) == 15) { - mongoc_log ( - MONGOC_LOG_LEVEL_TRACE, domain, "%s %s", str->str, astr->str); - bson_string_truncate (str, 0); - bson_string_truncate (astr, 0); - } else if ((_i % 16) == 7) { - bson_string_append (str, " "); - bson_string_append (astr, " "); - } - } - - if (_i != 16) { - mongoc_log ( - MONGOC_LOG_LEVEL_TRACE, domain, "%-56s %s", str->str, astr->str); - } - - bson_string_free (str, true); - bson_string_free (astr, true); -} - -void -mongoc_log_trace_iovec (const char *domain, - const mongoc_iovec_t *_iov, - size_t _iovcnt) -{ - bson_string_t *str, *astr; - const char *_b; - unsigned _i = 0; - unsigned _j = 0; - unsigned _k = 0; - size_t _l = 0; - uint8_t _v; - -#ifdef MONGOC_TRACE - if (!gLogTrace) { - return; - } -#endif - - for (_i = 0; _i < _iovcnt; _i++) { - _l += _iov[_i].iov_len; - } - - _i = 0; - str = bson_string_new (NULL); - astr = bson_string_new (NULL); - - for (_j = 0; _j < _iovcnt; _j++) { - _b = (char *) _iov[_j].iov_base; - _l = _iov[_j].iov_len; - - for (_k = 0; _k < _l; _k++, _i++) { - _v = *(_b + _k); - if ((_i % 16) == 0) { - bson_string_append_printf (str, "%05x: ", _i); - } - - bson_string_append_printf (str, " %02x", _v); - if (isprint (_v)) { - bson_string_append_printf (astr, " %c", _v); - } else { - bson_string_append (astr, " ."); - } - - if ((_i % 16) == 15) { - mongoc_log ( - MONGOC_LOG_LEVEL_TRACE, domain, "%s %s", str->str, astr->str); - bson_string_truncate (str, 0); - bson_string_truncate (astr, 0); - } else if ((_i % 16) == 7) { - bson_string_append (str, " "); - bson_string_append (astr, " "); - } - } - } - - if (_i != 16) { - mongoc_log ( - MONGOC_LOG_LEVEL_TRACE, domain, "%-56s %s", str->str, astr->str); - } - - bson_string_free (str, true); - bson_string_free (astr, true); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-log.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-log.h deleted file mode 100644 index 7ea76f4b2a1978af0ac1f86e80353cd39c0724ce..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-log.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_LOG_H -#define MONGOC_LOG_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - - -#ifndef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "mongoc" -#endif - - -#define MONGOC_ERROR(...) \ - mongoc_log (MONGOC_LOG_LEVEL_ERROR, MONGOC_LOG_DOMAIN, __VA_ARGS__) -#define MONGOC_CRITICAL(...) \ - mongoc_log (MONGOC_LOG_LEVEL_CRITICAL, MONGOC_LOG_DOMAIN, __VA_ARGS__) -#define MONGOC_WARNING(...) \ - mongoc_log (MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, __VA_ARGS__) -#define MONGOC_MESSAGE(...) \ - mongoc_log (MONGOC_LOG_LEVEL_MESSAGE, MONGOC_LOG_DOMAIN, __VA_ARGS__) -#define MONGOC_INFO(...) \ - mongoc_log (MONGOC_LOG_LEVEL_INFO, MONGOC_LOG_DOMAIN, __VA_ARGS__) -#define MONGOC_DEBUG(...) \ - mongoc_log (MONGOC_LOG_LEVEL_DEBUG, MONGOC_LOG_DOMAIN, __VA_ARGS__) - - -typedef enum { - MONGOC_LOG_LEVEL_ERROR, - MONGOC_LOG_LEVEL_CRITICAL, - MONGOC_LOG_LEVEL_WARNING, - MONGOC_LOG_LEVEL_MESSAGE, - MONGOC_LOG_LEVEL_INFO, - MONGOC_LOG_LEVEL_DEBUG, - MONGOC_LOG_LEVEL_TRACE, -} mongoc_log_level_t; - - -/** - * mongoc_log_func_t: - * @log_level: The level of the log message. - * @log_domain: The domain of the log message, such as "client". - * @message: The message generated. - * @user_data: User data provided to mongoc_log_set_handler(). - * - * This function prototype can be used to set a custom log handler for the - * libmongoc library. This is useful if you would like to show them in a - * user interface or alternate storage. - */ -typedef void (*mongoc_log_func_t) (mongoc_log_level_t log_level, - const char *log_domain, - const char *message, - void *user_data); - - -/** - * mongoc_log_set_handler: - * @log_func: A function to handle log messages. - * @user_data: User data for @log_func. - * - * Sets the function to be called to handle logging. - */ -MONGOC_EXPORT (void) -mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data); - - -/** - * mongoc_log: - * @log_level: The log level. - * @log_domain: The log domain (such as "client"). - * @format: The format string for the log message. - * - * Logs a message using the currently configured logger. - * - * This method will hold a logging lock to prevent concurrent calls to the - * logging infrastructure. It is important that your configured log function - * does not re-enter the logging system or deadlock will occur. - * - */ -MONGOC_EXPORT (void) -mongoc_log (mongoc_log_level_t log_level, - const char *log_domain, - const char *format, - ...) BSON_GNUC_PRINTF (3, 4); - - -MONGOC_EXPORT (void) -mongoc_log_default_handler (mongoc_log_level_t log_level, - const char *log_domain, - const char *message, - void *user_data); - - -/** - * mongoc_log_level_str: - * @log_level: The log level. - * - * Returns: The string representation of log_level - */ -MONGOC_EXPORT (const char *) -mongoc_log_level_str (mongoc_log_level_t log_level); - - -/** - * mongoc_log_trace_enable: - * - * Enables tracing at runtime (if it has been enabled at compile time). - */ -MONGOC_EXPORT (void) -mongoc_log_trace_enable (void); - - -/** - * mongoc_log_trace_disable: - * - * Disables tracing at runtime (if it has been enabled at compile time). - */ -MONGOC_EXPORT (void) -mongoc_log_trace_disable (void); - - -BSON_END_DECLS - - -#endif /* MONGOC_LOG_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-macros.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-macros.h deleted file mode 100644 index 62f106a8a11dfa952b52e3e11e07279f75039926..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-macros.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_MACROS_H -#define MONGOC_MACROS_H - -/* Decorate public functions: - * - if MONGOC_STATIC, we're compiling a program that uses libmongoc as - * a static library, don't decorate functions - * - else if MONGOC_COMPILATION, we're compiling a static or shared libmongoc, - * mark public functions for export from the shared lib (which has no effect - * on the static lib) - * - else, we're compiling a program that uses libmongoc as a shared library, - * mark public functions as DLL imports for Microsoft Visual C. - */ - -#ifdef _MSC_VER -/* - * Microsoft Visual C - */ -#ifdef MONGOC_STATIC -#define MONGOC_API -#elif defined(MONGOC_COMPILATION) -#define MONGOC_API __declspec(dllexport) -#else -#define MONGOC_API __declspec(dllimport) -#endif -#define MONGOC_CALL __cdecl - -#elif defined(__GNUC__) -/* - * GCC - */ -#ifdef MONGOC_STATIC -#define MONGOC_API -#elif defined(MONGOC_COMPILATION) -#define MONGOC_API __attribute__ ((visibility ("default"))) -#else -#define MONGOC_API -#endif -#define MONGOC_CALL - -#else -/* - * Other compilers - */ -#define MONGOC_API -#define MONGOC_CALL - -#endif - -#define MONGOC_EXPORT(type) MONGOC_API type MONGOC_CALL - -#endif /* MONGOC_MACROS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-op-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-op-private.h deleted file mode 100644 index 9150ac190d5bb6045a92dc094f7440f7b6d4bdb8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-op-private.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_MATCHER_OP_PRIVATE_H -#define MONGOC_MATCHER_OP_PRIVATE_H - -#include <bson/bson.h> - - -BSON_BEGIN_DECLS - - -typedef union _mongoc_matcher_op_t mongoc_matcher_op_t; -typedef struct _mongoc_matcher_op_base_t mongoc_matcher_op_base_t; -typedef struct _mongoc_matcher_op_logical_t mongoc_matcher_op_logical_t; -typedef struct _mongoc_matcher_op_compare_t mongoc_matcher_op_compare_t; -typedef struct _mongoc_matcher_op_exists_t mongoc_matcher_op_exists_t; -typedef struct _mongoc_matcher_op_type_t mongoc_matcher_op_type_t; -typedef struct _mongoc_matcher_op_not_t mongoc_matcher_op_not_t; - - -typedef enum { - MONGOC_MATCHER_OPCODE_EQ, - MONGOC_MATCHER_OPCODE_GT, - MONGOC_MATCHER_OPCODE_GTE, - MONGOC_MATCHER_OPCODE_IN, - MONGOC_MATCHER_OPCODE_LT, - MONGOC_MATCHER_OPCODE_LTE, - MONGOC_MATCHER_OPCODE_NE, - MONGOC_MATCHER_OPCODE_NIN, - MONGOC_MATCHER_OPCODE_OR, - MONGOC_MATCHER_OPCODE_AND, - MONGOC_MATCHER_OPCODE_NOT, - MONGOC_MATCHER_OPCODE_NOR, - MONGOC_MATCHER_OPCODE_EXISTS, - MONGOC_MATCHER_OPCODE_TYPE, -} mongoc_matcher_opcode_t; - - -struct _mongoc_matcher_op_base_t { - mongoc_matcher_opcode_t opcode; -}; - - -struct _mongoc_matcher_op_logical_t { - mongoc_matcher_op_base_t base; - mongoc_matcher_op_t *left; - mongoc_matcher_op_t *right; -}; - - -struct _mongoc_matcher_op_compare_t { - mongoc_matcher_op_base_t base; - char *path; - bson_iter_t iter; -}; - - -struct _mongoc_matcher_op_exists_t { - mongoc_matcher_op_base_t base; - char *path; - bool exists; -}; - - -struct _mongoc_matcher_op_type_t { - mongoc_matcher_op_base_t base; - bson_type_t type; - char *path; -}; - - -struct _mongoc_matcher_op_not_t { - mongoc_matcher_op_base_t base; - mongoc_matcher_op_t *child; - char *path; -}; - - -union _mongoc_matcher_op_t { - mongoc_matcher_op_base_t base; - mongoc_matcher_op_logical_t logical; - mongoc_matcher_op_compare_t compare; - mongoc_matcher_op_exists_t exists; - mongoc_matcher_op_type_t type; - mongoc_matcher_op_not_t not_; -}; - - -mongoc_matcher_op_t * -_mongoc_matcher_op_logical_new (mongoc_matcher_opcode_t opcode, - mongoc_matcher_op_t *left, - mongoc_matcher_op_t *right); -mongoc_matcher_op_t * -_mongoc_matcher_op_compare_new (mongoc_matcher_opcode_t opcode, - const char *path, - const bson_iter_t *iter); -mongoc_matcher_op_t * -_mongoc_matcher_op_exists_new (const char *path, bool exists); -mongoc_matcher_op_t * -_mongoc_matcher_op_type_new (const char *path, bson_type_t type); -mongoc_matcher_op_t * -_mongoc_matcher_op_not_new (const char *path, mongoc_matcher_op_t *child); -bool -_mongoc_matcher_op_match (mongoc_matcher_op_t *op, const bson_t *bson); -void -_mongoc_matcher_op_destroy (mongoc_matcher_op_t *op); -void -_mongoc_matcher_op_to_bson (mongoc_matcher_op_t *op, bson_t *bson); - - -BSON_END_DECLS - - -#endif /* MONGOC_MATCHER_OP_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-op.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-op.c deleted file mode 100644 index 11da2b9abee931b89e90f1f728fcf8ae01acd273..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-op.c +++ /dev/null @@ -1,1188 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-log.h" -#include "mongoc/mongoc-matcher-op-private.h" -#include "mongoc/mongoc-util-private.h" - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_exists_new -- - * - * Create a new op for checking {$exists: bool}. - * - * Returns: - * A newly allocated mongoc_matcher_op_t that should be freed with - * _mongoc_matcher_op_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_matcher_op_t * -_mongoc_matcher_op_exists_new (const char *path, /* IN */ - bool exists) /* IN */ -{ - mongoc_matcher_op_t *op; - - BSON_ASSERT (path); - - op = (mongoc_matcher_op_t *) bson_malloc0 (sizeof *op); - op->exists.base.opcode = MONGOC_MATCHER_OPCODE_EXISTS; - op->exists.path = bson_strdup (path); - op->exists.exists = exists; - - return op; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_type_new -- - * - * Create a new op for checking {$type: int}. - * - * Returns: - * A newly allocated mongoc_matcher_op_t that should be freed with - * _mongoc_matcher_op_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_matcher_op_t * -_mongoc_matcher_op_type_new (const char *path, /* IN */ - bson_type_t type) /* IN */ -{ - mongoc_matcher_op_t *op; - - BSON_ASSERT (path); - BSON_ASSERT (type); - - op = (mongoc_matcher_op_t *) bson_malloc0 (sizeof *op); - op->type.base.opcode = MONGOC_MATCHER_OPCODE_TYPE; - op->type.path = bson_strdup (path); - op->type.type = type; - - return op; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_logical_new -- - * - * Create a new op for checking any of: - * - * {$or: []} - * {$nor: []} - * {$and: []} - * - * Returns: - * A newly allocated mongoc_matcher_op_t that should be freed with - * _mongoc_matcher_op_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_matcher_op_t * -_mongoc_matcher_op_logical_new (mongoc_matcher_opcode_t opcode, /* IN */ - mongoc_matcher_op_t *left, /* IN */ - mongoc_matcher_op_t *right) /* IN */ -{ - mongoc_matcher_op_t *op; - - BSON_ASSERT (left); - BSON_ASSERT ((opcode >= MONGOC_MATCHER_OPCODE_OR) && - (opcode <= MONGOC_MATCHER_OPCODE_NOR)); - - op = (mongoc_matcher_op_t *) bson_malloc0 (sizeof *op); - op->logical.base.opcode = opcode; - op->logical.left = left; - op->logical.right = right; - - return op; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_compare_new -- - * - * Create a new op for checking any of: - * - * {"abc": "def"} - * {$gt: {...} - * {$gte: {...} - * {$lt: {...} - * {$lte: {...} - * {$ne: {...} - * {$in: [...]} - * {$nin: [...]} - * - * Returns: - * A newly allocated mongoc_matcher_op_t that should be freed with - * _mongoc_matcher_op_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_matcher_op_t * -_mongoc_matcher_op_compare_new (mongoc_matcher_opcode_t opcode, /* IN */ - const char *path, /* IN */ - const bson_iter_t *iter) /* IN */ -{ - mongoc_matcher_op_t *op; - - BSON_ASSERT (path); - BSON_ASSERT (iter); - - op = (mongoc_matcher_op_t *) bson_malloc0 (sizeof *op); - op->compare.base.opcode = opcode; - op->compare.path = bson_strdup (path); - memcpy (&op->compare.iter, iter, sizeof *iter); - - return op; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_not_new -- - * - * Create a new op for checking {$not: {...}} - * - * Returns: - * A newly allocated mongoc_matcher_op_t that should be freed with - * _mongoc_matcher_op_destroy(). - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_matcher_op_t * -_mongoc_matcher_op_not_new (const char *path, /* IN */ - mongoc_matcher_op_t *child) /* IN */ -{ - mongoc_matcher_op_t *op; - - BSON_ASSERT (path); - BSON_ASSERT (child); - - op = (mongoc_matcher_op_t *) bson_malloc0 (sizeof *op); - op->not_.base.opcode = MONGOC_MATCHER_OPCODE_NOT; - op->not_.path = bson_strdup (path); - op->not_.child = child; - - return op; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_destroy -- - * - * Free a mongoc_matcher_op_t structure and all children structures. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -_mongoc_matcher_op_destroy (mongoc_matcher_op_t *op) /* IN */ -{ - BSON_ASSERT (op); - - switch (op->base.opcode) { - case MONGOC_MATCHER_OPCODE_EQ: - case MONGOC_MATCHER_OPCODE_GT: - case MONGOC_MATCHER_OPCODE_GTE: - case MONGOC_MATCHER_OPCODE_IN: - case MONGOC_MATCHER_OPCODE_LT: - case MONGOC_MATCHER_OPCODE_LTE: - case MONGOC_MATCHER_OPCODE_NE: - case MONGOC_MATCHER_OPCODE_NIN: - bson_free (op->compare.path); - break; - case MONGOC_MATCHER_OPCODE_OR: - case MONGOC_MATCHER_OPCODE_AND: - case MONGOC_MATCHER_OPCODE_NOR: - if (op->logical.left) - _mongoc_matcher_op_destroy (op->logical.left); - if (op->logical.right) - _mongoc_matcher_op_destroy (op->logical.right); - break; - case MONGOC_MATCHER_OPCODE_NOT: - _mongoc_matcher_op_destroy (op->not_.child); - bson_free (op->not_.path); - break; - case MONGOC_MATCHER_OPCODE_EXISTS: - bson_free (op->exists.path); - break; - case MONGOC_MATCHER_OPCODE_TYPE: - bson_free (op->type.path); - break; - default: - break; - } - - bson_free (op); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_exists_match -- - * - * Checks to see if @bson matches @exists requirements. The - * {$exists: bool} query can be either true or fase so we must - * handle false as "not exists". - * - * Returns: - * true if the field exists and the spec expected it. - * true if the field does not exist and the spec expected it to not - * exist. - * Otherwise, false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_exists_match (mongoc_matcher_op_exists_t *exists, /* IN */ - const bson_t *bson) /* IN */ -{ - bson_iter_t iter; - bson_iter_t desc; - bool found; - - BSON_ASSERT (exists); - BSON_ASSERT (bson); - - found = (bson_iter_init (&iter, bson) && - bson_iter_find_descendant (&iter, exists->path, &desc)); - - return (found == exists->exists); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_type_match -- - * - * Checks if @bson matches the {$type: ...} op. - * - * Returns: - * true if the requested field was found and the type matched - * the requested type. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_type_match (mongoc_matcher_op_type_t *type, /* IN */ - const bson_t *bson) /* IN */ -{ - bson_iter_t iter; - bson_iter_t desc; - - BSON_ASSERT (type); - BSON_ASSERT (bson); - - if (bson_iter_init (&iter, bson) && - bson_iter_find_descendant (&iter, type->path, &desc)) { - return (bson_iter_type (&iter) == type->type); - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_not_match -- - * - * Checks if the {$not: ...} expression matches by negating the - * child expression. - * - * Returns: - * true if the child expression returned false. - * Otherwise false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_not_match (mongoc_matcher_op_not_t *not_, /* IN */ - const bson_t *bson) /* IN */ -{ - BSON_ASSERT (not_); - BSON_ASSERT (bson); - - return !_mongoc_matcher_op_match (not_->child, bson); -} - - -#define _TYPE_CODE(l, r) ((((int) (l)) << 8) | ((int) (r))) -#define _NATIVE_COMPARE(op, t1, t2) \ - (bson_iter##t2 (iter) op bson_iter##t1 (compare_iter)) -#define _EQ_COMPARE(t1, t2) _NATIVE_COMPARE (==, t1, t2) -#define _NE_COMPARE(t1, t2) _NATIVE_COMPARE (!=, t1, t2) -#define _GT_COMPARE(t1, t2) _NATIVE_COMPARE (>, t1, t2) -#define _GTE_COMPARE(t1, t2) _NATIVE_COMPARE (>=, t1, t2) -#define _LT_COMPARE(t1, t2) _NATIVE_COMPARE (<, t1, t2) -#define _LTE_COMPARE(t1, t2) _NATIVE_COMPARE (<=, t1, t2) - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_iter_eq_match -- - * - * Performs equality match for all types on either left or right - * side of the equation. - * - * We try to default to what the compiler would do for comparing - * things like integers. Therefore, we just have MACRO'tized - * everything so that the compiler sees the native values. (Such - * as (double == int64). - * - * The _TYPE_CODE() stuff allows us to shove the type of the left - * and the right into a single integer and then do a jump table - * with a switch/case for all our supported types. - * - * I imagine a bunch more of these will need to be added, so feel - * free to submit patches. - * - * Returns: - * true if the equality match succeeded. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_iter_eq_match (bson_iter_t *compare_iter, /* IN */ - bson_iter_t *iter) /* IN */ -{ - int code; - - BSON_ASSERT (compare_iter); - BSON_ASSERT (iter); - - code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); - - switch (code) { - /* Double on Left Side */ - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): - return _EQ_COMPARE (_double, _double); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): - return _EQ_COMPARE (_double, _bool); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT32): - return _EQ_COMPARE (_double, _int32); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT64): - return _EQ_COMPARE (_double, _int64); - - /* UTF8 on Left Side */ - case _TYPE_CODE (BSON_TYPE_UTF8, BSON_TYPE_UTF8): { - uint32_t llen; - uint32_t rlen; - const char *lstr; - const char *rstr; - - lstr = bson_iter_utf8 (compare_iter, &llen); - rstr = bson_iter_utf8 (iter, &rlen); - - return ((llen == rlen) && (0 == memcmp (lstr, rstr, llen))); - } - - /* Int32 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_DOUBLE): - return _EQ_COMPARE (_int32, _double); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_BOOL): - return _EQ_COMPARE (_int32, _bool); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT32): - return _EQ_COMPARE (_int32, _int32); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT64): - return _EQ_COMPARE (_int32, _int64); - - /* Int64 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_DOUBLE): - return _EQ_COMPARE (_int64, _double); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_BOOL): - return _EQ_COMPARE (_int64, _bool); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT32): - return _EQ_COMPARE (_int64, _int32); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT64): - return _EQ_COMPARE (_int64, _int64); - - /* Null on Left Side */ - case _TYPE_CODE (BSON_TYPE_NULL, BSON_TYPE_NULL): - case _TYPE_CODE (BSON_TYPE_NULL, BSON_TYPE_UNDEFINED): - return true; - - case _TYPE_CODE (BSON_TYPE_ARRAY, BSON_TYPE_ARRAY): { - bson_iter_t left_array; - bson_iter_t right_array; - BSON_ASSERT (bson_iter_recurse (compare_iter, &left_array)); - BSON_ASSERT (bson_iter_recurse (iter, &right_array)); - - while (true) { - bool left_has_next = bson_iter_next (&left_array); - bool right_has_next = bson_iter_next (&right_array); - - if (left_has_next != right_has_next) { - /* different lengths */ - return false; - } - - if (!left_has_next) { - /* finished */ - return true; - } - - if (!_mongoc_matcher_iter_eq_match (&left_array, &right_array)) { - return false; - } - } - } - - case _TYPE_CODE (BSON_TYPE_DOCUMENT, BSON_TYPE_DOCUMENT): { - uint32_t llen; - uint32_t rlen; - const uint8_t *ldoc; - const uint8_t *rdoc; - - bson_iter_document (compare_iter, &llen, &ldoc); - bson_iter_document (iter, &rlen, &rdoc); - - return ((llen == rlen) && (0 == memcmp (ldoc, rdoc, llen))); - } - - default: - return false; - } -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_eq_match -- - * - * Performs equality match for all types on either left or right - * side of the equation. - * - * Returns: - * true if the equality match succeeded. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_eq_match (mongoc_matcher_op_compare_t *compare, /* IN */ - bson_iter_t *iter) /* IN */ -{ - BSON_ASSERT (compare); - BSON_ASSERT (iter); - - return _mongoc_matcher_iter_eq_match (&compare->iter, iter); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_gt_match -- - * - * Perform {$gt: ...} match using @compare. - * - * In general, we try to default to what the compiler would do - * for comparison between different types. - * - * Returns: - * true if the document field was > the spec value. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_gt_match (mongoc_matcher_op_compare_t *compare, /* IN */ - bson_iter_t *iter) /* IN */ -{ - int code; - bson_iter_t *compare_iter = &compare->iter; - - BSON_ASSERT (compare); - BSON_ASSERT (iter); - - code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); - - switch (code) { - /* Double on Left Side */ - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): - return _GT_COMPARE (_double, _double); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): - return _GT_COMPARE (_double, _bool); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT32): - return _GT_COMPARE (_double, _int32); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT64): - return _GT_COMPARE (_double, _int64); - - /* Int32 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_DOUBLE): - return _GT_COMPARE (_int32, _double); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_BOOL): - return _GT_COMPARE (_int32, _bool); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT32): - return _GT_COMPARE (_int32, _int32); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT64): - return _GT_COMPARE (_int32, _int64); - - /* Int64 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_DOUBLE): - return _GT_COMPARE (_int64, _double); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_BOOL): - return _GT_COMPARE (_int64, _bool); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT32): - return _GT_COMPARE (_int64, _int32); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT64): - return _GT_COMPARE (_int64, _int64); - - default: - MONGOC_WARNING ("Implement for (Type(%d) > Type(%d))", - bson_iter_type (compare_iter), - bson_iter_type (iter)); - break; - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_gte_match -- - * - * Perform a match of {"path": {"$gte": value}}. - * - * Returns: - * true if the spec matches, otherwise false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_gte_match (mongoc_matcher_op_compare_t *compare, /* IN */ - bson_iter_t *iter) /* IN */ -{ - bson_iter_t *compare_iter; - int code; - - BSON_ASSERT (compare); - BSON_ASSERT (iter); - - compare_iter = &compare->iter; - code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); - - switch (code) { - /* Double on Left Side */ - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): - return _GTE_COMPARE (_double, _double); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): - return _GTE_COMPARE (_double, _bool); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT32): - return _GTE_COMPARE (_double, _int32); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT64): - return _GTE_COMPARE (_double, _int64); - - /* Int32 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_DOUBLE): - return _GTE_COMPARE (_int32, _double); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_BOOL): - return _GTE_COMPARE (_int32, _bool); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT32): - return _GTE_COMPARE (_int32, _int32); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT64): - return _GTE_COMPARE (_int32, _int64); - - /* Int64 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_DOUBLE): - return _GTE_COMPARE (_int64, _double); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_BOOL): - return _GTE_COMPARE (_int64, _bool); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT32): - return _GTE_COMPARE (_int64, _int32); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT64): - return _GTE_COMPARE (_int64, _int64); - - default: - MONGOC_WARNING ("Implement for (Type(%d) >= Type(%d))", - bson_iter_type (compare_iter), - bson_iter_type (iter)); - break; - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_in_match -- - * - * Checks the spec {"path": {"$in": [value1, value2, ...]}}. - * - * Returns: - * true if the spec matched, otherwise false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_in_match (mongoc_matcher_op_compare_t *compare, /* IN */ - bson_iter_t *iter) /* IN */ -{ - mongoc_matcher_op_compare_t op; - - op.base.opcode = MONGOC_MATCHER_OPCODE_EQ; - op.path = compare->path; - - if (!BSON_ITER_HOLDS_ARRAY (&compare->iter) || - !bson_iter_recurse (&compare->iter, &op.iter)) { - return false; - } - - while (bson_iter_next (&op.iter)) { - if (_mongoc_matcher_op_eq_match (&op, iter)) { - return true; - } - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_lt_match -- - * - * Perform a {"path": "$lt": {value}} match. - * - * Returns: - * true if the spec matched, otherwise false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_lt_match (mongoc_matcher_op_compare_t *compare, /* IN */ - bson_iter_t *iter) /* IN */ -{ - bson_iter_t *compare_iter; - int code; - - BSON_ASSERT (compare); - BSON_ASSERT (iter); - - compare_iter = &compare->iter; - code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); - - switch (code) { - /* Double on Left Side */ - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): - return _LT_COMPARE (_double, _double); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): - return _LT_COMPARE (_double, _bool); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT32): - return _LT_COMPARE (_double, _int32); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT64): - return _LT_COMPARE (_double, _int64); - - /* Int32 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_DOUBLE): - return _LT_COMPARE (_int32, _double); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_BOOL): - return _LT_COMPARE (_int32, _bool); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT32): - return _LT_COMPARE (_int32, _int32); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT64): - return _LT_COMPARE (_int32, _int64); - - /* Int64 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_DOUBLE): - return _LT_COMPARE (_int64, _double); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_BOOL): - return _LT_COMPARE (_int64, _bool); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT32): - return _LT_COMPARE (_int64, _int32); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT64): - return _LT_COMPARE (_int64, _int64); - - default: - MONGOC_WARNING ("Implement for (Type(%d) < Type(%d))", - bson_iter_type (compare_iter), - bson_iter_type (iter)); - break; - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_lte_match -- - * - * Perform a {"$path": {"$lte": value}} match. - * - * Returns: - * true if the spec matched, otherwise false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_lte_match (mongoc_matcher_op_compare_t *compare, /* IN */ - bson_iter_t *iter) /* IN */ -{ - bson_iter_t *compare_iter; - int code; - - BSON_ASSERT (compare); - BSON_ASSERT (iter); - - compare_iter = &compare->iter; - code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); - - switch (code) { - /* Double on Left Side */ - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): - return _LTE_COMPARE (_double, _double); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): - return _LTE_COMPARE (_double, _bool); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT32): - return _LTE_COMPARE (_double, _int32); - case _TYPE_CODE (BSON_TYPE_DOUBLE, BSON_TYPE_INT64): - return _LTE_COMPARE (_double, _int64); - - /* Int32 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_DOUBLE): - return _LTE_COMPARE (_int32, _double); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_BOOL): - return _LTE_COMPARE (_int32, _bool); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT32): - return _LTE_COMPARE (_int32, _int32); - case _TYPE_CODE (BSON_TYPE_INT32, BSON_TYPE_INT64): - return _LTE_COMPARE (_int32, _int64); - - /* Int64 on Left Side */ - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_DOUBLE): - return _LTE_COMPARE (_int64, _double); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_BOOL): - return _LTE_COMPARE (_int64, _bool); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT32): - return _LTE_COMPARE (_int64, _int32); - case _TYPE_CODE (BSON_TYPE_INT64, BSON_TYPE_INT64): - return _LTE_COMPARE (_int64, _int64); - - default: - MONGOC_WARNING ("Implement for (Type(%d) <= Type(%d))", - bson_iter_type (compare_iter), - bson_iter_type (iter)); - break; - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_ne_match -- - * - * Perform a {"path": {"$ne": value}} match. - * - * Returns: - * true if the field "path" was not found or the value is not-equal - * to value. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_ne_match (mongoc_matcher_op_compare_t *compare, /* IN */ - bson_iter_t *iter) /* IN */ -{ - return !_mongoc_matcher_op_eq_match (compare, iter); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_nin_match -- - * - * Perform a {"path": {"$nin": value}} match. - * - * Returns: - * true if value was not found in the array at "path". - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_nin_match (mongoc_matcher_op_compare_t *compare, /* IN */ - bson_iter_t *iter) /* IN */ -{ - return !_mongoc_matcher_op_in_match (compare, iter); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_compare_match -- - * - * Dispatch function for mongoc_matcher_op_compare_t operations - * to perform a match. - * - * Returns: - * Opcode dependent. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_compare_match (mongoc_matcher_op_compare_t *compare, /* IN */ - const bson_t *bson) /* IN */ -{ - bson_iter_t tmp; - bson_iter_t iter; - - BSON_ASSERT (compare); - BSON_ASSERT (bson); - - if (strchr (compare->path, '.')) { - if (!bson_iter_init (&tmp, bson) || - !bson_iter_find_descendant (&tmp, compare->path, &iter)) { - return false; - } - } else if (!bson_iter_init_find (&iter, bson, compare->path)) { - return false; - } - - switch ((int) compare->base.opcode) { - case MONGOC_MATCHER_OPCODE_EQ: - return _mongoc_matcher_op_eq_match (compare, &iter); - case MONGOC_MATCHER_OPCODE_GT: - return _mongoc_matcher_op_gt_match (compare, &iter); - case MONGOC_MATCHER_OPCODE_GTE: - return _mongoc_matcher_op_gte_match (compare, &iter); - case MONGOC_MATCHER_OPCODE_IN: - return _mongoc_matcher_op_in_match (compare, &iter); - case MONGOC_MATCHER_OPCODE_LT: - return _mongoc_matcher_op_lt_match (compare, &iter); - case MONGOC_MATCHER_OPCODE_LTE: - return _mongoc_matcher_op_lte_match (compare, &iter); - case MONGOC_MATCHER_OPCODE_NE: - return _mongoc_matcher_op_ne_match (compare, &iter); - case MONGOC_MATCHER_OPCODE_NIN: - return _mongoc_matcher_op_nin_match (compare, &iter); - default: - BSON_ASSERT (false); - break; - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_logical_match -- - * - * Dispatch function for mongoc_matcher_op_logical_t operations - * to perform a match. - * - * Returns: - * Opcode specific. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_matcher_op_logical_match (mongoc_matcher_op_logical_t *logical, /* IN */ - const bson_t *bson) /* IN */ -{ - BSON_ASSERT (logical); - BSON_ASSERT (bson); - - switch ((int) logical->base.opcode) { - case MONGOC_MATCHER_OPCODE_OR: - return (_mongoc_matcher_op_match (logical->left, bson) || - _mongoc_matcher_op_match (logical->right, bson)); - case MONGOC_MATCHER_OPCODE_AND: - return (_mongoc_matcher_op_match (logical->left, bson) && - _mongoc_matcher_op_match (logical->right, bson)); - case MONGOC_MATCHER_OPCODE_NOR: - return !(_mongoc_matcher_op_match (logical->left, bson) || - _mongoc_matcher_op_match (logical->right, bson)); - default: - BSON_ASSERT (false); - break; - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_match -- - * - * Dispatch function for all operation types to perform a match. - * - * Returns: - * Opcode specific. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_matcher_op_match (mongoc_matcher_op_t *op, /* IN */ - const bson_t *bson) /* IN */ -{ - BSON_ASSERT (op); - BSON_ASSERT (bson); - - switch (op->base.opcode) { - case MONGOC_MATCHER_OPCODE_EQ: - case MONGOC_MATCHER_OPCODE_GT: - case MONGOC_MATCHER_OPCODE_GTE: - case MONGOC_MATCHER_OPCODE_IN: - case MONGOC_MATCHER_OPCODE_LT: - case MONGOC_MATCHER_OPCODE_LTE: - case MONGOC_MATCHER_OPCODE_NE: - case MONGOC_MATCHER_OPCODE_NIN: - return _mongoc_matcher_op_compare_match (&op->compare, bson); - case MONGOC_MATCHER_OPCODE_OR: - case MONGOC_MATCHER_OPCODE_AND: - case MONGOC_MATCHER_OPCODE_NOR: - return _mongoc_matcher_op_logical_match (&op->logical, bson); - case MONGOC_MATCHER_OPCODE_NOT: - return _mongoc_matcher_op_not_match (&op->not_, bson); - case MONGOC_MATCHER_OPCODE_EXISTS: - return _mongoc_matcher_op_exists_match (&op->exists, bson); - case MONGOC_MATCHER_OPCODE_TYPE: - return _mongoc_matcher_op_type_match (&op->type, bson); - default: - break; - } - - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_op_to_bson -- - * - * Convert the optree specified by @op to a bson document similar - * to what the query would have been. This is not perfectly the - * same, and so should not be used as such. - * - * Returns: - * None. - * - * Side effects: - * @bson is appended to, and therefore must be initialized before - * calling this function. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_matcher_op_to_bson (mongoc_matcher_op_t *op, /* IN */ - bson_t *bson) /* IN */ -{ - const char *str; - bson_t child; - bson_t child2; - - BSON_ASSERT (op); - BSON_ASSERT (bson); - - switch (op->base.opcode) { - case MONGOC_MATCHER_OPCODE_EQ: - (void) bson_append_iter (bson, op->compare.path, -1, &op->compare.iter); - break; - case MONGOC_MATCHER_OPCODE_GT: - case MONGOC_MATCHER_OPCODE_GTE: - case MONGOC_MATCHER_OPCODE_IN: - case MONGOC_MATCHER_OPCODE_LT: - case MONGOC_MATCHER_OPCODE_LTE: - case MONGOC_MATCHER_OPCODE_NE: - case MONGOC_MATCHER_OPCODE_NIN: - switch ((int) op->base.opcode) { - case MONGOC_MATCHER_OPCODE_GT: - str = "$gt"; - break; - case MONGOC_MATCHER_OPCODE_GTE: - str = "$gte"; - break; - case MONGOC_MATCHER_OPCODE_IN: - str = "$in"; - break; - case MONGOC_MATCHER_OPCODE_LT: - str = "$lt"; - break; - case MONGOC_MATCHER_OPCODE_LTE: - str = "$lte"; - break; - case MONGOC_MATCHER_OPCODE_NE: - str = "$ne"; - break; - case MONGOC_MATCHER_OPCODE_NIN: - str = "$nin"; - break; - default: - str = "???"; - break; - } - if (bson_append_document_begin (bson, op->compare.path, -1, &child)) { - (void) bson_append_iter (&child, str, -1, &op->compare.iter); - bson_append_document_end (bson, &child); - } - break; - case MONGOC_MATCHER_OPCODE_OR: - case MONGOC_MATCHER_OPCODE_AND: - case MONGOC_MATCHER_OPCODE_NOR: - if (op->base.opcode == MONGOC_MATCHER_OPCODE_OR) { - str = "$or"; - } else if (op->base.opcode == MONGOC_MATCHER_OPCODE_AND) { - str = "$and"; - } else if (op->base.opcode == MONGOC_MATCHER_OPCODE_NOR) { - str = "$nor"; - } else { - BSON_ASSERT (false); - str = NULL; - } - bson_append_array_begin (bson, str, -1, &child); - bson_append_document_begin (&child, "0", 1, &child2); - _mongoc_matcher_op_to_bson (op->logical.left, &child2); - bson_append_document_end (&child, &child2); - if (op->logical.right) { - bson_append_document_begin (&child, "1", 1, &child2); - _mongoc_matcher_op_to_bson (op->logical.right, &child2); - bson_append_document_end (&child, &child2); - } - bson_append_array_end (bson, &child); - break; - case MONGOC_MATCHER_OPCODE_NOT: - bson_append_document_begin (bson, op->not_.path, -1, &child); - bson_append_document_begin (&child, "$not", 4, &child2); - _mongoc_matcher_op_to_bson (op->not_.child, &child2); - bson_append_document_end (&child, &child2); - bson_append_document_end (bson, &child); - break; - case MONGOC_MATCHER_OPCODE_EXISTS: - BSON_APPEND_BOOL (bson, "$exists", op->exists.exists); - break; - case MONGOC_MATCHER_OPCODE_TYPE: - BSON_APPEND_INT32 (bson, "$type", (int) op->type.type); - break; - default: - BSON_ASSERT (false); - break; - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-private.h deleted file mode 100644 index c17786a031df529f5d6bb8f050f5e01d536d6fa9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_MATCHER_PRIVATE_H -#define MONGOC_MATCHER_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-matcher-op-private.h" - - -BSON_BEGIN_DECLS - - -struct _mongoc_matcher_t { - bson_t query; - mongoc_matcher_op_t *optree; -}; - - -BSON_END_DECLS - - -#endif /* MONGOC_MATCHER_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher.c deleted file mode 100644 index 9dce09d127fdc59f8c70edc84c393ec150b41de2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright 2014 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 <stdlib.h> - -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-matcher.h" -#include "mongoc/mongoc-matcher-private.h" -#include "mongoc/mongoc-matcher-op-private.h" - - -static mongoc_matcher_op_t * -_mongoc_matcher_parse_logical (mongoc_matcher_opcode_t opcode, - bson_iter_t *iter, - bool is_root, - bson_error_t *error); - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_parse_compare -- - * - * Parse a compare spec such as $gt or $in. - * - * See the following link for more information. - * - * http://docs.mongodb.org/manual/reference/operator/query/ - * - * Returns: - * A newly allocated mongoc_matcher_op_t if successful; otherwise - * NULL and @error is set. - * - * Side effects: - * @error may be set. - * - *-------------------------------------------------------------------------- - */ - -static mongoc_matcher_op_t * -_mongoc_matcher_parse_compare (bson_iter_t *iter, /* IN */ - const char *path, /* IN */ - bson_error_t *error) /* OUT */ -{ - const char *key; - mongoc_matcher_op_t *op = NULL, *op_child; - bson_iter_t child; - - BSON_ASSERT (iter); - BSON_ASSERT (path); - - if (bson_iter_type (iter) == BSON_TYPE_DOCUMENT) { - if (!bson_iter_recurse (iter, &child) || !bson_iter_next (&child)) { - bson_set_error (error, - MONGOC_ERROR_MATCHER, - MONGOC_ERROR_MATCHER_INVALID, - "Document contains no operations."); - return NULL; - } - - key = bson_iter_key (&child); - - if (key[0] != '$') { - op = _mongoc_matcher_op_compare_new ( - MONGOC_MATCHER_OPCODE_EQ, path, iter); - } else if (strcmp (key, "$not") == 0) { - if (!(op_child = - _mongoc_matcher_parse_compare (&child, path, error))) { - return NULL; - } - op = _mongoc_matcher_op_not_new (path, op_child); - } else if (strcmp (key, "$gt") == 0) { - op = _mongoc_matcher_op_compare_new ( - MONGOC_MATCHER_OPCODE_GT, path, &child); - } else if (strcmp (key, "$gte") == 0) { - op = _mongoc_matcher_op_compare_new ( - MONGOC_MATCHER_OPCODE_GTE, path, &child); - } else if (strcmp (key, "$in") == 0) { - op = _mongoc_matcher_op_compare_new ( - MONGOC_MATCHER_OPCODE_IN, path, &child); - } else if (strcmp (key, "$lt") == 0) { - op = _mongoc_matcher_op_compare_new ( - MONGOC_MATCHER_OPCODE_LT, path, &child); - } else if (strcmp (key, "$lte") == 0) { - op = _mongoc_matcher_op_compare_new ( - MONGOC_MATCHER_OPCODE_LTE, path, &child); - } else if (strcmp (key, "$ne") == 0) { - op = _mongoc_matcher_op_compare_new ( - MONGOC_MATCHER_OPCODE_NE, path, &child); - } else if (strcmp (key, "$nin") == 0) { - op = _mongoc_matcher_op_compare_new ( - MONGOC_MATCHER_OPCODE_NIN, path, &child); - } else if (strcmp (key, "$exists") == 0) { - op = _mongoc_matcher_op_exists_new (path, bson_iter_bool (&child)); - } else if (strcmp (key, "$type") == 0) { - op = _mongoc_matcher_op_type_new (path, bson_iter_type (&child)); - } else { - bson_set_error (error, - MONGOC_ERROR_MATCHER, - MONGOC_ERROR_MATCHER_INVALID, - "Invalid operator \"%s\"", - key); - return NULL; - } - } else { - op = - _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_EQ, path, iter); - } - - BSON_ASSERT (op); - - return op; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_parse -- - * - * Parse a query spec observed by the current key of @iter. - * - * Returns: - * A newly allocated mongoc_matcher_op_t if successful; otherwise - * NULL an @error is set. - * - * Side effects: - * @error may be set. - * - *-------------------------------------------------------------------------- - */ - -static mongoc_matcher_op_t * -_mongoc_matcher_parse (bson_iter_t *iter, /* IN */ - bson_error_t *error) /* OUT */ -{ - bson_iter_t child; - const char *key; - - BSON_ASSERT (iter); - - key = bson_iter_key (iter); - - if (*key != '$') { - return _mongoc_matcher_parse_compare (iter, key, error); - } else { - BSON_ASSERT (bson_iter_type (iter) == BSON_TYPE_ARRAY); - - if (!bson_iter_recurse (iter, &child)) { - bson_set_error (error, - MONGOC_ERROR_MATCHER, - MONGOC_ERROR_MATCHER_INVALID, - "Invalid value for operator \"%s\"", - key); - return NULL; - } - - if (strcmp (key, "$or") == 0) { - return _mongoc_matcher_parse_logical ( - MONGOC_MATCHER_OPCODE_OR, &child, false, error); - } else if (strcmp (key, "$and") == 0) { - return _mongoc_matcher_parse_logical ( - MONGOC_MATCHER_OPCODE_AND, &child, false, error); - } else if (strcmp (key, "$nor") == 0) { - return _mongoc_matcher_parse_logical ( - MONGOC_MATCHER_OPCODE_NOR, &child, false, error); - } - } - - bson_set_error (error, - MONGOC_ERROR_MATCHER, - MONGOC_ERROR_MATCHER_INVALID, - "Invalid operator \"%s\"", - key); - - return NULL; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_matcher_parse_logical -- - * - * Parse a query spec containing a logical operator such as - * $or, $and, $not, and $nor. - * - * See the following link for more information. - * - * http://docs.mongodb.org/manual/reference/operator/query/ - * - * Returns: - * A newly allocated mongoc_matcher_op_t if successful; otherwise - * NULL and @error is set. - * - * Side effects: - * @error may be set. - * - *-------------------------------------------------------------------------- - */ - -static mongoc_matcher_op_t * -_mongoc_matcher_parse_logical (mongoc_matcher_opcode_t opcode, /* IN */ - bson_iter_t *iter, /* IN */ - bool is_root, /* IN */ - bson_error_t *error) /* OUT */ -{ - mongoc_matcher_op_t *left; - mongoc_matcher_op_t *right; - mongoc_matcher_op_t *more; - mongoc_matcher_op_t *more_wrap; - bson_iter_t child; - - BSON_ASSERT (opcode); - BSON_ASSERT (iter); - BSON_ASSERT (iter); - - if (!bson_iter_next (iter)) { - bson_set_error (error, - MONGOC_ERROR_MATCHER, - MONGOC_ERROR_MATCHER_INVALID, - "Invalid logical operator."); - return NULL; - } - - if (is_root) { - if (!(left = _mongoc_matcher_parse (iter, error))) { - return NULL; - } - } else { - if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { - bson_set_error (error, - MONGOC_ERROR_MATCHER, - MONGOC_ERROR_MATCHER_INVALID, - "Expected document in value."); - return NULL; - } - - if (!bson_iter_recurse (iter, &child)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "corrupt BSON"); - return NULL; - } - - if (!bson_iter_next (&child)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "corrupt BSON"); - return NULL; - } - - if (!(left = _mongoc_matcher_parse (&child, error))) { - return NULL; - } - } - - if (!bson_iter_next (iter)) { - return left; - } - - if (is_root) { - if (!(right = _mongoc_matcher_parse (iter, error))) { - return NULL; - } - } else { - if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { - bson_set_error (error, - MONGOC_ERROR_MATCHER, - MONGOC_ERROR_MATCHER_INVALID, - "Expected document in value."); - return NULL; - } - - if (!bson_iter_recurse (iter, &child)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "bson_iter_recurse failed."); - return NULL; - } - - if (!bson_iter_next (&child)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "corrupt BSON"); - return NULL; - } - - if (!(right = _mongoc_matcher_parse (&child, error))) { - return NULL; - } - } - - more = _mongoc_matcher_parse_logical (opcode, iter, is_root, error); - - if (more) { - more_wrap = _mongoc_matcher_op_logical_new (opcode, right, more); - return _mongoc_matcher_op_logical_new (opcode, left, more_wrap); - } - - return _mongoc_matcher_op_logical_new (opcode, left, right); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_matcher_new -- - * - * Create a new mongoc_matcher_t using the query specification - * provided in @query. - * - * This will build an operation tree that can be applied to arbitrary - * bson documents using mongoc_matcher_match(). - * - * Returns: - * A newly allocated mongoc_matcher_t if successful; otherwise NULL - * and @error is set. - * - * The mongoc_matcher_t should be freed with - * mongoc_matcher_destroy(). - * - * Side effects: - * @error may be set. - * - *-------------------------------------------------------------------------- - */ - -mongoc_matcher_t * -mongoc_matcher_new (const bson_t *query, /* IN */ - bson_error_t *error) /* OUT */ -{ - mongoc_matcher_op_t *op; - mongoc_matcher_t *matcher; - bson_iter_t iter; - - BSON_ASSERT (query); - - matcher = (mongoc_matcher_t *) bson_malloc0 (sizeof *matcher); - bson_copy_to (query, &matcher->query); - - if (!bson_iter_init (&iter, &matcher->query)) { - goto failure; - } - - if (!(op = _mongoc_matcher_parse_logical ( - MONGOC_MATCHER_OPCODE_AND, &iter, true, error))) { - goto failure; - } - - matcher->optree = op; - - return matcher; - -failure: - bson_destroy (&matcher->query); - bson_free (matcher); - return NULL; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_matcher_match -- - * - * Checks to see if @bson matches the query specified when creating - * @matcher. - * - * Returns: - * TRUE if @bson matched the query, otherwise FALSE. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_matcher_match (const mongoc_matcher_t *matcher, /* IN */ - const bson_t *document) /* IN */ -{ - BSON_ASSERT (matcher); - BSON_ASSERT (matcher->optree); - BSON_ASSERT (document); - - return _mongoc_matcher_op_match (matcher->optree, document); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_matcher_destroy -- - * - * Release all resources associated with @matcher. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_matcher_destroy (mongoc_matcher_t *matcher) /* IN */ -{ - BSON_ASSERT (matcher); - - _mongoc_matcher_op_destroy (matcher->optree); - bson_destroy (&matcher->query); - bson_free (matcher); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher.h deleted file mode 100644 index 8afb4925b8e62bd95b3e7bbc3c7355c27a1d77a9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-matcher.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_MATCHER_H -#define MONGOC_MATCHER_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_matcher_t mongoc_matcher_t; - - -MONGOC_EXPORT (mongoc_matcher_t *) -mongoc_matcher_new (const bson_t *query, - bson_error_t *error) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (bool) -mongoc_matcher_match (const mongoc_matcher_t *matcher, - const bson_t *document) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (void) -mongoc_matcher_destroy (mongoc_matcher_t *matcher) BSON_GNUC_DEPRECATED; - - -BSON_END_DECLS - - -#endif /* MONGOC_MATCHER_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-memcmp-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-memcmp-private.h deleted file mode 100644 index f8a3bcc43751e70abebfa759d68c39fc1563b148..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-memcmp-private.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_MEMCMP_PRIVATE_H -#define MONGOC_MEMCMP_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-config.h" - -/* WARNING: mongoc_memcmp() must be used to verify if two secret keys - * are equal, in constant time. - * It returns 0 if the keys are equal, and -1 if they differ. - * This function is not designed for lexicographical comparisons. - */ -int -mongoc_memcmp (const void *const b1, const void *const b2, size_t len); - -#endif /* MONGOC_MEMCMP_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-memcmp.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-memcmp.c deleted file mode 100644 index ea7896ce3cfad9c77f5417f684b72db2aa3f2fcb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-memcmp.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013-2015 - * Frank Denis <j at pureftpd dot org> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "mongoc/mongoc-memcmp-private.h" - -int -mongoc_memcmp (const void *const b1, const void *const b2, size_t len) -{ - const unsigned char *p1 = b1, *p2 = b2; - int ret = 0; - - for (; len > 0; len--) { - ret |= *p1++ ^ *p2++; - } - - return ret ? 1 : 0; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-opcode.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-opcode.h deleted file mode 100644 index 00307a8df118114cbd9cae05dc7ecb02be7bd6cd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-opcode.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_OPCODE_H -#define MONGOC_OPCODE_H - -#include <bson/bson.h> - - -BSON_BEGIN_DECLS - - -typedef enum { - MONGOC_OPCODE_REPLY = 1, - MONGOC_OPCODE_UPDATE = 2001, - MONGOC_OPCODE_INSERT = 2002, - MONGOC_OPCODE_QUERY = 2004, - MONGOC_OPCODE_GET_MORE = 2005, - MONGOC_OPCODE_DELETE = 2006, - MONGOC_OPCODE_KILL_CURSORS = 2007, - MONGOC_OPCODE_COMPRESSED = 2012, - MONGOC_OPCODE_MSG = 2013, -} mongoc_opcode_t; - - -BSON_END_DECLS - - -#endif /* MONGOC_OPCODE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-openssl-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-openssl-private.h deleted file mode 100644 index d71ae530c1341fcf64d8974f0aa707e297913156..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-openssl-private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_OPENSSL_PRIVATE_H -#define MONGOC_OPENSSL_PRIVATE_H - -#include <bson/bson.h> -#include <openssl/bio.h> -#include <openssl/ssl.h> -#include <openssl/err.h> - -#include "mongoc/mongoc-ssl.h" - - -BSON_BEGIN_DECLS - - -bool -_mongoc_openssl_check_cert (SSL *ssl, - const char *host, - bool allow_invalid_hostname); -SSL_CTX * -_mongoc_openssl_ctx_new (mongoc_ssl_opt_t *opt); -char * -_mongoc_openssl_extract_subject (const char *filename, const char *passphrase); -void -_mongoc_openssl_init (void); -void -_mongoc_openssl_cleanup (void); - - -BSON_END_DECLS - - -#endif /* MONGOC_OPENSSL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-openssl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-openssl.c deleted file mode 100644 index ec625b7150ff601562d0ce0223005c2d6285ee0c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-openssl.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_OPENSSL - -#include <bson/bson.h> -#include <limits.h> -#include <openssl/bio.h> -#include <openssl/ssl.h> -#include <openssl/err.h> -#include <openssl/x509v3.h> -#include <openssl/crypto.h> - -#include <string.h> - -#include "mongoc/mongoc-init.h" -#include "mongoc/mongoc-socket.h" -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-openssl-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-thread-private.h" -#include "mongoc/mongoc-util-private.h" - -#ifdef _WIN32 -#include <wincrypt.h> -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static bson_mutex_t *gMongocOpenSslThreadLocks; - -static void -_mongoc_openssl_thread_startup (void); -static void -_mongoc_openssl_thread_cleanup (void); -#endif -#ifndef MONGOC_HAVE_ASN1_STRING_GET0_DATA -#define ASN1_STRING_get0_data ASN1_STRING_data -#endif - -/** - * _mongoc_openssl_init: - * - * initialization function for SSL - * - * This needs to get called early on and is not threadsafe. Called by - * mongoc_init. - */ -void -_mongoc_openssl_init (void) -{ - SSL_CTX *ctx; - - SSL_library_init (); - SSL_load_error_strings (); - ERR_load_BIO_strings (); - OpenSSL_add_all_algorithms (); -#if OPENSSL_VERSION_NUMBER < 0x10100000L - _mongoc_openssl_thread_startup (); -#endif - - ctx = SSL_CTX_new (SSLv23_method ()); - if (!ctx) { - MONGOC_ERROR ("Failed to initialize OpenSSL."); - } - - SSL_CTX_free (ctx); -} - -void -_mongoc_openssl_cleanup (void) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L - _mongoc_openssl_thread_cleanup (); -#endif -} - -static int -_mongoc_openssl_password_cb (char *buf, int num, int rwflag, void *user_data) -{ - char *pass = (char *) user_data; - int pass_len = (int) strlen (pass); - - if (num < pass_len + 1) { - return 0; - } - - bson_strncpy (buf, pass, num); - return pass_len; -} - -#ifdef _WIN32 -bool -_mongoc_openssl_import_cert_store (LPWSTR store_name, - DWORD dwFlags, - X509_STORE *openssl_store) -{ - PCCERT_CONTEXT cert = NULL; - HCERTSTORE cert_store; - - cert_store = CertOpenStore ( - CERT_STORE_PROV_SYSTEM, /* provider */ - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */ - 0, /* unused */ - dwFlags, /* dwFlags */ - store_name); /* system store name. "My" or "Root" */ - - if (cert_store == NULL) { - LPTSTR msg = NULL; - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ARGUMENT_ARRAY, - NULL, - GetLastError (), - LANG_NEUTRAL, - (LPTSTR) &msg, - 0, - NULL); - MONGOC_ERROR ("Can't open CA store: 0x%.8X: '%s'", GetLastError (), msg); - LocalFree (msg); - return false; - } - - while ((cert = CertEnumCertificatesInStore (cert_store, cert)) != NULL) { - X509 *x509Obj = d2i_X509 (NULL, - (const unsigned char **) &cert->pbCertEncoded, - cert->cbCertEncoded); - - if (x509Obj == NULL) { - MONGOC_WARNING ( - "Error parsing X509 object from Windows certificate store"); - continue; - } - - X509_STORE_add_cert (openssl_store, x509Obj); - X509_free (x509Obj); - } - - CertCloseStore (cert_store, 0); - return true; -} - -bool -_mongoc_openssl_import_cert_stores (SSL_CTX *context) -{ - bool retval; - X509_STORE *store = SSL_CTX_get_cert_store (context); - - if (!store) { - MONGOC_WARNING ("no X509 store found for SSL context while loading " - "system certificates"); - return false; - } - - retval = _mongoc_openssl_import_cert_store (L"root", - CERT_SYSTEM_STORE_CURRENT_USER | - CERT_STORE_READONLY_FLAG, - store); - retval &= _mongoc_openssl_import_cert_store ( - L"CA", CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, store); - - return retval; -} -#endif - -/** mongoc_openssl_hostcheck - * - * rfc 6125 match a given hostname against a given pattern - * - * Patterns come from DNS common names or subjectAltNames. - * - * This code is meant to implement RFC 6125 6.4.[1-3] - * - */ -static bool -_mongoc_openssl_hostcheck (const char *pattern, const char *hostname) -{ - const char *pattern_label_end; - const char *pattern_wildcard; - const char *hostname_label_end; - size_t prefixlen; - size_t suffixlen; - - TRACE ("Comparing '%s' == '%s'", pattern, hostname); - pattern_wildcard = strchr (pattern, '*'); - - if (pattern_wildcard == NULL) { - return strcasecmp (pattern, hostname) == 0; - } - - pattern_label_end = strchr (pattern, '.'); - - /* Bail out on wildcarding in a couple of situations: - * o we don't have 2 dots - we're not going to wildcard root tlds - * o the wildcard isn't in the left most group (separated by dots) - * o the pattern is embedded in an A-label or U-label - */ - if (pattern_label_end == NULL || - strchr (pattern_label_end + 1, '.') == NULL || - pattern_wildcard > pattern_label_end || - strncasecmp (pattern, "xn--", 4) == 0) { - return strcasecmp (pattern, hostname) == 0; - } - - hostname_label_end = strchr (hostname, '.'); - - /* we know we have a dot in the pattern, we need one in the hostname */ - if (hostname_label_end == NULL || - strcasecmp (pattern_label_end, hostname_label_end)) { - return 0; - } - - /* The wildcard must match at least one character, so the left part of the - * hostname is at least as large as the left part of the pattern. */ - if ((hostname_label_end - hostname) < (pattern_label_end - pattern)) { - return 0; - } - - /* If the left prefix group before the star matches and right of the star - * matches... we have a wildcard match */ - prefixlen = pattern_wildcard - pattern; - suffixlen = pattern_label_end - (pattern_wildcard + 1); - return strncasecmp (pattern, hostname, prefixlen) == 0 && - strncasecmp (pattern_wildcard + 1, - hostname_label_end - suffixlen, - suffixlen) == 0; -} - - -/** check if a provided cert matches a passed hostname - */ -bool -_mongoc_openssl_check_cert (SSL *ssl, - const char *host, - bool allow_invalid_hostname) -{ - X509 *peer; - X509_NAME *subject_name; - X509_NAME_ENTRY *entry; - ASN1_STRING *entry_data; - int length; - int idx; - int r = 0; - long verify_status; - - size_t addrlen = 0; - unsigned char addr4[sizeof (struct in_addr)]; - unsigned char addr6[sizeof (struct in6_addr)]; - int i; - int n_sans = -1; - int target = GEN_DNS; - - STACK_OF (GENERAL_NAME) *sans = NULL; - - ENTRY; - BSON_ASSERT (ssl); - BSON_ASSERT (host); - - if (allow_invalid_hostname) { - RETURN (true); - } - - /** if the host looks like an IP address, match that, otherwise we assume we - * have a DNS name */ - if (inet_pton (AF_INET, host, &addr4)) { - target = GEN_IPADD; - addrlen = sizeof addr4; - } else if (inet_pton (AF_INET6, host, &addr6)) { - target = GEN_IPADD; - addrlen = sizeof addr6; - } - - peer = SSL_get_peer_certificate (ssl); - - if (!peer) { - MONGOC_WARNING ("SSL Certification verification failed: %s", - ERR_error_string (ERR_get_error (), NULL)); - RETURN (false); - } - - verify_status = SSL_get_verify_result (ssl); - - if (verify_status == X509_V_OK) { - /* gets a stack of alt names that we can iterate through */ - sans = (STACK_OF (GENERAL_NAME) *) X509_get_ext_d2i ( - (X509 *) peer, NID_subject_alt_name, NULL, NULL); - - if (sans) { - n_sans = sk_GENERAL_NAME_num (sans); - - /* loop through the stack, or until we find a match */ - for (i = 0; i < n_sans && !r; i++) { - const GENERAL_NAME *name = sk_GENERAL_NAME_value (sans, i); - - /* skip entries that can't apply, I.e. IP entries if we've got a - * DNS host */ - if (name->type == target) { - const char *check; - - check = (const char *) ASN1_STRING_get0_data (name->d.ia5); - length = ASN1_STRING_length (name->d.ia5); - - switch (target) { - case GEN_DNS: - - /* check that we don't have an embedded null byte */ - if ((length == bson_strnlen (check, length)) && - _mongoc_openssl_hostcheck (check, host)) { - r = 1; - } - - break; - case GEN_IPADD: - if (length == addrlen) { - if (length == sizeof addr6 && - !memcmp (check, &addr6, length)) { - r = 1; - } else if (length == sizeof addr4 && - !memcmp (check, &addr4, length)) { - r = 1; - } - } - - break; - default: - BSON_ASSERT (0); - break; - } - } - } - GENERAL_NAMES_free (sans); - } else { - subject_name = X509_get_subject_name (peer); - - if (subject_name) { - i = -1; - - /* skip to the last common name */ - while ((idx = X509_NAME_get_index_by_NID ( - subject_name, NID_commonName, i)) >= 0) { - i = idx; - } - - if (i >= 0) { - entry = X509_NAME_get_entry (subject_name, i); - entry_data = X509_NAME_ENTRY_get_data (entry); - - if (entry_data) { - char *check; - - /* TODO: I've heard tell that old versions of SSL crap out - * when calling ASN1_STRING_to_UTF8 on already utf8 data. - * Check up on that */ - length = ASN1_STRING_to_UTF8 ((unsigned char **) &check, - entry_data); - - if (length >= 0) { - /* check for embedded nulls */ - if ((length == bson_strnlen (check, length)) && - _mongoc_openssl_hostcheck (check, host)) { - r = 1; - } - - OPENSSL_free (check); - } - } - } - } - } - } - - X509_free (peer); - RETURN (r); -} - - -static bool -_mongoc_openssl_setup_ca (SSL_CTX *ctx, const char *cert, const char *cert_dir) -{ - BSON_ASSERT (ctx); - BSON_ASSERT (cert || cert_dir); - - if (!SSL_CTX_load_verify_locations (ctx, cert, cert_dir)) { - MONGOC_ERROR ("Cannot load Certificate Authorities from '%s' and '%s'", - cert, - cert_dir); - return 0; - } - - return 1; -} - - -static bool -_mongoc_openssl_setup_crl (SSL_CTX *ctx, const char *crlfile) -{ - X509_STORE *store; - X509_LOOKUP *lookup; - int status; - - store = SSL_CTX_get_cert_store (ctx); - X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK); - - lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()); - - status = X509_load_crl_file (lookup, crlfile, X509_FILETYPE_PEM); - - return status != 0; -} - - -static bool -_mongoc_openssl_setup_pem_file (SSL_CTX *ctx, - const char *pem_file, - const char *password) -{ - if (!SSL_CTX_use_certificate_chain_file (ctx, pem_file)) { - MONGOC_ERROR ("Cannot find certificate in '%s'", pem_file); - return 0; - } - - if (password) { - SSL_CTX_set_default_passwd_cb_userdata (ctx, (void *) password); - SSL_CTX_set_default_passwd_cb (ctx, _mongoc_openssl_password_cb); - } - - if (!(SSL_CTX_use_PrivateKey_file (ctx, pem_file, SSL_FILETYPE_PEM))) { - MONGOC_ERROR ("Cannot find private key in: '%s'", pem_file); - return 0; - } - - if (!(SSL_CTX_check_private_key (ctx))) { - MONGOC_ERROR ("Cannot load private key: '%s'", pem_file); - return 0; - } - - return 1; -} - - -/** - * _mongoc_openssl_ctx_new: - * - * Create a new ssl context declaratively - * - * The opt.pem_pwd parameter, if passed, must exist for the life of this - * context object (for storing and loading the associated pem file) - */ -SSL_CTX * -_mongoc_openssl_ctx_new (mongoc_ssl_opt_t *opt) -{ - SSL_CTX *ctx = NULL; - int ssl_ctx_options = 0; - - /* - * Ensure we are initialized. This is safe to call multiple times. - */ - mongoc_init (); - - ctx = SSL_CTX_new (SSLv23_method ()); - - BSON_ASSERT (ctx); - - /* SSL_OP_ALL - Activate all bug workaround options, to support buggy client - * SSL's. */ - ssl_ctx_options |= SSL_OP_ALL; - - /* SSL_OP_NO_SSLv2 - Disable SSL v2 support */ - ssl_ctx_options |= SSL_OP_NO_SSLv2; - -/* Disable compression, if we can. - * OpenSSL 0.9.x added compression support which was always enabled when built - * against zlib - * OpenSSL 1.0.0 added the ability to disable it, while keeping it enabled by - * default - * OpenSSL 1.1.0 disabled it by default. - */ -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - ssl_ctx_options |= SSL_OP_NO_COMPRESSION; -#endif - - SSL_CTX_set_options (ctx, ssl_ctx_options); - -/* only defined in special build, using: - * --enable-system-crypto-profile (autotools) - * -DENABLE_CRYPTO_SYSTEM_PROFILE:BOOL=ON (cmake) */ -#ifndef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE - /* HIGH - Enable strong ciphers - * !EXPORT - Disable export ciphers (40/56 bit) - * !aNULL - Disable anonymous auth ciphers - * @STRENGTH - Sort ciphers based on strength */ - SSL_CTX_set_cipher_list (ctx, "HIGH:!EXPORT:!aNULL@STRENGTH"); -#endif - - /* If renegotiation is needed, don't return from recv() or send() until it's - * successful. - * Note: this is for blocking sockets only. */ - SSL_CTX_set_mode (ctx, SSL_MODE_AUTO_RETRY); - - /* Load my private keys to present to the server */ - if (opt->pem_file && - !_mongoc_openssl_setup_pem_file (ctx, opt->pem_file, opt->pem_pwd)) { - SSL_CTX_free (ctx); - return NULL; - } - - /* Load in my Certificate Authority, to verify the server against - * If none provided, fallback to the distro defaults */ - if (opt->ca_file || opt->ca_dir) { - if (!_mongoc_openssl_setup_ca (ctx, opt->ca_file, opt->ca_dir)) { - SSL_CTX_free (ctx); - return NULL; - } - } else { -/* If the server certificate is issued by known CA we trust it by default */ -#ifdef _WIN32 - _mongoc_openssl_import_cert_stores (ctx); -#else - SSL_CTX_set_default_verify_paths (ctx); -#endif - } - - /* Load my revocation list, to verify the server against */ - if (opt->crl_file && !_mongoc_openssl_setup_crl (ctx, opt->crl_file)) { - SSL_CTX_free (ctx); - return NULL; - } - - return ctx; -} - - -char * -_mongoc_openssl_extract_subject (const char *filename, const char *passphrase) -{ - X509_NAME *subject = NULL; - X509 *cert = NULL; - BIO *certbio = NULL; - BIO *strbio = NULL; - char *str = NULL; - int ret; - - if (!filename) { - return NULL; - } - - certbio = BIO_new (BIO_s_file ()); - strbio = BIO_new (BIO_s_mem ()); - ; - - BSON_ASSERT (certbio); - BSON_ASSERT (strbio); - - - if (BIO_read_filename (certbio, filename) && - (cert = PEM_read_bio_X509 (certbio, NULL, 0, NULL))) { - if ((subject = X509_get_subject_name (cert))) { - ret = X509_NAME_print_ex (strbio, subject, 0, XN_FLAG_RFC2253); - - if ((ret > 0) && (ret < INT_MAX)) { - str = (char *) bson_malloc (ret + 2); - BIO_gets (strbio, str, ret + 1); - str[ret] = '\0'; - } - } - } - - if (cert) { - X509_free (cert); - } - - if (certbio) { - BIO_free (certbio); - } - - if (strbio) { - BIO_free (strbio); - } - - return str; -} - -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#ifdef _WIN32 - -static unsigned long -_mongoc_openssl_thread_id_callback (void) -{ - unsigned long ret; - - ret = (unsigned long) GetCurrentThreadId (); - return ret; -} - -#else - -static unsigned long -_mongoc_openssl_thread_id_callback (void) -{ - unsigned long ret; - - ret = (unsigned long) pthread_self (); - return ret; -} - -#endif - -static void -_mongoc_openssl_thread_locking_callback (int mode, - int type, - const char *file, - int line) -{ - if (mode & CRYPTO_LOCK) { - bson_mutex_lock (&gMongocOpenSslThreadLocks[type]); - } else { - bson_mutex_unlock (&gMongocOpenSslThreadLocks[type]); - } -} - -static void -_mongoc_openssl_thread_startup (void) -{ - int i; - - gMongocOpenSslThreadLocks = (bson_mutex_t *) OPENSSL_malloc ( - CRYPTO_num_locks () * sizeof (bson_mutex_t)); - - for (i = 0; i < CRYPTO_num_locks (); i++) { - bson_mutex_init (&gMongocOpenSslThreadLocks[i]); - } - - if (!CRYPTO_get_locking_callback ()) { - CRYPTO_set_locking_callback (_mongoc_openssl_thread_locking_callback); - CRYPTO_set_id_callback (_mongoc_openssl_thread_id_callback); - } -} - -static void -_mongoc_openssl_thread_cleanup (void) -{ - int i; - - if (CRYPTO_get_locking_callback () == - _mongoc_openssl_thread_locking_callback) { - CRYPTO_set_locking_callback (NULL); - } - - if (CRYPTO_get_id_callback () == _mongoc_openssl_thread_id_callback) { - CRYPTO_set_id_callback (NULL); - } - - for (i = 0; i < CRYPTO_num_locks (); i++) { - bson_mutex_destroy (&gMongocOpenSslThreadLocks[i]); - } - OPENSSL_free (gMongocOpenSslThreadLocks); -} -#endif - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-helpers-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-helpers-private.h deleted file mode 100644 index 707b07494fdcd00469dce0b56e78845c86acc006..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-helpers-private.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2019-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 "mongoc/mongoc-prelude.h" - -#include <bson/bson.h> -#include "mongoc/mongoc-client-session-private.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-write-command-private.h" - -#ifndef LIBMONGOC_MONGOC_OPTS_HELPERS_H -#define LIBMONGOC_MONGOC_OPTS_HELPERS_H - -#define _mongoc_convert_session_id _mongoc_client_session_from_iter - -typedef struct _mongoc_timestamp_t { - uint32_t timestamp; - uint32_t increment; -} mongoc_timestamp_t; - -bool -_mongoc_timestamp_empty (mongoc_timestamp_t *timestamp); - -void -_mongoc_timestamp_set (mongoc_timestamp_t *dst, mongoc_timestamp_t *src); - -void -_mongoc_timestamp_set_from_bson (mongoc_timestamp_t *timestamp, - bson_iter_t *iter); - -void -_mongoc_timestamp_append (mongoc_timestamp_t *timestamp, - bson_t *bson, - char *key); - -void -_mongoc_timestamp_clear (mongoc_timestamp_t *timestamp); - -bool -_mongoc_convert_document (mongoc_client_t *client, - const bson_iter_t *iter, - bson_t *doc, - bson_error_t *error); - -bool -_mongoc_convert_array (mongoc_client_t *client, - const bson_iter_t *iter, - bson_t *doc, - bson_error_t *error); - -bool -_mongoc_convert_int64_positive (mongoc_client_t *client, - const bson_iter_t *iter, - int64_t *num, - bson_error_t *error); - -bool -_mongoc_convert_int32_t (mongoc_client_t *client, - const bson_iter_t *iter, - int32_t *num, - bson_error_t *error); - -bool -_mongoc_convert_int32_positive (mongoc_client_t *client, - const bson_iter_t *iter, - int32_t *num, - bson_error_t *error); - -bool -_mongoc_convert_bool (mongoc_client_t *client, - const bson_iter_t *iter, - bool *flag, - bson_error_t *error); - -bool -_mongoc_convert_bson_value_t (mongoc_client_t *client, - const bson_iter_t *iter, - bson_value_t *value, - bson_error_t *error); - -bool -_mongoc_convert_timestamp (mongoc_client_t *client, - const bson_iter_t *iter, - mongoc_timestamp_t *timestamp, - bson_error_t *error); - -bool -_mongoc_convert_utf8 (mongoc_client_t *client, - const bson_iter_t *iter, - const char **comment, - bson_error_t *error); - -bool -_mongoc_convert_validate_flags (mongoc_client_t *client, - const bson_iter_t *iter, - bson_validate_flags_t *flags, - bson_error_t *error); - -bool -_mongoc_convert_mongoc_write_bypass_document_validation_t ( - mongoc_client_t *client, - const bson_iter_t *iter, - bool *bdv, - bson_error_t *error); - -bool -_mongoc_convert_write_concern (mongoc_client_t *client, - const bson_iter_t *iter, - mongoc_write_concern_t **wc, - bson_error_t *error); - -bool -_mongoc_convert_server_id (mongoc_client_t *client, - const bson_iter_t *iter, - uint32_t *server_id, - bson_error_t *error); - -bool -_mongoc_convert_read_concern (mongoc_client_t *client, - const bson_iter_t *iter, - mongoc_read_concern_t **rc, - bson_error_t *error); - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-helpers.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-helpers.c deleted file mode 100644 index b94d02e83a92b730bba1507048afff86ffcca79f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-helpers.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2019-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 "mongoc/mongoc-opts-helpers-private.h" -#include "mongoc/mongoc-client-session-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-read-concern-private.h" - -#define BSON_ERR(...) \ - do { \ - bson_set_error ( \ - error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, __VA_ARGS__); \ - return false; \ - } while (0) - - -#define CONVERSION_ERR(...) \ - do { \ - bson_set_error (error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - __VA_ARGS__); \ - return false; \ - } while (0) - - -bool -_mongoc_timestamp_empty (mongoc_timestamp_t *timestamp) -{ - return (timestamp->timestamp == 0 && timestamp->increment == 0); -} - -void -_mongoc_timestamp_set (mongoc_timestamp_t *dst, mongoc_timestamp_t *src) -{ - dst->timestamp = src->timestamp; - dst->increment = src->increment; -} - -void -_mongoc_timestamp_set_from_bson (mongoc_timestamp_t *timestamp, - bson_iter_t *iter) -{ - bson_iter_timestamp (iter, &(timestamp->timestamp), &(timestamp->increment)); -} - -void -_mongoc_timestamp_append (mongoc_timestamp_t *timestamp, - bson_t *bson, - char *key) -{ - bson_append_timestamp ( - bson, key, strlen (key), timestamp->timestamp, timestamp->increment); -} - -void -_mongoc_timestamp_clear (mongoc_timestamp_t *timestamp) -{ - timestamp->timestamp = 0; - timestamp->increment = 0; -} - -bool -_mongoc_convert_document (mongoc_client_t *client, - const bson_iter_t *iter, - bson_t *doc, - bson_error_t *error) -{ - uint32_t len; - const uint8_t *data; - bson_t value; - - if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { - CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain document," - " not %s", - bson_iter_key (iter), - _mongoc_bson_type_to_str (bson_iter_type (iter))); - } - - bson_iter_document (iter, &len, &data); - if (!bson_init_static (&value, data, len)) { - BSON_ERR ("Corrupt BSON in field \"%s\" in opts", bson_iter_key (iter)); - } - - bson_destroy (doc); - bson_copy_to (&value, doc); - - return true; -} - -bool -_mongoc_convert_array (mongoc_client_t *client, - const bson_iter_t *iter, - bson_t *doc, - bson_error_t *error) -{ - uint32_t len; - const uint8_t *data; - bson_t value; - - if (!BSON_ITER_HOLDS_ARRAY (iter)) { - CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain array," - " not %s", - bson_iter_key (iter), - _mongoc_bson_type_to_str (bson_iter_type (iter))); - } - - bson_iter_array (iter, &len, &data); - if (!bson_init_static (&value, data, len)) { - BSON_ERR ("Corrupt BSON in field \"%s\" in opts", bson_iter_key (iter)); - } - - bson_destroy (doc); - bson_copy_to (&value, doc); - - return true; -} - -bool -_mongoc_convert_int64_positive (mongoc_client_t *client, - const bson_iter_t *iter, - int64_t *num, - bson_error_t *error) -{ - int64_t i; - - if (!BSON_ITER_HOLDS_NUMBER (iter)) { - CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain number," - " not %s", - bson_iter_key (iter), - _mongoc_bson_type_to_str (bson_iter_type (iter))); - } - - i = bson_iter_as_int64 (iter); - if (i <= 0) { - CONVERSION_ERR ("Invalid field \"%s\" in opts, should be greater than 0," - " not %" PRId64, - bson_iter_key (iter), - i); - } - - *num = bson_iter_as_int64 (iter); - return true; -} - -bool -_mongoc_convert_int32_t (mongoc_client_t *client, - const bson_iter_t *iter, - int32_t *num, - bson_error_t *error) -{ - int64_t i; - - if (!BSON_ITER_HOLDS_NUMBER (iter)) { - CONVERSION_ERR ("Invalid field \"%s\" in opts", bson_iter_key (iter)); - } - - i = bson_iter_as_int64 (iter); - if (i > INT32_MAX || i < INT32_MIN) { - CONVERSION_ERR ("Invalid field \"%s\" in opts: %" PRId64 - " out of range for int32", - bson_iter_key (iter), - i); - } - - *num = (int32_t) i; - - return true; -} - -bool -_mongoc_convert_int32_positive (mongoc_client_t *client, - const bson_iter_t *iter, - int32_t *num, - bson_error_t *error) -{ - int32_t i; - - if (!_mongoc_convert_int32_t (client, iter, &i, error)) { - return false; - } - - if (i <= 0) { - CONVERSION_ERR ( - "Invalid field \"%s\" in opts, should be greater than 0, not %d", - bson_iter_key (iter), - i); - } - - *num = i; - - return true; -} - -bool -_mongoc_convert_bool (mongoc_client_t *client, - const bson_iter_t *iter, - bool *flag, - bson_error_t *error) -{ - if (BSON_ITER_HOLDS_BOOL (iter)) { - *flag = bson_iter_bool (iter); - return true; - } - - CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain bool," - " not %s", - bson_iter_key (iter), - _mongoc_bson_type_to_str (bson_iter_type (iter))); -} - -bool -_mongoc_convert_bson_value_t (mongoc_client_t *client, - const bson_iter_t *iter, - bson_value_t *value, - bson_error_t *error) -{ - bson_value_copy (bson_iter_value ((bson_iter_t *) iter), value); - return true; -} - -bool -_mongoc_convert_timestamp (mongoc_client_t *client, - const bson_iter_t *iter, - mongoc_timestamp_t *timestamp, - bson_error_t *error) -{ - bson_iter_timestamp (iter, ×tamp->timestamp, ×tamp->increment); - return true; -} - -bool -_mongoc_convert_utf8 (mongoc_client_t *client, - const bson_iter_t *iter, - const char **str, - bson_error_t *error) -{ - if (BSON_ITER_HOLDS_UTF8 (iter)) { - *str = bson_iter_utf8 (iter, NULL); - return true; - } - - CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain string," - " not %s", - bson_iter_key (iter), - _mongoc_bson_type_to_str (bson_iter_type (iter))); -} - -bool -_mongoc_convert_validate_flags (mongoc_client_t *client, - const bson_iter_t *iter, - bson_validate_flags_t *flags, - bson_error_t *error) -{ - if (BSON_ITER_HOLDS_BOOL (iter)) { - if (!bson_iter_as_bool (iter)) { - *flags = BSON_VALIDATE_NONE; - return true; - } else { - /* validate: false is ok but validate: true is prohibited */ - CONVERSION_ERR ("Invalid option \"%s\": true, must be a bitwise-OR of" - " bson_validate_flags_t values.", - bson_iter_key (iter)); - } - } else if (BSON_ITER_HOLDS_INT32 (iter)) { - if (bson_iter_int32 (iter) <= 0x1F) { - *flags = (bson_validate_flags_t) bson_iter_int32 (iter); - return true; - } else { - CONVERSION_ERR ("Invalid field \"%s\" in opts, must be a bitwise-OR of" - " bson_validate_flags_t values.", - bson_iter_key (iter)); - } - } - CONVERSION_ERR ("Invalid type for option \"%s\": \"%s\"." - " \"%s\" must be a boolean or a bitwise-OR of" - " bson_validate_flags_t values.", - bson_iter_key (iter), - _mongoc_bson_type_to_str (bson_iter_type (iter)), - bson_iter_key (iter)); -} - -bool -_mongoc_convert_write_concern (mongoc_client_t *client, - const bson_iter_t *iter, - mongoc_write_concern_t **wc, - bson_error_t *error) -{ - mongoc_write_concern_t *tmp; - - tmp = _mongoc_write_concern_new_from_iter (iter, error); - if (tmp) { - *wc = tmp; - return true; - } - - return false; -} - -bool -_mongoc_convert_server_id (mongoc_client_t *client, - const bson_iter_t *iter, - uint32_t *server_id, - bson_error_t *error) -{ - int64_t tmp; - - if (!BSON_ITER_HOLDS_INT (iter)) { - CONVERSION_ERR ("The serverId option must be an integer"); - } - - tmp = bson_iter_as_int64 (iter); - if (tmp <= 0) { - CONVERSION_ERR ("The serverId option must be >= 1"); - } - - *server_id = (uint32_t) tmp; - return true; -} - -bool -_mongoc_convert_read_concern (mongoc_client_t *client, - const bson_iter_t *iter, - mongoc_read_concern_t **rc, - bson_error_t *error) -{ - *rc = _mongoc_read_concern_new_from_iter (iter, error); - if (!*rc) { - return false; - } - return true; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-private.h deleted file mode 100644 index 77f5bf06804bb95fa68e3b8506b9e803c5eb87f1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-opts-private.h +++ /dev/null @@ -1,384 +0,0 @@ -#include "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_OPTS_H -#define MONGOC_OPTS_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-client-session.h" -#include "mongoc/mongoc-bulk-operation-private.h" -#include "mongoc/mongoc-opts-helpers-private.h" - -/************************************************** - * - * Generated by build/generate-opts.py. - * - * DO NOT EDIT THIS FILE. - * - *************************************************/ -/* clang-format off */ - -typedef struct _mongoc_crud_opts_t { - mongoc_write_concern_t *writeConcern; - bool write_concern_owned; - mongoc_client_session_t *client_session; - bson_validate_flags_t validate; -} mongoc_crud_opts_t; - -typedef struct _mongoc_update_opts_t { - mongoc_crud_opts_t crud; - bool bypass; - bson_t collation; - bool upsert; -} mongoc_update_opts_t; - -typedef struct _mongoc_insert_one_opts_t { - mongoc_crud_opts_t crud; - bool bypass; - bson_t extra; -} mongoc_insert_one_opts_t; - -typedef struct _mongoc_insert_many_opts_t { - mongoc_crud_opts_t crud; - bool ordered; - bool bypass; - bson_t extra; -} mongoc_insert_many_opts_t; - -typedef struct _mongoc_delete_one_opts_t { - mongoc_crud_opts_t crud; - bson_t collation; - bson_t extra; -} mongoc_delete_one_opts_t; - -typedef struct _mongoc_delete_many_opts_t { - mongoc_crud_opts_t crud; - bson_t collation; - bson_t extra; -} mongoc_delete_many_opts_t; - -typedef struct _mongoc_update_one_opts_t { - mongoc_update_opts_t update; - bson_t arrayFilters; - bson_t extra; -} mongoc_update_one_opts_t; - -typedef struct _mongoc_update_many_opts_t { - mongoc_update_opts_t update; - bson_t arrayFilters; - bson_t extra; -} mongoc_update_many_opts_t; - -typedef struct _mongoc_replace_one_opts_t { - mongoc_update_opts_t update; - bson_t extra; -} mongoc_replace_one_opts_t; - -typedef struct _mongoc_bulk_opts_t { - mongoc_write_concern_t *writeConcern; - bool write_concern_owned; - bool ordered; - mongoc_client_session_t *client_session; - bson_t extra; -} mongoc_bulk_opts_t; - -typedef struct _mongoc_bulk_insert_opts_t { - bson_validate_flags_t validate; - bson_t extra; -} mongoc_bulk_insert_opts_t; - -typedef struct _mongoc_bulk_update_opts_t { - bson_validate_flags_t validate; - bson_t collation; - bool upsert; - bool multi; -} mongoc_bulk_update_opts_t; - -typedef struct _mongoc_bulk_update_one_opts_t { - mongoc_bulk_update_opts_t update; - bson_t arrayFilters; - bson_t extra; -} mongoc_bulk_update_one_opts_t; - -typedef struct _mongoc_bulk_update_many_opts_t { - mongoc_bulk_update_opts_t update; - bson_t arrayFilters; - bson_t extra; -} mongoc_bulk_update_many_opts_t; - -typedef struct _mongoc_bulk_replace_one_opts_t { - mongoc_bulk_update_opts_t update; - bson_t extra; -} mongoc_bulk_replace_one_opts_t; - -typedef struct _mongoc_bulk_remove_opts_t { - bson_t collation; - int32_t limit; -} mongoc_bulk_remove_opts_t; - -typedef struct _mongoc_bulk_remove_one_opts_t { - mongoc_bulk_remove_opts_t remove; - bson_t extra; -} mongoc_bulk_remove_one_opts_t; - -typedef struct _mongoc_bulk_remove_many_opts_t { - mongoc_bulk_remove_opts_t remove; - bson_t extra; -} mongoc_bulk_remove_many_opts_t; - -typedef struct _mongoc_change_stream_opts_t { - int32_t batchSize; - bson_t resumeAfter; - bson_t startAfter; - mongoc_timestamp_t startAtOperationTime; - int64_t maxAwaitTimeMS; - const char *fullDocument; - bson_t extra; -} mongoc_change_stream_opts_t; - -typedef struct _mongoc_create_index_opts_t { - mongoc_write_concern_t *writeConcern; - bool write_concern_owned; - mongoc_client_session_t *client_session; - bson_t extra; -} mongoc_create_index_opts_t; - -typedef struct _mongoc_read_write_opts_t { - bson_t readConcern; - mongoc_write_concern_t *writeConcern; - bool write_concern_owned; - mongoc_client_session_t *client_session; - bson_t collation; - uint32_t serverId; - bson_t extra; -} mongoc_read_write_opts_t; - -typedef struct _mongoc_gridfs_bucket_opts_t { - const char *bucketName; - int32_t chunkSizeBytes; - mongoc_write_concern_t *writeConcern; - bool write_concern_owned; - mongoc_read_concern_t *readConcern; - bson_t extra; -} mongoc_gridfs_bucket_opts_t; - -typedef struct _mongoc_gridfs_bucket_upload_opts_t { - int32_t chunkSizeBytes; - bson_t metadata; - bson_t extra; -} mongoc_gridfs_bucket_upload_opts_t; - -typedef struct _mongoc_aggregate_opts_t { - mongoc_read_concern_t *readConcern; - mongoc_write_concern_t *writeConcern; - bool write_concern_owned; - mongoc_client_session_t *client_session; - bool bypass; - bson_t collation; - uint32_t serverId; - int32_t batchSize; - bool batchSize_is_set; - bson_t extra; -} mongoc_aggregate_opts_t; - -bool -_mongoc_insert_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_insert_one_opts_t *mongoc_insert_one_opts, - bson_error_t *error); - -void -_mongoc_insert_one_opts_cleanup (mongoc_insert_one_opts_t *mongoc_insert_one_opts); - -bool -_mongoc_insert_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_insert_many_opts_t *mongoc_insert_many_opts, - bson_error_t *error); - -void -_mongoc_insert_many_opts_cleanup (mongoc_insert_many_opts_t *mongoc_insert_many_opts); - -bool -_mongoc_delete_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_delete_one_opts_t *mongoc_delete_one_opts, - bson_error_t *error); - -void -_mongoc_delete_one_opts_cleanup (mongoc_delete_one_opts_t *mongoc_delete_one_opts); - -bool -_mongoc_delete_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_delete_many_opts_t *mongoc_delete_many_opts, - bson_error_t *error); - -void -_mongoc_delete_many_opts_cleanup (mongoc_delete_many_opts_t *mongoc_delete_many_opts); - -bool -_mongoc_update_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_update_one_opts_t *mongoc_update_one_opts, - bson_error_t *error); - -void -_mongoc_update_one_opts_cleanup (mongoc_update_one_opts_t *mongoc_update_one_opts); - -bool -_mongoc_update_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_update_many_opts_t *mongoc_update_many_opts, - bson_error_t *error); - -void -_mongoc_update_many_opts_cleanup (mongoc_update_many_opts_t *mongoc_update_many_opts); - -bool -_mongoc_replace_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_replace_one_opts_t *mongoc_replace_one_opts, - bson_error_t *error); - -void -_mongoc_replace_one_opts_cleanup (mongoc_replace_one_opts_t *mongoc_replace_one_opts); - -bool -_mongoc_bulk_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_opts_t *mongoc_bulk_opts, - bson_error_t *error); - -void -_mongoc_bulk_opts_cleanup (mongoc_bulk_opts_t *mongoc_bulk_opts); - -bool -_mongoc_bulk_insert_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts, - bson_error_t *error); - -void -_mongoc_bulk_insert_opts_cleanup (mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts); - -bool -_mongoc_bulk_update_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts, - bson_error_t *error); - -void -_mongoc_bulk_update_one_opts_cleanup (mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts); - -bool -_mongoc_bulk_update_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts, - bson_error_t *error); - -void -_mongoc_bulk_update_many_opts_cleanup (mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts); - -bool -_mongoc_bulk_replace_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts, - bson_error_t *error); - -void -_mongoc_bulk_replace_one_opts_cleanup (mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts); - -bool -_mongoc_bulk_remove_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts, - bson_error_t *error); - -void -_mongoc_bulk_remove_one_opts_cleanup (mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts); - -bool -_mongoc_bulk_remove_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts, - bson_error_t *error); - -void -_mongoc_bulk_remove_many_opts_cleanup (mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts); - -bool -_mongoc_change_stream_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_change_stream_opts_t *mongoc_change_stream_opts, - bson_error_t *error); - -void -_mongoc_change_stream_opts_cleanup (mongoc_change_stream_opts_t *mongoc_change_stream_opts); - -bool -_mongoc_create_index_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_create_index_opts_t *mongoc_create_index_opts, - bson_error_t *error); - -void -_mongoc_create_index_opts_cleanup (mongoc_create_index_opts_t *mongoc_create_index_opts); - -bool -_mongoc_read_write_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_read_write_opts_t *mongoc_read_write_opts, - bson_error_t *error); - -void -_mongoc_read_write_opts_cleanup (mongoc_read_write_opts_t *mongoc_read_write_opts); - -bool -_mongoc_gridfs_bucket_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts, - bson_error_t *error); - -void -_mongoc_gridfs_bucket_opts_cleanup (mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts); - -bool -_mongoc_gridfs_bucket_upload_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts, - bson_error_t *error); - -void -_mongoc_gridfs_bucket_upload_opts_cleanup (mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts); - -bool -_mongoc_aggregate_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_aggregate_opts_t *mongoc_aggregate_opts, - bson_error_t *error); - -void -_mongoc_aggregate_opts_cleanup (mongoc_aggregate_opts_t *mongoc_aggregate_opts); - -#endif /* MONGOC_OPTS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-opts.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-opts.c deleted file mode 100644 index 6d986fdecad222da4196836282935aecf1adcc30..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-opts.c +++ /dev/null @@ -1,1887 +0,0 @@ -#include "mongoc/mongoc-opts-helpers-private.h" -#include "mongoc/mongoc-opts-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-client-private.h" - -/************************************************** - * - * Generated by build/generate-opts.py. - * - * DO NOT EDIT THIS FILE. - * - *************************************************/ -/* clang-format off */ - - -bool -_mongoc_insert_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_insert_one_opts_t *mongoc_insert_one_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_insert_one_opts->crud.writeConcern = NULL; - mongoc_insert_one_opts->crud.write_concern_owned = false; - mongoc_insert_one_opts->crud.client_session = NULL; - mongoc_insert_one_opts->crud.validate = _mongoc_default_insert_vflags; - mongoc_insert_one_opts->bypass = false; - bson_init (&mongoc_insert_one_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_insert_one_opts->crud.writeConcern, - error)) { - return false; - } - - mongoc_insert_one_opts->crud.write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_insert_one_opts->crud.client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_insert_one_opts->crud.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_insert_one_opts->bypass, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_insert_one_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_insert_one_opts_cleanup (mongoc_insert_one_opts_t *mongoc_insert_one_opts) -{ - if (mongoc_insert_one_opts->crud.write_concern_owned) { - mongoc_write_concern_destroy (mongoc_insert_one_opts->crud.writeConcern); - } - bson_destroy (&mongoc_insert_one_opts->extra); -} - -bool -_mongoc_insert_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_insert_many_opts_t *mongoc_insert_many_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_insert_many_opts->crud.writeConcern = NULL; - mongoc_insert_many_opts->crud.write_concern_owned = false; - mongoc_insert_many_opts->crud.client_session = NULL; - mongoc_insert_many_opts->crud.validate = _mongoc_default_insert_vflags; - mongoc_insert_many_opts->ordered = true; - mongoc_insert_many_opts->bypass = false; - bson_init (&mongoc_insert_many_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_insert_many_opts->crud.writeConcern, - error)) { - return false; - } - - mongoc_insert_many_opts->crud.write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_insert_many_opts->crud.client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_insert_many_opts->crud.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "ordered")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_insert_many_opts->ordered, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_insert_many_opts->bypass, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_insert_many_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_insert_many_opts_cleanup (mongoc_insert_many_opts_t *mongoc_insert_many_opts) -{ - if (mongoc_insert_many_opts->crud.write_concern_owned) { - mongoc_write_concern_destroy (mongoc_insert_many_opts->crud.writeConcern); - } - bson_destroy (&mongoc_insert_many_opts->extra); -} - -bool -_mongoc_delete_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_delete_one_opts_t *mongoc_delete_one_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_delete_one_opts->crud.writeConcern = NULL; - mongoc_delete_one_opts->crud.write_concern_owned = false; - mongoc_delete_one_opts->crud.client_session = NULL; - mongoc_delete_one_opts->crud.validate = BSON_VALIDATE_NONE; - bson_init (&mongoc_delete_one_opts->collation); - bson_init (&mongoc_delete_one_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_delete_one_opts->crud.writeConcern, - error)) { - return false; - } - - mongoc_delete_one_opts->crud.write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_delete_one_opts->crud.client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_delete_one_opts->crud.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_delete_one_opts->collation, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_delete_one_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_delete_one_opts_cleanup (mongoc_delete_one_opts_t *mongoc_delete_one_opts) -{ - if (mongoc_delete_one_opts->crud.write_concern_owned) { - mongoc_write_concern_destroy (mongoc_delete_one_opts->crud.writeConcern); - } - bson_destroy (&mongoc_delete_one_opts->collation); - bson_destroy (&mongoc_delete_one_opts->extra); -} - -bool -_mongoc_delete_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_delete_many_opts_t *mongoc_delete_many_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_delete_many_opts->crud.writeConcern = NULL; - mongoc_delete_many_opts->crud.write_concern_owned = false; - mongoc_delete_many_opts->crud.client_session = NULL; - mongoc_delete_many_opts->crud.validate = BSON_VALIDATE_NONE; - bson_init (&mongoc_delete_many_opts->collation); - bson_init (&mongoc_delete_many_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_delete_many_opts->crud.writeConcern, - error)) { - return false; - } - - mongoc_delete_many_opts->crud.write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_delete_many_opts->crud.client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_delete_many_opts->crud.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_delete_many_opts->collation, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_delete_many_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_delete_many_opts_cleanup (mongoc_delete_many_opts_t *mongoc_delete_many_opts) -{ - if (mongoc_delete_many_opts->crud.write_concern_owned) { - mongoc_write_concern_destroy (mongoc_delete_many_opts->crud.writeConcern); - } - bson_destroy (&mongoc_delete_many_opts->collation); - bson_destroy (&mongoc_delete_many_opts->extra); -} - -bool -_mongoc_update_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_update_one_opts_t *mongoc_update_one_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_update_one_opts->update.crud.writeConcern = NULL; - mongoc_update_one_opts->update.crud.write_concern_owned = false; - mongoc_update_one_opts->update.crud.client_session = NULL; - mongoc_update_one_opts->update.crud.validate = _mongoc_default_update_vflags; - mongoc_update_one_opts->update.bypass = false; - bson_init (&mongoc_update_one_opts->update.collation); - mongoc_update_one_opts->update.upsert = false; - bson_init (&mongoc_update_one_opts->arrayFilters); - bson_init (&mongoc_update_one_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_update_one_opts->update.crud.writeConcern, - error)) { - return false; - } - - mongoc_update_one_opts->update.crud.write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_update_one_opts->update.crud.client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_update_one_opts->update.crud.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_update_one_opts->update.bypass, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_update_one_opts->update.collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "upsert")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_update_one_opts->update.upsert, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) { - if (!_mongoc_convert_array ( - client, - &iter, - &mongoc_update_one_opts->arrayFilters, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_update_one_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_update_one_opts_cleanup (mongoc_update_one_opts_t *mongoc_update_one_opts) -{ - if (mongoc_update_one_opts->update.crud.write_concern_owned) { - mongoc_write_concern_destroy (mongoc_update_one_opts->update.crud.writeConcern); - } - bson_destroy (&mongoc_update_one_opts->update.collation); - bson_destroy (&mongoc_update_one_opts->arrayFilters); - bson_destroy (&mongoc_update_one_opts->extra); -} - -bool -_mongoc_update_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_update_many_opts_t *mongoc_update_many_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_update_many_opts->update.crud.writeConcern = NULL; - mongoc_update_many_opts->update.crud.write_concern_owned = false; - mongoc_update_many_opts->update.crud.client_session = NULL; - mongoc_update_many_opts->update.crud.validate = _mongoc_default_update_vflags; - mongoc_update_many_opts->update.bypass = false; - bson_init (&mongoc_update_many_opts->update.collation); - mongoc_update_many_opts->update.upsert = false; - bson_init (&mongoc_update_many_opts->arrayFilters); - bson_init (&mongoc_update_many_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_update_many_opts->update.crud.writeConcern, - error)) { - return false; - } - - mongoc_update_many_opts->update.crud.write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_update_many_opts->update.crud.client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_update_many_opts->update.crud.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_update_many_opts->update.bypass, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_update_many_opts->update.collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "upsert")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_update_many_opts->update.upsert, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) { - if (!_mongoc_convert_array ( - client, - &iter, - &mongoc_update_many_opts->arrayFilters, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_update_many_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_update_many_opts_cleanup (mongoc_update_many_opts_t *mongoc_update_many_opts) -{ - if (mongoc_update_many_opts->update.crud.write_concern_owned) { - mongoc_write_concern_destroy (mongoc_update_many_opts->update.crud.writeConcern); - } - bson_destroy (&mongoc_update_many_opts->update.collation); - bson_destroy (&mongoc_update_many_opts->arrayFilters); - bson_destroy (&mongoc_update_many_opts->extra); -} - -bool -_mongoc_replace_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_replace_one_opts_t *mongoc_replace_one_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_replace_one_opts->update.crud.writeConcern = NULL; - mongoc_replace_one_opts->update.crud.write_concern_owned = false; - mongoc_replace_one_opts->update.crud.client_session = NULL; - mongoc_replace_one_opts->update.crud.validate = _mongoc_default_replace_vflags; - mongoc_replace_one_opts->update.bypass = false; - bson_init (&mongoc_replace_one_opts->update.collation); - mongoc_replace_one_opts->update.upsert = false; - bson_init (&mongoc_replace_one_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_replace_one_opts->update.crud.writeConcern, - error)) { - return false; - } - - mongoc_replace_one_opts->update.crud.write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_replace_one_opts->update.crud.client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_replace_one_opts->update.crud.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_replace_one_opts->update.bypass, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_replace_one_opts->update.collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "upsert")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_replace_one_opts->update.upsert, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_replace_one_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_replace_one_opts_cleanup (mongoc_replace_one_opts_t *mongoc_replace_one_opts) -{ - if (mongoc_replace_one_opts->update.crud.write_concern_owned) { - mongoc_write_concern_destroy (mongoc_replace_one_opts->update.crud.writeConcern); - } - bson_destroy (&mongoc_replace_one_opts->update.collation); - bson_destroy (&mongoc_replace_one_opts->extra); -} - -bool -_mongoc_bulk_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_opts_t *mongoc_bulk_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_bulk_opts->writeConcern = NULL; - mongoc_bulk_opts->write_concern_owned = false; - mongoc_bulk_opts->ordered = true; - mongoc_bulk_opts->client_session = NULL; - bson_init (&mongoc_bulk_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_bulk_opts->writeConcern, - error)) { - return false; - } - - mongoc_bulk_opts->write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "ordered")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_bulk_opts->ordered, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_bulk_opts->client_session, - error)) { - return false; - } - } - else { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option '%s'", - bson_iter_key (&iter)); - return false; - } - } - - return true; -} - -void -_mongoc_bulk_opts_cleanup (mongoc_bulk_opts_t *mongoc_bulk_opts) -{ - if (mongoc_bulk_opts->write_concern_owned) { - mongoc_write_concern_destroy (mongoc_bulk_opts->writeConcern); - } - bson_destroy (&mongoc_bulk_opts->extra); -} - -bool -_mongoc_bulk_insert_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_bulk_insert_opts->validate = _mongoc_default_insert_vflags; - bson_init (&mongoc_bulk_insert_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_bulk_insert_opts->validate, - error)) { - return false; - } - } - else { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option '%s'", - bson_iter_key (&iter)); - return false; - } - } - - return true; -} - -void -_mongoc_bulk_insert_opts_cleanup (mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts) -{ - bson_destroy (&mongoc_bulk_insert_opts->extra); -} - -bool -_mongoc_bulk_update_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_bulk_update_one_opts->update.validate = _mongoc_default_update_vflags; - bson_init (&mongoc_bulk_update_one_opts->update.collation); - mongoc_bulk_update_one_opts->update.upsert = false; - mongoc_bulk_update_one_opts->update.multi = false; - bson_init (&mongoc_bulk_update_one_opts->arrayFilters); - bson_init (&mongoc_bulk_update_one_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_bulk_update_one_opts->update.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_bulk_update_one_opts->update.collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "upsert")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_bulk_update_one_opts->update.upsert, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "multi")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_bulk_update_one_opts->update.multi, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) { - if (!_mongoc_convert_array ( - client, - &iter, - &mongoc_bulk_update_one_opts->arrayFilters, - error)) { - return false; - } - } - else { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option '%s'", - bson_iter_key (&iter)); - return false; - } - } - - return true; -} - -void -_mongoc_bulk_update_one_opts_cleanup (mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts) -{ - bson_destroy (&mongoc_bulk_update_one_opts->update.collation); - bson_destroy (&mongoc_bulk_update_one_opts->arrayFilters); - bson_destroy (&mongoc_bulk_update_one_opts->extra); -} - -bool -_mongoc_bulk_update_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_bulk_update_many_opts->update.validate = _mongoc_default_update_vflags; - bson_init (&mongoc_bulk_update_many_opts->update.collation); - mongoc_bulk_update_many_opts->update.upsert = false; - mongoc_bulk_update_many_opts->update.multi = true; - bson_init (&mongoc_bulk_update_many_opts->arrayFilters); - bson_init (&mongoc_bulk_update_many_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_bulk_update_many_opts->update.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_bulk_update_many_opts->update.collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "upsert")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_bulk_update_many_opts->update.upsert, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "multi")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_bulk_update_many_opts->update.multi, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) { - if (!_mongoc_convert_array ( - client, - &iter, - &mongoc_bulk_update_many_opts->arrayFilters, - error)) { - return false; - } - } - else { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option '%s'", - bson_iter_key (&iter)); - return false; - } - } - - return true; -} - -void -_mongoc_bulk_update_many_opts_cleanup (mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts) -{ - bson_destroy (&mongoc_bulk_update_many_opts->update.collation); - bson_destroy (&mongoc_bulk_update_many_opts->arrayFilters); - bson_destroy (&mongoc_bulk_update_many_opts->extra); -} - -bool -_mongoc_bulk_replace_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_bulk_replace_one_opts->update.validate = _mongoc_default_replace_vflags; - bson_init (&mongoc_bulk_replace_one_opts->update.collation); - mongoc_bulk_replace_one_opts->update.upsert = false; - mongoc_bulk_replace_one_opts->update.multi = false; - bson_init (&mongoc_bulk_replace_one_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "validate")) { - if (!_mongoc_convert_validate_flags ( - client, - &iter, - &mongoc_bulk_replace_one_opts->update.validate, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_bulk_replace_one_opts->update.collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "upsert")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_bulk_replace_one_opts->update.upsert, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "multi")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_bulk_replace_one_opts->update.multi, - error)) { - return false; - } - } - else { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option '%s'", - bson_iter_key (&iter)); - return false; - } - } - - return true; -} - -void -_mongoc_bulk_replace_one_opts_cleanup (mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts) -{ - bson_destroy (&mongoc_bulk_replace_one_opts->update.collation); - bson_destroy (&mongoc_bulk_replace_one_opts->extra); -} - -bool -_mongoc_bulk_remove_one_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - bson_init (&mongoc_bulk_remove_one_opts->remove.collation); - mongoc_bulk_remove_one_opts->remove.limit = 1; - bson_init (&mongoc_bulk_remove_one_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_bulk_remove_one_opts->remove.collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "limit")) { - if (!_mongoc_convert_int32_t ( - client, - &iter, - &mongoc_bulk_remove_one_opts->remove.limit, - error)) { - return false; - } - } - else { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option '%s'", - bson_iter_key (&iter)); - return false; - } - } - - return true; -} - -void -_mongoc_bulk_remove_one_opts_cleanup (mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts) -{ - bson_destroy (&mongoc_bulk_remove_one_opts->remove.collation); - bson_destroy (&mongoc_bulk_remove_one_opts->extra); -} - -bool -_mongoc_bulk_remove_many_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - bson_init (&mongoc_bulk_remove_many_opts->remove.collation); - mongoc_bulk_remove_many_opts->remove.limit = 0; - bson_init (&mongoc_bulk_remove_many_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_bulk_remove_many_opts->remove.collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "limit")) { - if (!_mongoc_convert_int32_t ( - client, - &iter, - &mongoc_bulk_remove_many_opts->remove.limit, - error)) { - return false; - } - } - else { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option '%s'", - bson_iter_key (&iter)); - return false; - } - } - - return true; -} - -void -_mongoc_bulk_remove_many_opts_cleanup (mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts) -{ - bson_destroy (&mongoc_bulk_remove_many_opts->remove.collation); - bson_destroy (&mongoc_bulk_remove_many_opts->extra); -} - -bool -_mongoc_change_stream_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_change_stream_opts_t *mongoc_change_stream_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_change_stream_opts->batchSize = 0; - bson_init (&mongoc_change_stream_opts->resumeAfter); - bson_init (&mongoc_change_stream_opts->startAfter); - memset (&mongoc_change_stream_opts->startAtOperationTime, 0, sizeof (mongoc_timestamp_t)); - mongoc_change_stream_opts->maxAwaitTimeMS = 0; - mongoc_change_stream_opts->fullDocument = "default"; - bson_init (&mongoc_change_stream_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "batchSize")) { - if (!_mongoc_convert_int32_t ( - client, - &iter, - &mongoc_change_stream_opts->batchSize, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "resumeAfter")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_change_stream_opts->resumeAfter, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "startAfter")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_change_stream_opts->startAfter, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "startAtOperationTime")) { - if (!_mongoc_convert_timestamp ( - client, - &iter, - &mongoc_change_stream_opts->startAtOperationTime, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "maxAwaitTimeMS")) { - if (!_mongoc_convert_int64_positive ( - client, - &iter, - &mongoc_change_stream_opts->maxAwaitTimeMS, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "fullDocument")) { - if (!_mongoc_convert_utf8 ( - client, - &iter, - &mongoc_change_stream_opts->fullDocument, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_change_stream_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_change_stream_opts_cleanup (mongoc_change_stream_opts_t *mongoc_change_stream_opts) -{ - bson_destroy (&mongoc_change_stream_opts->resumeAfter); - bson_destroy (&mongoc_change_stream_opts->startAfter); - bson_destroy (&mongoc_change_stream_opts->extra); -} - -bool -_mongoc_create_index_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_create_index_opts_t *mongoc_create_index_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_create_index_opts->writeConcern = NULL; - mongoc_create_index_opts->write_concern_owned = false; - mongoc_create_index_opts->client_session = NULL; - bson_init (&mongoc_create_index_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_create_index_opts->writeConcern, - error)) { - return false; - } - - mongoc_create_index_opts->write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_create_index_opts->client_session, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_create_index_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_create_index_opts_cleanup (mongoc_create_index_opts_t *mongoc_create_index_opts) -{ - if (mongoc_create_index_opts->write_concern_owned) { - mongoc_write_concern_destroy (mongoc_create_index_opts->writeConcern); - } - bson_destroy (&mongoc_create_index_opts->extra); -} - -bool -_mongoc_read_write_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_read_write_opts_t *mongoc_read_write_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - bson_init (&mongoc_read_write_opts->readConcern); - mongoc_read_write_opts->writeConcern = NULL; - mongoc_read_write_opts->write_concern_owned = false; - mongoc_read_write_opts->client_session = NULL; - bson_init (&mongoc_read_write_opts->collation); - mongoc_read_write_opts->serverId = 0; - bson_init (&mongoc_read_write_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "readConcern")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_read_write_opts->readConcern, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_read_write_opts->writeConcern, - error)) { - return false; - } - - mongoc_read_write_opts->write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_read_write_opts->client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_read_write_opts->collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "serverId")) { - if (!_mongoc_convert_server_id ( - client, - &iter, - &mongoc_read_write_opts->serverId, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_read_write_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_read_write_opts_cleanup (mongoc_read_write_opts_t *mongoc_read_write_opts) -{ - bson_destroy (&mongoc_read_write_opts->readConcern); - if (mongoc_read_write_opts->write_concern_owned) { - mongoc_write_concern_destroy (mongoc_read_write_opts->writeConcern); - } - bson_destroy (&mongoc_read_write_opts->collation); - bson_destroy (&mongoc_read_write_opts->extra); -} - -bool -_mongoc_gridfs_bucket_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_gridfs_bucket_opts->bucketName = "fs"; - mongoc_gridfs_bucket_opts->chunkSizeBytes = 261120; - mongoc_gridfs_bucket_opts->writeConcern = NULL; - mongoc_gridfs_bucket_opts->write_concern_owned = false; - mongoc_gridfs_bucket_opts->readConcern = NULL; - bson_init (&mongoc_gridfs_bucket_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "bucketName")) { - if (!_mongoc_convert_utf8 ( - client, - &iter, - &mongoc_gridfs_bucket_opts->bucketName, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "chunkSizeBytes")) { - if (!_mongoc_convert_int32_positive ( - client, - &iter, - &mongoc_gridfs_bucket_opts->chunkSizeBytes, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_gridfs_bucket_opts->writeConcern, - error)) { - return false; - } - - mongoc_gridfs_bucket_opts->write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "readConcern")) { - if (!_mongoc_convert_read_concern ( - client, - &iter, - &mongoc_gridfs_bucket_opts->readConcern, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_gridfs_bucket_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_gridfs_bucket_opts_cleanup (mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts) -{ - if (mongoc_gridfs_bucket_opts->write_concern_owned) { - mongoc_write_concern_destroy (mongoc_gridfs_bucket_opts->writeConcern); - } - mongoc_read_concern_destroy (mongoc_gridfs_bucket_opts->readConcern); - bson_destroy (&mongoc_gridfs_bucket_opts->extra); -} - -bool -_mongoc_gridfs_bucket_upload_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_gridfs_bucket_upload_opts->chunkSizeBytes = 0; - bson_init (&mongoc_gridfs_bucket_upload_opts->metadata); - bson_init (&mongoc_gridfs_bucket_upload_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "chunkSizeBytes")) { - if (!_mongoc_convert_int32_positive ( - client, - &iter, - &mongoc_gridfs_bucket_upload_opts->chunkSizeBytes, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "metadata")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_gridfs_bucket_upload_opts->metadata, - error)) { - return false; - } - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_gridfs_bucket_upload_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_gridfs_bucket_upload_opts_cleanup (mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts) -{ - bson_destroy (&mongoc_gridfs_bucket_upload_opts->metadata); - bson_destroy (&mongoc_gridfs_bucket_upload_opts->extra); -} - -bool -_mongoc_aggregate_opts_parse ( - mongoc_client_t *client, - const bson_t *opts, - mongoc_aggregate_opts_t *mongoc_aggregate_opts, - bson_error_t *error) -{ - bson_iter_t iter; - - mongoc_aggregate_opts->readConcern = NULL; - mongoc_aggregate_opts->writeConcern = NULL; - mongoc_aggregate_opts->write_concern_owned = false; - mongoc_aggregate_opts->client_session = NULL; - mongoc_aggregate_opts->bypass = false; - bson_init (&mongoc_aggregate_opts->collation); - mongoc_aggregate_opts->serverId = 0; - mongoc_aggregate_opts->batchSize = 0; - mongoc_aggregate_opts->batchSize_is_set = false; - bson_init (&mongoc_aggregate_opts->extra); - - if (!opts) { - return true; - } - - if (!bson_iter_init (&iter, opts)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_key (&iter), "readConcern")) { - if (!_mongoc_convert_read_concern ( - client, - &iter, - &mongoc_aggregate_opts->readConcern, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "writeConcern")) { - if (!_mongoc_convert_write_concern ( - client, - &iter, - &mongoc_aggregate_opts->writeConcern, - error)) { - return false; - } - - mongoc_aggregate_opts->write_concern_owned = true; - } - else if (!strcmp (bson_iter_key (&iter), "sessionId")) { - if (!_mongoc_convert_session_id ( - client, - &iter, - &mongoc_aggregate_opts->client_session, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) { - if (!_mongoc_convert_bool ( - client, - &iter, - &mongoc_aggregate_opts->bypass, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "collation")) { - if (!_mongoc_convert_document ( - client, - &iter, - &mongoc_aggregate_opts->collation, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "serverId")) { - if (!_mongoc_convert_server_id ( - client, - &iter, - &mongoc_aggregate_opts->serverId, - error)) { - return false; - } - } - else if (!strcmp (bson_iter_key (&iter), "batchSize")) { - if (!_mongoc_convert_int32_t ( - client, - &iter, - &mongoc_aggregate_opts->batchSize, - error)) { - return false; - } - - mongoc_aggregate_opts->batchSize_is_set = true; - } - else { - /* unrecognized values are copied to "extra" */ - if (!BSON_APPEND_VALUE ( - &mongoc_aggregate_opts->extra, - bson_iter_key (&iter), - bson_iter_value (&iter))) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Invalid 'opts' parameter."); - return false; - } - } - } - - return true; -} - -void -_mongoc_aggregate_opts_cleanup (mongoc_aggregate_opts_t *mongoc_aggregate_opts) -{ - mongoc_read_concern_destroy (mongoc_aggregate_opts->readConcern); - if (mongoc_aggregate_opts->write_concern_owned) { - mongoc_write_concern_destroy (mongoc_aggregate_opts->writeConcern); - } - bson_destroy (&mongoc_aggregate_opts->collation); - bson_destroy (&mongoc_aggregate_opts->extra); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-prelude.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-prelude.h deleted file mode 100644 index 5482e15b565e451da000f8e8da4bab96c06b27e2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-prelude.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2018-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. - */ - -#if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) -#error "Only <mongoc/mongoc.h> can be included directly." -#endif \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-queue-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-queue-private.h deleted file mode 100644 index f36794db8a667284d6e75b687fea9523d38deed8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-queue-private.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_QUEUE_PRIVATE_H -#define MONGOC_QUEUE_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-list-private.h" - - -BSON_BEGIN_DECLS - - -#define MONGOC_QUEUE_INITIALIZER \ - { \ - NULL, NULL \ - } - - -typedef struct _mongoc_queue_t mongoc_queue_t; -typedef struct _mongoc_queue_item_t mongoc_queue_item_t; - - -struct _mongoc_queue_t { - mongoc_queue_item_t *head; - mongoc_queue_item_t *tail; - uint32_t length; -}; - - -struct _mongoc_queue_item_t { - mongoc_queue_item_t *next; - void *data; -}; - - -void -_mongoc_queue_init (mongoc_queue_t *queue); -void * -_mongoc_queue_pop_head (mongoc_queue_t *queue); -void * -_mongoc_queue_pop_tail (mongoc_queue_t *queue); -void -_mongoc_queue_push_head (mongoc_queue_t *queue, void *data); -void -_mongoc_queue_push_tail (mongoc_queue_t *queue, void *data); -uint32_t -_mongoc_queue_get_length (const mongoc_queue_t *queue); - - -BSON_END_DECLS - - -#endif /* MONGOC_QUEUE_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-queue.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-queue.c deleted file mode 100644 index 9c8ea9786fb5867f4ea9d3f27e4e53ae0dee37ab..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-queue.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2013 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 <string.h> - -#include "mongoc/mongoc-queue-private.h" - - -void -_mongoc_queue_init (mongoc_queue_t *queue) -{ - BSON_ASSERT (queue); - - memset (queue, 0, sizeof *queue); -} - - -void -_mongoc_queue_push_head (mongoc_queue_t *queue, void *data) -{ - mongoc_queue_item_t *item; - - BSON_ASSERT (queue); - BSON_ASSERT (data); - - item = (mongoc_queue_item_t *) bson_malloc0 (sizeof *item); - item->next = queue->head; - item->data = data; - - queue->head = item; - - if (!queue->tail) { - queue->tail = item; - } - - queue->length++; -} - - -void -_mongoc_queue_push_tail (mongoc_queue_t *queue, void *data) -{ - mongoc_queue_item_t *item; - - BSON_ASSERT (queue); - BSON_ASSERT (data); - - item = (mongoc_queue_item_t *) bson_malloc0 (sizeof *item); - item->data = data; - - if (queue->tail) { - queue->tail->next = item; - } else { - queue->head = item; - } - - queue->tail = item; - queue->length++; -} - - -void * -_mongoc_queue_pop_head (mongoc_queue_t *queue) -{ - mongoc_queue_item_t *item; - void *data = NULL; - - BSON_ASSERT (queue); - - if ((item = queue->head)) { - if (!item->next) { - queue->tail = NULL; - } - queue->head = item->next; - data = item->data; - bson_free (item); - queue->length--; - } - - return data; -} - - -void * -_mongoc_queue_pop_tail (mongoc_queue_t *queue) -{ - mongoc_queue_item_t *item; - void *data = NULL; - - BSON_ASSERT (queue); - - if (queue->length == 0) { - return NULL; - } - - data = queue->tail->data; - - if (queue->length == 1) { - bson_free (queue->tail); - queue->head = queue->tail = NULL; - } else { - /* find item pointing at tail */ - for (item = queue->head; item; item = item->next) { - if (item->next == queue->tail) { - item->next = NULL; - bson_free (queue->tail); - queue->tail = item; - break; - } - } - } - - queue->length--; - - return data; -} - - -uint32_t -_mongoc_queue_get_length (const mongoc_queue_t *queue) -{ - BSON_ASSERT (queue); - - return queue->length; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-cng.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-cng.c deleted file mode 100644 index 784123fb66a95607457a27a4af5c2e3d59f57eb2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-cng.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL - -#include "mongoc/mongoc-rand.h" -#include "mongoc/mongoc-rand-private.h" - -#include "mongoc/mongoc.h" - -#include <windows.h> -#include <stdio.h> -#include <bcrypt.h> - -#define NT_SUCCESS(Status) (((NTSTATUS) (Status)) >= 0) -#define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L) - -int -_mongoc_rand_bytes (uint8_t *buf, int num) -{ - static BCRYPT_ALG_HANDLE algorithm = 0; - NTSTATUS status = 0; - - if (!algorithm) { - status = BCryptOpenAlgorithmProvider ( - &algorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); - if (!NT_SUCCESS (status)) { - MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %d", status); - return 0; - } - } - - status = BCryptGenRandom (algorithm, buf, num, 0); - if (NT_SUCCESS (status)) { - return 1; - } - - MONGOC_ERROR ("BCryptGenRandom(): %d", status); - return 0; -} - -void -mongoc_rand_seed (const void *buf, int num) -{ - /* N/A - OS Does not need entropy seed */ -} - -void -mongoc_rand_add (const void *buf, int num, double entropy) -{ - /* N/A - OS Does not need entropy seed */ -} - -int -mongoc_rand_status (void) -{ - return 1; -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-common-crypto.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-common-crypto.c deleted file mode 100644 index e2faba5783c3297c0803328116acf715cbea1fed..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-common-crypto.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO - -#include "mongoc/mongoc-rand.h" -#include "mongoc/mongoc-rand-private.h" - -#include "mongoc/mongoc.h" -#include <Security/Security.h> -/* rumour has it this wasn't in standard Security.h in ~10.8 */ -#include <Security/SecRandom.h> - -int -_mongoc_rand_bytes (uint8_t *buf, int num) -{ - return !SecRandomCopyBytes (kSecRandomDefault, num, buf); -} - -void -mongoc_rand_seed (const void *buf, int num) -{ - /* No such thing in Common Crypto */ -} - -void -mongoc_rand_add (const void *buf, int num, double entropy) -{ - /* No such thing in Common Crypto */ -} - -int -mongoc_rand_status (void) -{ - return 1; -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-openssl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-openssl.c deleted file mode 100644 index 3d03ace6f8050694e29d94362a54c64d4134cb19..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-openssl.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO - -#include "mongoc/mongoc-rand.h" -#include "mongoc/mongoc-rand-private.h" - -#include "mongoc/mongoc.h" - -#include <openssl/rand.h> - -int -_mongoc_rand_bytes (uint8_t *buf, int num) -{ - return RAND_bytes (buf, num); -} - -void -mongoc_rand_seed (const void *buf, int num) -{ - RAND_seed (buf, num); -} - -void -mongoc_rand_add (const void *buf, int num, double entropy) -{ - RAND_add (buf, num, entropy); -} - -int -mongoc_rand_status (void) -{ - return RAND_status (); -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-private.h deleted file mode 100644 index 402696d416e060a995dfee0decd5e36270f1b080..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand-private.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_RAND_PRIVATE_H -#define MONGOC_RAND_PRIVATE_H - - -#include <bson/bson.h> - - -BSON_BEGIN_DECLS - -int -_mongoc_rand_bytes (uint8_t *buf, int num); - -BSON_END_DECLS - - -#endif /* MONGOC_RAND_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-rand.h deleted file mode 100644 index 9dca817f57787756c8629c2c4f57bd32ed736bfe..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-rand.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_RAND_H -#define MONGOC_RAND_H - - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -MONGOC_EXPORT (void) -mongoc_rand_seed (const void *buf, int num); -MONGOC_EXPORT (void) -mongoc_rand_add (const void *buf, int num, double entropy); -MONGOC_EXPORT (int) -mongoc_rand_status (void); - -BSON_END_DECLS - - -#endif /* MONGOC_RAND_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern-private.h deleted file mode 100644 index e3fa1f85ae465513b23cdf38bbaf2ed4092e66a4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_READ_CONCERN_PRIVATE_H -#define MONGOC_READ_CONCERN_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-read-concern.h" - - -BSON_BEGIN_DECLS - - -struct _mongoc_read_concern_t { - char *level; - bool frozen; - bson_t compiled; -}; - - -const bson_t * -_mongoc_read_concern_get_bson (mongoc_read_concern_t *read_concern); - - -mongoc_read_concern_t * -_mongoc_read_concern_new_from_iter (const bson_iter_t *iter, - bson_error_t *error); - -BSON_END_DECLS - - -#endif /* MONGOC_READ_CONCERN_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern.c deleted file mode 100644 index 58266d73432d6e6a8eb53477e8d5a291bfba2d0c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-error.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-read-concern.h" -#include "mongoc/mongoc-read-concern-private.h" - - -static void -_mongoc_read_concern_freeze (mongoc_read_concern_t *read_concern); - - -/** - * mongoc_read_concern_new: - * - * Create a new mongoc_read_concern_t. - * - * Returns: A newly allocated mongoc_read_concern_t. This should be freed - * with mongoc_read_concern_destroy(). - */ -mongoc_read_concern_t * -mongoc_read_concern_new (void) -{ - mongoc_read_concern_t *read_concern; - - read_concern = (mongoc_read_concern_t *) bson_malloc0 (sizeof *read_concern); - - bson_init (&read_concern->compiled); - - return read_concern; -} - - -mongoc_read_concern_t * -mongoc_read_concern_copy (const mongoc_read_concern_t *read_concern) -{ - mongoc_read_concern_t *ret = NULL; - - if (read_concern) { - ret = mongoc_read_concern_new (); - ret->level = bson_strdup (read_concern->level); - } - - return ret; -} - - -/** - * mongoc_read_concern_destroy: - * @read_concern: A mongoc_read_concern_t. - * - * Releases a mongoc_read_concern_t and all associated memory. - */ -void -mongoc_read_concern_destroy (mongoc_read_concern_t *read_concern) -{ - if (read_concern) { - bson_destroy (&read_concern->compiled); - bson_free (read_concern->level); - bson_free (read_concern); - } -} - - -const char * -mongoc_read_concern_get_level (const mongoc_read_concern_t *read_concern) -{ - BSON_ASSERT (read_concern); - - return read_concern->level; -} - - -/** - * mongoc_read_concern_set_level: - * @read_concern: A mongoc_read_concern_t. - * @level: The read concern level - * - * Sets the read concern level. Any string is supported for future compatibility - * but MongoDB 3.2 only accepts "local" and "majority", aka: - * - MONGOC_READ_CONCERN_LEVEL_LOCAL - * - MONGOC_READ_CONCERN_LEVEL_MAJORITY - * MongoDB 3.4 added - * - MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE - * - * See the MongoDB docs for more information on readConcernLevel - */ -bool -mongoc_read_concern_set_level (mongoc_read_concern_t *read_concern, - const char *level) -{ - BSON_ASSERT (read_concern); - - bson_free (read_concern->level); - read_concern->level = bson_strdup (level); - read_concern->frozen = false; - - return true; -} - -/** - * mongoc_read_concern_append: - * @read_concern: (in): A mongoc_read_concern_t. - * @opts: (out): A pointer to a bson document. - * - * Appends a read_concern document to command options to send to - * a server. - * - * Returns true on success, false on failure. - * - */ -bool -mongoc_read_concern_append (mongoc_read_concern_t *read_concern, - bson_t *command) -{ - BSON_ASSERT (read_concern); - - if (!read_concern->level) { - return true; - } - - if (!bson_append_document (command, - "readConcern", - 11, - _mongoc_read_concern_get_bson (read_concern))) { - MONGOC_ERROR ("Could not append readConcern to command."); - return false; - } - - return true; -} - - -/** - * mongoc_read_concern_is_default: - * @read_concern: A const mongoc_read_concern_t. - * - * Returns true when read_concern has not been modified. - */ -bool -mongoc_read_concern_is_default (const mongoc_read_concern_t *read_concern) -{ - return !read_concern || !read_concern->level; -} - - -/** - * mongoc_read_concern_get_bson: - * @read_concern: A mongoc_read_concern_t. - * - * This is an internal function. - * - * Returns: A bson_t representing the read concern, which is owned by the - * mongoc_read_concern_t instance and should not be modified or freed. - */ -const bson_t * -_mongoc_read_concern_get_bson (mongoc_read_concern_t *read_concern) -{ - if (!read_concern->frozen) { - _mongoc_read_concern_freeze (read_concern); - } - - return &read_concern->compiled; -} - - -/** - * _mongoc_read_concern_new_from_iter: - * - * Create a new mongoc_read_concern_t from an iterator positioned on - * a "readConcern" document. - * - * Returns: A newly allocated mongoc_read_concern_t. This should be freed - * with mongoc_read_concern_destroy(). - */ -mongoc_read_concern_t * -_mongoc_read_concern_new_from_iter (const bson_iter_t *iter, - bson_error_t *error) -{ - bson_iter_t inner; - mongoc_read_concern_t *read_concern; - - BSON_ASSERT (iter); - - read_concern = mongoc_read_concern_new (); - if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { - goto fail; - } - - BSON_ASSERT (bson_iter_recurse (iter, &inner)); - if (!bson_iter_find (&inner, "level") || !BSON_ITER_HOLDS_UTF8 (&inner)) { - goto fail; - } - - mongoc_read_concern_set_level (read_concern, bson_iter_utf8 (&inner, NULL)); - - return read_concern; - -fail: - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid readConcern"); - - mongoc_read_concern_destroy (read_concern); - return NULL; -} - - -/** - * mongoc_read_concern_freeze: - * @read_concern: A mongoc_read_concern_t. - * - * This is an internal function. - * - * Encodes the read concern into a bson_t, which may then be returned by - * mongoc_read_concern_get_bson(). - */ -static void -_mongoc_read_concern_freeze (mongoc_read_concern_t *read_concern) -{ - bson_t *compiled; - - BSON_ASSERT (read_concern); - - compiled = &read_concern->compiled; - - read_concern->frozen = true; - - bson_reinit (compiled); - - if (read_concern->level) { - BSON_APPEND_UTF8 (compiled, "level", read_concern->level); - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern.h deleted file mode 100644 index a68ce5b677c86fbb6bcd7f60dbb74a591c076026..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-concern.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_READ_CONCERN_H -#define MONGOC_READ_CONCERN_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - - -#define MONGOC_READ_CONCERN_LEVEL_AVAILABLE "available" -#define MONGOC_READ_CONCERN_LEVEL_LOCAL "local" -#define MONGOC_READ_CONCERN_LEVEL_MAJORITY "majority" -#define MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE "linearizable" -#define MONGOC_READ_CONCERN_LEVEL_SNAPSHOT "snapshot" - -typedef struct _mongoc_read_concern_t mongoc_read_concern_t; - - -MONGOC_EXPORT (mongoc_read_concern_t *) -mongoc_read_concern_new (void); -MONGOC_EXPORT (mongoc_read_concern_t *) -mongoc_read_concern_copy (const mongoc_read_concern_t *read_concern); -MONGOC_EXPORT (void) -mongoc_read_concern_destroy (mongoc_read_concern_t *read_concern); -MONGOC_EXPORT (const char *) -mongoc_read_concern_get_level (const mongoc_read_concern_t *read_concern); -MONGOC_EXPORT (bool) -mongoc_read_concern_set_level (mongoc_read_concern_t *read_concern, - const char *level); -MONGOC_EXPORT (bool) -mongoc_read_concern_append (mongoc_read_concern_t *read_concern, bson_t *doc); -MONGOC_EXPORT (bool) -mongoc_read_concern_is_default (const mongoc_read_concern_t *read_concern); - -BSON_END_DECLS - - -#endif /* MONGOC_READ_CONCERN_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs-private.h deleted file mode 100644 index 35140928941bab1d5dd1668908dc5da3e0be431d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs-private.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_READ_PREFS_PRIVATE_H -#define MONGOC_READ_PREFS_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-read-prefs.h" - - -BSON_BEGIN_DECLS - -struct _mongoc_read_prefs_t { - mongoc_read_mode_t mode; - bson_t tags; - int64_t max_staleness_seconds; -}; - - -typedef struct _mongoc_assemble_query_result_t { - bson_t *assembled_query; - bool query_owned; - mongoc_query_flags_t flags; -} mongoc_assemble_query_result_t; - - -#define ASSEMBLE_QUERY_RESULT_INIT \ - { \ - NULL, false, MONGOC_QUERY_NONE \ - } - -const char * -_mongoc_read_mode_as_str (mongoc_read_mode_t mode); - -void -assemble_query (const mongoc_read_prefs_t *read_prefs, - const mongoc_server_stream_t *server_stream, - const bson_t *query_bson, - mongoc_query_flags_t initial_flags, - mongoc_assemble_query_result_t *result); - -void -assemble_query_result_cleanup (mongoc_assemble_query_result_t *result); - -bool -_mongoc_read_prefs_validate (const mongoc_read_prefs_t *read_prefs, - bson_error_t *error); - -#define IS_PREF_PRIMARY(_pref) \ - (!(_pref) || ((_pref)->mode == MONGOC_READ_PRIMARY)) - -BSON_END_DECLS - - -#endif /* MONGOC_READ_PREFS_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs.c deleted file mode 100644 index 0d1f2e7dbfbdef5dbc9441a8df4a9ad98fe9d25e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-error.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-trace-private.h" - - -mongoc_read_prefs_t * -mongoc_read_prefs_new (mongoc_read_mode_t mode) -{ - mongoc_read_prefs_t *read_prefs; - - read_prefs = (mongoc_read_prefs_t *) bson_malloc0 (sizeof *read_prefs); - read_prefs->mode = mode; - bson_init (&read_prefs->tags); - read_prefs->max_staleness_seconds = MONGOC_NO_MAX_STALENESS; - - return read_prefs; -} - - -mongoc_read_mode_t -mongoc_read_prefs_get_mode (const mongoc_read_prefs_t *read_prefs) -{ - return read_prefs ? read_prefs->mode : MONGOC_READ_PRIMARY; -} - - -void -mongoc_read_prefs_set_mode (mongoc_read_prefs_t *read_prefs, - mongoc_read_mode_t mode) -{ - BSON_ASSERT (read_prefs); - BSON_ASSERT (mode <= MONGOC_READ_NEAREST); - - read_prefs->mode = mode; -} - - -const bson_t * -mongoc_read_prefs_get_tags (const mongoc_read_prefs_t *read_prefs) -{ - BSON_ASSERT (read_prefs); - return &read_prefs->tags; -} - - -void -mongoc_read_prefs_set_tags (mongoc_read_prefs_t *read_prefs, const bson_t *tags) -{ - BSON_ASSERT (read_prefs); - - bson_destroy (&read_prefs->tags); - - if (tags) { - bson_copy_to (tags, &read_prefs->tags); - } else { - bson_init (&read_prefs->tags); - } -} - - -void -mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag) -{ - bson_t empty = BSON_INITIALIZER; - char str[16]; - int key; - - BSON_ASSERT (read_prefs); - - key = bson_count_keys (&read_prefs->tags); - bson_snprintf (str, sizeof str, "%d", key); - - if (tag) { - bson_append_document (&read_prefs->tags, str, -1, tag); - } else { - bson_append_document (&read_prefs->tags, str, -1, &empty); - } - - bson_destroy (&empty); -} - - -int64_t -mongoc_read_prefs_get_max_staleness_seconds ( - const mongoc_read_prefs_t *read_prefs) -{ - BSON_ASSERT (read_prefs); - - return read_prefs->max_staleness_seconds; -} - - -void -mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs, - int64_t max_staleness_seconds) -{ - BSON_ASSERT (read_prefs); - - read_prefs->max_staleness_seconds = max_staleness_seconds; -} - - -bool -mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs) -{ - BSON_ASSERT (read_prefs); - - /* - * Tags or maxStalenessSeconds are not supported with PRIMARY mode. - */ - if (read_prefs->mode == MONGOC_READ_PRIMARY) { - if (!bson_empty (&read_prefs->tags) || - read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { - return false; - } - } - - if (read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS && - read_prefs->max_staleness_seconds <= 0) { - return false; - } - - return true; -} - - -void -mongoc_read_prefs_destroy (mongoc_read_prefs_t *read_prefs) -{ - if (read_prefs) { - bson_destroy (&read_prefs->tags); - bson_free (read_prefs); - } -} - - -mongoc_read_prefs_t * -mongoc_read_prefs_copy (const mongoc_read_prefs_t *read_prefs) -{ - mongoc_read_prefs_t *ret = NULL; - - if (read_prefs) { - ret = mongoc_read_prefs_new (read_prefs->mode); - bson_destroy (&ret->tags); - bson_copy_to (&read_prefs->tags, &ret->tags); - ret->max_staleness_seconds = read_prefs->max_staleness_seconds; - } - - return ret; -} - - -const char * -_mongoc_read_mode_as_str (mongoc_read_mode_t mode) -{ - switch (mode) { - case MONGOC_READ_PRIMARY: - return "primary"; - case MONGOC_READ_PRIMARY_PREFERRED: - return "primaryPreferred"; - case MONGOC_READ_SECONDARY: - return "secondary"; - case MONGOC_READ_SECONDARY_PREFERRED: - return "secondaryPreferred"; - case MONGOC_READ_NEAREST: - return "nearest"; - default: - return ""; - } -} - - -/* Update result with the read prefs, following Server Selection Spec. - * The driver must have discovered the server is a mongos. - */ -static void -_apply_read_preferences_mongos ( - const mongoc_read_prefs_t *read_prefs, - const bson_t *query_bson, - mongoc_assemble_query_result_t *result /* OUT */) -{ - mongoc_read_mode_t mode; - const bson_t *tags = NULL; - bson_t child; - const char *mode_str; - int64_t max_staleness_seconds; - - mode = mongoc_read_prefs_get_mode (read_prefs); - if (read_prefs) { - tags = mongoc_read_prefs_get_tags (read_prefs); - } - - /* Server Selection Spec says: - * - * For mode 'primary', drivers MUST NOT set the slaveOK wire protocol flag - * and MUST NOT use $readPreference - * - * For mode 'secondary', drivers MUST set the slaveOK wire protocol flag and - * MUST also use $readPreference - * - * For mode 'primaryPreferred', drivers MUST set the slaveOK wire protocol - * flag and MUST also use $readPreference - * - * For mode 'secondaryPreferred', drivers MUST set the slaveOK wire protocol - * flag. If the read preference contains a non-empty tag_sets parameter, - * drivers MUST use $readPreference; otherwise, drivers MUST NOT use - * $readPreference - * - * For mode 'nearest', drivers MUST set the slaveOK wire protocol flag and - * MUST also use $readPreference - */ - if (mode == MONGOC_READ_SECONDARY_PREFERRED && bson_empty0 (tags)) { - result->flags |= MONGOC_QUERY_SLAVE_OK; - - } else if (mode != MONGOC_READ_PRIMARY) { - result->flags |= MONGOC_QUERY_SLAVE_OK; - - /* Server Selection Spec: "When any $ modifier is used, including the - * $readPreference modifier, the query MUST be provided using the $query - * modifier". - * - * This applies to commands, too. - */ - result->assembled_query = bson_new (); - result->query_owned = true; - - if (bson_has_field (query_bson, "$query")) { - bson_concat (result->assembled_query, query_bson); - } else { - bson_append_document ( - result->assembled_query, "$query", 6, query_bson); - } - - bson_append_document_begin ( - result->assembled_query, "$readPreference", 15, &child); - mode_str = _mongoc_read_mode_as_str (mode); - bson_append_utf8 (&child, "mode", 4, mode_str, -1); - if (!bson_empty0 (tags)) { - bson_append_array (&child, "tags", 4, tags); - } - - max_staleness_seconds = - mongoc_read_prefs_get_max_staleness_seconds (read_prefs); - - if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { - bson_append_int64 ( - &child, "maxStalenessSeconds", 19, max_staleness_seconds); - } - - bson_append_document_end (result->assembled_query, &child); - } -} - -/* - *-------------------------------------------------------------------------- - * - * assemble_query -- - * - * Update @result based on @read_prefs, following the Server Selection - * Spec. - * - * Side effects: - * Sets @result->assembled_query and @result->flags. - * - * Note: - * This function, the mongoc_assemble_query_result_t struct, and all - * related functions are only used for find operations with OP_QUERY. - * Remove them once we have implemented exhaust cursors with OP_MSG in - * the server, and all previous server versions are EOL. - * - *-------------------------------------------------------------------------- - */ - -void -assemble_query (const mongoc_read_prefs_t *read_prefs, - const mongoc_server_stream_t *server_stream, - const bson_t *query_bson, - mongoc_query_flags_t initial_flags, - mongoc_assemble_query_result_t *result /* OUT */) -{ - mongoc_server_description_type_t server_type; - - ENTRY; - - BSON_ASSERT (server_stream); - BSON_ASSERT (query_bson); - BSON_ASSERT (result); - - /* default values */ - result->assembled_query = (bson_t *) query_bson; - result->query_owned = false; - result->flags = initial_flags; - - server_type = server_stream->sd->type; - - switch (server_stream->topology_type) { - case MONGOC_TOPOLOGY_SINGLE: - if (server_type == MONGOC_SERVER_MONGOS) { - _apply_read_preferences_mongos (read_prefs, query_bson, result); - } else { - /* Server Selection Spec: for topology type single and server types - * besides mongos, "clients MUST always set the slaveOK wire protocol - * flag on reads to ensure that any server type can handle the - * request." - */ - result->flags |= MONGOC_QUERY_SLAVE_OK; - } - - break; - - case MONGOC_TOPOLOGY_RS_NO_PRIMARY: - case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: - /* Server Selection Spec: for RS topology types, "For all read - * preferences modes except primary, clients MUST set the slaveOK wire - * protocol flag to ensure that any suitable server can handle the - * request. Clients MUST NOT set the slaveOK wire protocol flag if the - * read preference mode is primary. - */ - if (read_prefs && read_prefs->mode != MONGOC_READ_PRIMARY) { - result->flags |= MONGOC_QUERY_SLAVE_OK; - } - - break; - - case MONGOC_TOPOLOGY_SHARDED: - _apply_read_preferences_mongos (read_prefs, query_bson, result); - break; - - case MONGOC_TOPOLOGY_UNKNOWN: - case MONGOC_TOPOLOGY_DESCRIPTION_TYPES: - default: - /* must not call _apply_read_preferences with unknown topology type */ - BSON_ASSERT (false); - } - - EXIT; -} - - -void -assemble_query_result_cleanup (mongoc_assemble_query_result_t *result) -{ - ENTRY; - - BSON_ASSERT (result); - - if (result->query_owned) { - bson_destroy (result->assembled_query); - } - - EXIT; -} - -bool -_mongoc_read_prefs_validate (const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) -{ - if (read_prefs && !mongoc_read_prefs_is_valid (read_prefs)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid mongoc_read_prefs_t"); - return false; - } - return true; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs.h deleted file mode 100644 index ef158be15afca18e578cf29e580a4e9df61bb55c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-read-prefs.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_READ_PREFS_H -#define MONGOC_READ_PREFS_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-config.h" - -BSON_BEGIN_DECLS - - -#define MONGOC_NO_MAX_STALENESS -1 -#define MONGOC_SMALLEST_MAX_STALENESS_SECONDS 90 - -typedef struct _mongoc_read_prefs_t mongoc_read_prefs_t; - - -typedef enum { - MONGOC_READ_PRIMARY = (1 << 0), - MONGOC_READ_SECONDARY = (1 << 1), - MONGOC_READ_PRIMARY_PREFERRED = (1 << 2) | MONGOC_READ_PRIMARY, - MONGOC_READ_SECONDARY_PREFERRED = (1 << 2) | MONGOC_READ_SECONDARY, - MONGOC_READ_NEAREST = (1 << 3) | MONGOC_READ_SECONDARY, -} mongoc_read_mode_t; - - -MONGOC_EXPORT (mongoc_read_prefs_t *) -mongoc_read_prefs_new (mongoc_read_mode_t read_mode); -MONGOC_EXPORT (mongoc_read_prefs_t *) -mongoc_read_prefs_copy (const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (void) -mongoc_read_prefs_destroy (mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (mongoc_read_mode_t) -mongoc_read_prefs_get_mode (const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (void) -mongoc_read_prefs_set_mode (mongoc_read_prefs_t *read_prefs, - mongoc_read_mode_t mode); -MONGOC_EXPORT (const bson_t *) -mongoc_read_prefs_get_tags (const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (void) -mongoc_read_prefs_set_tags (mongoc_read_prefs_t *read_prefs, - const bson_t *tags); -MONGOC_EXPORT (void) -mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag); -MONGOC_EXPORT (int64_t) -mongoc_read_prefs_get_max_staleness_seconds ( - const mongoc_read_prefs_t *read_prefs); -MONGOC_EXPORT (void) -mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs, - int64_t max_staleness_seconds); -MONGOC_EXPORT (bool) -mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs); - - -BSON_END_DECLS - - -#endif /* MONGOC_READ_PREFS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-rpc-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-rpc-private.h deleted file mode 100644 index 3b6df09a3eb54b69d614dbeb712182c6bd5b56dd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-rpc-private.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_RPC_PRIVATE_H -#define MONGOC_RPC_PRIVATE_H - -#include <bson/bson.h> -#include <stddef.h> - -#include "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-cmd-private.h" -#include "mongoc/mongoc-iovec.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-flags.h" -/* forward declaration */ -struct _mongoc_cluster_t; - -BSON_BEGIN_DECLS - -typedef struct _mongoc_rpc_section_t { - uint8_t payload_type; - union { - /* payload_type == 0 */ - const uint8_t *bson_document; - /* payload_type == 1 */ - struct { - int32_t size; - uint32_t size_le; - const char *identifier; - const uint8_t *bson_documents; - } sequence; - } payload; -} mongoc_rpc_section_t; - -#define RPC(_name, _code) \ - typedef struct { \ - _code \ - } mongoc_rpc_##_name##_t; -#define ENUM_FIELD(_name) uint32_t _name; -#define INT32_FIELD(_name) int32_t _name; -#define UINT8_FIELD(_name) uint8_t _name; -#define INT64_FIELD(_name) int64_t _name; -#define INT64_ARRAY_FIELD(_len, _name) \ - int32_t _len; \ - int64_t *_name; -#define CSTRING_FIELD(_name) const char *_name; -#define BSON_FIELD(_name) const uint8_t *_name; -#define BSON_ARRAY_FIELD(_name) \ - const uint8_t *_name; \ - int32_t _name##_len; -#define IOVEC_ARRAY_FIELD(_name) \ - const mongoc_iovec_t *_name; \ - int32_t n_##_name; \ - mongoc_iovec_t _name##_recv; -#define SECTION_ARRAY_FIELD(_name) \ - mongoc_rpc_section_t _name[2]; \ - int32_t n_##_name; -#define RAW_BUFFER_FIELD(_name) \ - const uint8_t *_name; \ - int32_t _name##_len; -#define BSON_OPTIONAL(_check, _code) _code - - -#pragma pack(1) -#include "op-delete.def" -#include "op-get-more.def" -#include "op-header.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-reply-header.def" -#include "op-update.def" -#include "op-compressed.def" -/* restore default packing */ -#pragma pack() - -#include "op-msg.def" - -typedef union { - mongoc_rpc_delete_t delete_; - mongoc_rpc_get_more_t get_more; - mongoc_rpc_header_t header; - mongoc_rpc_insert_t insert; - mongoc_rpc_kill_cursors_t kill_cursors; - mongoc_rpc_msg_t msg; - mongoc_rpc_query_t query; - mongoc_rpc_reply_t reply; - mongoc_rpc_reply_header_t reply_header; - mongoc_rpc_update_t update; - mongoc_rpc_compressed_t compressed; -} mongoc_rpc_t; - - -BSON_STATIC_ASSERT2 (sizeof_rpc_header, sizeof (mongoc_rpc_header_t) == 16); -BSON_STATIC_ASSERT2 (offsetof_rpc_header, - offsetof (mongoc_rpc_header_t, opcode) == - offsetof (mongoc_rpc_reply_t, opcode)); -BSON_STATIC_ASSERT2 (sizeof_reply_header, - sizeof (mongoc_rpc_reply_header_t) == 36); - - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef BSON_OPTIONAL -#undef RAW_BUFFER_FIELD - - -void -_mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array); -void -_mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc); -void -_mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc); -void -_mongoc_rpc_printf (mongoc_rpc_t *rpc); -bool -_mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen); -bool -_mongoc_rpc_scatter_reply_header_only (mongoc_rpc_t *rpc, - const uint8_t *buf, - size_t buflen); -bool -_mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply); -bool -_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson); -void -_mongoc_rpc_prep_command (mongoc_rpc_t *rpc, - const char *cmd_ns, - mongoc_cmd_t *cmd); -bool -_mongoc_rpc_check_ok (mongoc_rpc_t *rpc, - int32_t error_api_version, - bson_error_t *error /* OUT */, - bson_t *error_doc /* OUT */); -bool -_mongoc_cmd_check_ok (const bson_t *doc, - int32_t error_api_version, - bson_error_t *error); - -bool -_mongoc_cmd_check_ok_no_wce (const bson_t *doc, - int32_t error_api_version, - bson_error_t *error); - -bool -_mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen); - -char * -_mongoc_rpc_compress (struct _mongoc_cluster_t *cluster, - int32_t compressor_id, - mongoc_rpc_t *rpc_le, - bson_error_t *error); - -BSON_END_DECLS - - -#endif /* MONGOC_RPC_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-rpc.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-rpc.c deleted file mode 100644 index b9fb598dd35abb104b441fe737e2dfc9bf2818a2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-rpc.c +++ /dev/null @@ -1,1326 +0,0 @@ -/* - * Copyright 2013 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 <bson/bson.h> - -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-compression-private.h" -#include "mongoc/mongoc-cluster-private.h" - - -#define RPC(_name, _code) \ - static void _mongoc_rpc_gather_##_name (mongoc_rpc_##_name##_t *rpc, \ - mongoc_rpc_header_t *header, \ - mongoc_array_t *array) \ - { \ - mongoc_iovec_t iov; \ - BSON_ASSERT (rpc); \ - BSON_ASSERT (array); \ - header->msg_len = 0; \ - _code \ - } -#define UINT8_FIELD(_name) \ - iov.iov_base = (void *) &rpc->_name; \ - iov.iov_len = 1; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define INT32_FIELD(_name) \ - iov.iov_base = (void *) &rpc->_name; \ - iov.iov_len = 4; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define ENUM_FIELD INT32_FIELD -#define INT64_FIELD(_name) \ - iov.iov_base = (void *) &rpc->_name; \ - iov.iov_len = 8; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define CSTRING_FIELD(_name) \ - BSON_ASSERT (rpc->_name); \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = strlen (rpc->_name) + 1; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define BSON_FIELD(_name) \ - do { \ - int32_t __l; \ - memcpy (&__l, rpc->_name, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = __l; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - } while (0); -#define BSON_OPTIONAL(_check, _code) \ - if (rpc->_check) { \ - _code \ - } -#define BSON_ARRAY_FIELD(_name) \ - if (rpc->_name##_len) { \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = rpc->_name##_len; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - } -#define IOVEC_ARRAY_FIELD(_name) \ - do { \ - ssize_t _i; \ - BSON_ASSERT (rpc->n_##_name); \ - for (_i = 0; _i < rpc->n_##_name; _i++) { \ - BSON_ASSERT (rpc->_name[_i].iov_len); \ - header->msg_len += (int32_t) rpc->_name[_i].iov_len; \ - _mongoc_array_append_val (array, rpc->_name[_i]); \ - } \ - } while (0); -#define SECTION_ARRAY_FIELD(_name) \ - do { \ - ssize_t _i; \ - BSON_ASSERT (rpc->n_##_name); \ - for (_i = 0; _i < rpc->n_##_name; _i++) { \ - int32_t __l; \ - iov.iov_base = (void *) &rpc->_name[_i].payload_type; \ - iov.iov_len = 1; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - switch (rpc->_name[_i].payload_type) { \ - case 0: \ - memcpy (&__l, rpc->_name[_i].payload.bson_document, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - iov.iov_base = (void *) rpc->_name[_i].payload.bson_document; \ - iov.iov_len = __l; \ - break; \ - case 1: \ - rpc->_name[_i].payload.sequence.size_le = \ - BSON_UINT32_TO_LE (rpc->_name[_i].payload.sequence.size); \ - iov.iov_base = (void *) &rpc->_name[_i].payload.sequence.size_le; \ - iov.iov_len = 4; \ - header->msg_len += 4; \ - _mongoc_array_append_val (array, iov); \ - iov.iov_base = \ - (void *) rpc->_name[_i].payload.sequence.identifier; \ - iov.iov_len = \ - strlen (rpc->_name[_i].payload.sequence.identifier) + 1; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - iov.iov_base = \ - (void *) rpc->_name[_i].payload.sequence.bson_documents; \ - iov.iov_len = \ - rpc->_name[_i].payload.sequence.size - iov.iov_len - 4; \ - break; \ - default: \ - MONGOC_ERROR ("Unknown Payload Type: %d", \ - rpc->_name[_i].payload_type); \ - BSON_ASSERT (0); \ - } \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - } \ - } while (0); -#define RAW_BUFFER_FIELD(_name) \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = rpc->_name##_len; \ - BSON_ASSERT (iov.iov_len); \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); -#define INT64_ARRAY_FIELD(_len, _name) \ - iov.iov_base = (void *) &rpc->_len; \ - iov.iov_len = 4; \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); \ - iov.iov_base = (void *) rpc->_name; \ - iov.iov_len = rpc->_len * 8; \ - BSON_ASSERT (iov.iov_len); \ - header->msg_len += (int32_t) iov.iov_len; \ - _mongoc_array_append_val (array, iov); - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-compressed.def" -#include "op-update.def" - - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef RAW_BUFFER_FIELD -#undef BSON_OPTIONAL - - -#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN - -#define RPC(_name, _code) \ - static void _mongoc_rpc_swab_to_le_##_name (mongoc_rpc_##_name##_t *rpc) \ - { \ - BSON_ASSERT (rpc); \ - _code \ - } -#define UINT8_FIELD(_name) -#define INT32_FIELD(_name) rpc->_name = BSON_UINT32_FROM_LE (rpc->_name); -#define ENUM_FIELD INT32_FIELD -#define INT64_FIELD(_name) rpc->_name = BSON_UINT64_FROM_LE (rpc->_name); -#define CSTRING_FIELD(_name) -#define BSON_FIELD(_name) -#define BSON_ARRAY_FIELD(_name) -#define IOVEC_ARRAY_FIELD(_name) -#define SECTION_ARRAY_FIELD(_name) -#define BSON_OPTIONAL(_check, _code) \ - if (rpc->_check) { \ - _code \ - } -#define RAW_BUFFER_FIELD(_name) -#define INT64_ARRAY_FIELD(_len, _name) \ - do { \ - ssize_t i; \ - for (i = 0; i < rpc->_len; i++) { \ - rpc->_name[i] = BSON_UINT64_FROM_LE (rpc->_name[i]); \ - } \ - rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \ - } while (0); - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-compressed.def" -#include "op-update.def" - -#undef RPC -#undef INT64_ARRAY_FIELD - -#define RPC(_name, _code) \ - static void _mongoc_rpc_swab_from_le_##_name (mongoc_rpc_##_name##_t *rpc) \ - { \ - BSON_ASSERT (rpc); \ - _code \ - } -#define INT64_ARRAY_FIELD(_len, _name) \ - do { \ - ssize_t i; \ - rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \ - for (i = 0; i < rpc->_len; i++) { \ - rpc->_name[i] = BSON_UINT64_FROM_LE (rpc->_name[i]); \ - } \ - } while (0); - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-compressed.def" -#include "op-update.def" - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef BSON_OPTIONAL -#undef RAW_BUFFER_FIELD - -#endif /* BSON_BYTE_ORDER == BSON_BIG_ENDIAN */ - - -#define RPC(_name, _code) \ - static void _mongoc_rpc_printf_##_name (mongoc_rpc_##_name##_t *rpc) \ - { \ - BSON_ASSERT (rpc); \ - _code \ - } -#define UINT8_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name); -#define INT32_FIELD(_name) printf (" " #_name " : %d\n", rpc->_name); -#define ENUM_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name); -#define INT64_FIELD(_name) \ - printf (" " #_name " : %" PRIi64 "\n", (int64_t) rpc->_name); -#define CSTRING_FIELD(_name) printf (" " #_name " : %s\n", rpc->_name); -#define BSON_FIELD(_name) \ - do { \ - bson_t b; \ - char *s; \ - int32_t __l; \ - memcpy (&__l, rpc->_name, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - BSON_ASSERT (bson_init_static (&b, rpc->_name, __l)); \ - s = bson_as_relaxed_extended_json (&b, NULL); \ - printf (" " #_name " : %s\n", s); \ - bson_free (s); \ - bson_destroy (&b); \ - } while (0); -#define BSON_ARRAY_FIELD(_name) \ - do { \ - bson_reader_t *__r; \ - bool __eof; \ - const bson_t *__b; \ - __r = bson_reader_new_from_data (rpc->_name, rpc->_name##_len); \ - while ((__b = bson_reader_read (__r, &__eof))) { \ - char *s = bson_as_relaxed_extended_json (__b, NULL); \ - printf (" " #_name " : %s\n", s); \ - bson_free (s); \ - } \ - bson_reader_destroy (__r); \ - } while (0); -#define IOVEC_ARRAY_FIELD(_name) \ - do { \ - ssize_t _i; \ - size_t _j; \ - for (_i = 0; _i < rpc->n_##_name; _i++) { \ - printf (" " #_name " : "); \ - for (_j = 0; _j < rpc->_name[_i].iov_len; _j++) { \ - uint8_t u; \ - u = ((char *) rpc->_name[_i].iov_base)[_j]; \ - printf (" %02x", u); \ - } \ - printf ("\n"); \ - } \ - } while (0); -#define SECTION_ARRAY_FIELD(_name) \ - do { \ - ssize_t _i; \ - printf (" " #_name " : %d\n", rpc->n_##_name); \ - for (_i = 0; _i < rpc->n_##_name; _i++) { \ - if (rpc->_name[_i].payload_type == 0) { \ - do { \ - bson_t b; \ - char *s; \ - int32_t __l; \ - memcpy (&__l, rpc->_name[_i].payload.bson_document, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - BSON_ASSERT (bson_init_static ( \ - &b, rpc->_name[_i].payload.bson_document, __l)); \ - s = bson_as_relaxed_extended_json (&b, NULL); \ - printf (" Type %d: %s\n", rpc->_name[_i].payload_type, s); \ - bson_free (s); \ - bson_destroy (&b); \ - } while (0); \ - } else if (rpc->_name[_i].payload_type == 1) { \ - bson_reader_t *__r; \ - int max = rpc->_name[_i].payload.sequence.size - \ - strlen (rpc->_name[_i].payload.sequence.identifier) - \ - 1 - sizeof (int32_t); \ - bool __eof; \ - const bson_t *__b; \ - printf (" Identifier: %s\n", \ - rpc->_name[_i].payload.sequence.identifier); \ - printf (" Size: %d\n", max); \ - __r = bson_reader_new_from_data ( \ - rpc->_name[_i].payload.sequence.bson_documents, max); \ - while ((__b = bson_reader_read (__r, &__eof))) { \ - char *s = bson_as_relaxed_extended_json (__b, NULL); \ - bson_free (s); \ - } \ - bson_reader_destroy (__r); \ - } \ - } \ - } while (0); -#define BSON_OPTIONAL(_check, _code) \ - if (rpc->_check) { \ - _code \ - } -#define RAW_BUFFER_FIELD(_name) \ - { \ - ssize_t __i; \ - printf (" " #_name " :"); \ - for (__i = 0; __i < rpc->_name##_len; __i++) { \ - uint8_t u; \ - u = ((char *) rpc->_name)[__i]; \ - printf (" %02x", u); \ - } \ - printf ("\n"); \ - } -#define INT64_ARRAY_FIELD(_len, _name) \ - do { \ - ssize_t i; \ - for (i = 0; i < rpc->_len; i++) { \ - printf (" " #_name " : %" PRIi64 "\n", (int64_t) rpc->_name[i]); \ - } \ - rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \ - } while (0); - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-compressed.def" -#include "op-update.def" - - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef BSON_OPTIONAL -#undef RAW_BUFFER_FIELD - - -#define RPC(_name, _code) \ - static bool _mongoc_rpc_scatter_##_name ( \ - mongoc_rpc_##_name##_t *rpc, const uint8_t *buf, size_t buflen) \ - { \ - BSON_ASSERT (rpc); \ - BSON_ASSERT (buf); \ - BSON_ASSERT (buflen); \ - _code return true; \ - } -#define UINT8_FIELD(_name) \ - if (buflen < 1) { \ - return false; \ - } \ - memcpy (&rpc->_name, buf, 1); \ - buflen -= 1; \ - buf += 1; -#define INT32_FIELD(_name) \ - if (buflen < 4) { \ - return false; \ - } \ - memcpy (&rpc->_name, buf, 4); \ - buflen -= 4; \ - buf += 4; -#define ENUM_FIELD INT32_FIELD -#define INT64_FIELD(_name) \ - if (buflen < 8) { \ - return false; \ - } \ - memcpy (&rpc->_name, buf, 8); \ - buflen -= 8; \ - buf += 8; -#define INT64_ARRAY_FIELD(_len, _name) \ - do { \ - size_t needed; \ - if (buflen < 4) { \ - return false; \ - } \ - memcpy (&rpc->_len, buf, 4); \ - buflen -= 4; \ - buf += 4; \ - needed = BSON_UINT32_FROM_LE (rpc->_len) * 8; \ - if (needed > buflen) { \ - return false; \ - } \ - rpc->_name = (int64_t *) buf; \ - buf += needed; \ - buflen -= needed; \ - } while (0); -#define CSTRING_FIELD(_name) \ - do { \ - size_t __i; \ - bool found = false; \ - for (__i = 0; __i < buflen; __i++) { \ - if (!buf[__i]) { \ - rpc->_name = (const char *) buf; \ - buflen -= __i + 1; \ - buf += __i + 1; \ - found = true; \ - break; \ - } \ - } \ - if (!found) { \ - return false; \ - } \ - } while (0); -#define BSON_FIELD(_name) \ - do { \ - uint32_t __l; \ - if (buflen < 4) { \ - return false; \ - } \ - memcpy (&__l, buf, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - if (__l < 5 || __l > buflen) { \ - return false; \ - } \ - rpc->_name = (uint8_t *) buf; \ - buf += __l; \ - buflen -= __l; \ - } while (0); -#define BSON_ARRAY_FIELD(_name) \ - rpc->_name = (uint8_t *) buf; \ - rpc->_name##_len = (int32_t) buflen; \ - buf = NULL; \ - buflen = 0; -#define BSON_OPTIONAL(_check, _code) \ - if (buflen) { \ - _code \ - } -#define IOVEC_ARRAY_FIELD(_name) \ - rpc->_name##_recv.iov_base = (void *) buf; \ - rpc->_name##_recv.iov_len = buflen; \ - rpc->_name = &rpc->_name##_recv; \ - rpc->n_##_name = 1; \ - buf = NULL; \ - buflen = 0; -#define SECTION_ARRAY_FIELD(_name) \ - do { \ - uint32_t __l; \ - mongoc_rpc_section_t *section = &rpc->_name[rpc->n_##_name]; \ - section->payload_type = buf[0]; \ - buf++; \ - buflen -= 1; \ - memcpy (&__l, buf, 4); \ - __l = BSON_UINT32_FROM_LE (__l); \ - if (section->payload_type == 0) { \ - section->payload.bson_document = buf; \ - } else { \ - const uint8_t *section_buf = buf + 4; \ - section->payload.sequence.size = __l; \ - section->payload.sequence.identifier = (const char *) section_buf; \ - section_buf += strlen ((const char *) section_buf) + 1; \ - section->payload.sequence.bson_documents = section_buf; \ - } \ - buf += __l; \ - buflen -= __l; \ - rpc->n_##_name++; \ - } while (buflen); -#define RAW_BUFFER_FIELD(_name) \ - rpc->_name = (void *) buf; \ - rpc->_name##_len = (int32_t) buflen; \ - buf = NULL; \ - buflen = 0; - - -#include "op-delete.def" -#include "op-get-more.def" -#include "op-header.def" -#include "op-insert.def" -#include "op-kill-cursors.def" -#include "op-msg.def" -#include "op-query.def" -#include "op-reply.def" -#include "op-reply-header.def" -#include "op-compressed.def" -#include "op-update.def" - - -#undef RPC -#undef ENUM_FIELD -#undef UINT8_FIELD -#undef INT32_FIELD -#undef INT64_FIELD -#undef INT64_ARRAY_FIELD -#undef CSTRING_FIELD -#undef BSON_FIELD -#undef BSON_ARRAY_FIELD -#undef IOVEC_ARRAY_FIELD -#undef SECTION_ARRAY_FIELD -#undef BSON_OPTIONAL -#undef RAW_BUFFER_FIELD - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_gather -- - * - * Takes a (native endian) rpc struct and gathers the buffer. - * Caller should swab to little endian after calling gather. - * - * Gather, swab, compress write. - * Read, scatter, uncompress, swab - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array) -{ - mongoc_counter_op_egress_total_inc (); - switch ((mongoc_opcode_t) rpc->header.opcode) { - case MONGOC_OPCODE_REPLY: - _mongoc_rpc_gather_reply (&rpc->reply, &rpc->header, array); - return; - - case MONGOC_OPCODE_MSG: - _mongoc_rpc_gather_msg (&rpc->msg, &rpc->header, array); - mongoc_counter_op_egress_msg_inc (); - return; - - case MONGOC_OPCODE_UPDATE: - _mongoc_rpc_gather_update (&rpc->update, &rpc->header, array); - mongoc_counter_op_egress_update_inc (); - return; - - case MONGOC_OPCODE_INSERT: - _mongoc_rpc_gather_insert (&rpc->insert, &rpc->header, array); - mongoc_counter_op_egress_insert_inc (); - return; - - case MONGOC_OPCODE_QUERY: - _mongoc_rpc_gather_query (&rpc->query, &rpc->header, array); - mongoc_counter_op_egress_query_inc (); - return; - - case MONGOC_OPCODE_GET_MORE: - _mongoc_rpc_gather_get_more (&rpc->get_more, &rpc->header, array); - mongoc_counter_op_egress_getmore_inc (); - return; - - case MONGOC_OPCODE_DELETE: - _mongoc_rpc_gather_delete (&rpc->delete_, &rpc->header, array); - mongoc_counter_op_egress_delete_inc (); - return; - - case MONGOC_OPCODE_KILL_CURSORS: - _mongoc_rpc_gather_kill_cursors (&rpc->kill_cursors, &rpc->header, array); - mongoc_counter_op_egress_killcursors_inc (); - return; - - case MONGOC_OPCODE_COMPRESSED: - _mongoc_rpc_gather_compressed (&rpc->compressed, &rpc->header, array); - mongoc_counter_op_egress_compressed_inc (); - return; - - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode); - BSON_ASSERT (false); - break; - } -} - - -void -_mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc) -{ -#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN - mongoc_opcode_t opcode; - - opcode = rpc->header.opcode; - - switch (opcode) { - case MONGOC_OPCODE_REPLY: - _mongoc_rpc_swab_to_le_reply (&rpc->reply); - break; - case MONGOC_OPCODE_MSG: - _mongoc_rpc_swab_to_le_msg (&rpc->msg); - break; - case MONGOC_OPCODE_UPDATE: - _mongoc_rpc_swab_to_le_update (&rpc->update); - break; - case MONGOC_OPCODE_INSERT: - _mongoc_rpc_swab_to_le_insert (&rpc->insert); - break; - case MONGOC_OPCODE_QUERY: - _mongoc_rpc_swab_to_le_query (&rpc->query); - break; - case MONGOC_OPCODE_GET_MORE: - _mongoc_rpc_swab_to_le_get_more (&rpc->get_more); - break; - case MONGOC_OPCODE_DELETE: - _mongoc_rpc_swab_to_le_delete (&rpc->delete_); - break; - case MONGOC_OPCODE_KILL_CURSORS: - _mongoc_rpc_swab_to_le_kill_cursors (&rpc->kill_cursors); - break; - case MONGOC_OPCODE_COMPRESSED: - _mongoc_rpc_swab_to_le_compressed (&rpc->compressed); - break; - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode); - break; - } -#endif -#if 0 - _mongoc_rpc_printf (rpc); -#endif -} - - -void -_mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc) -{ -#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN - mongoc_opcode_t opcode; - - opcode = BSON_UINT32_FROM_LE (rpc->header.opcode); - - switch (opcode) { - case MONGOC_OPCODE_REPLY: - _mongoc_rpc_swab_from_le_reply (&rpc->reply); - break; - case MONGOC_OPCODE_MSG: - _mongoc_rpc_swab_from_le_msg (&rpc->msg); - break; - case MONGOC_OPCODE_UPDATE: - _mongoc_rpc_swab_from_le_update (&rpc->update); - break; - case MONGOC_OPCODE_INSERT: - _mongoc_rpc_swab_from_le_insert (&rpc->insert); - break; - case MONGOC_OPCODE_QUERY: - _mongoc_rpc_swab_from_le_query (&rpc->query); - break; - case MONGOC_OPCODE_GET_MORE: - _mongoc_rpc_swab_from_le_get_more (&rpc->get_more); - break; - case MONGOC_OPCODE_DELETE: - _mongoc_rpc_swab_from_le_delete (&rpc->delete_); - break; - case MONGOC_OPCODE_KILL_CURSORS: - _mongoc_rpc_swab_from_le_kill_cursors (&rpc->kill_cursors); - break; - case MONGOC_OPCODE_COMPRESSED: - _mongoc_rpc_swab_from_le_compressed (&rpc->compressed); - break; - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode); - break; - } -#endif -#if 0 - _mongoc_rpc_printf (rpc); -#endif -} - - -void -_mongoc_rpc_printf (mongoc_rpc_t *rpc) -{ - switch ((mongoc_opcode_t) rpc->header.opcode) { - case MONGOC_OPCODE_REPLY: - _mongoc_rpc_printf_reply (&rpc->reply); - break; - case MONGOC_OPCODE_MSG: - _mongoc_rpc_printf_msg (&rpc->msg); - break; - case MONGOC_OPCODE_UPDATE: - _mongoc_rpc_printf_update (&rpc->update); - break; - case MONGOC_OPCODE_INSERT: - _mongoc_rpc_printf_insert (&rpc->insert); - break; - case MONGOC_OPCODE_QUERY: - _mongoc_rpc_printf_query (&rpc->query); - break; - case MONGOC_OPCODE_GET_MORE: - _mongoc_rpc_printf_get_more (&rpc->get_more); - break; - case MONGOC_OPCODE_DELETE: - _mongoc_rpc_printf_delete (&rpc->delete_); - break; - case MONGOC_OPCODE_KILL_CURSORS: - _mongoc_rpc_printf_kill_cursors (&rpc->kill_cursors); - break; - case MONGOC_OPCODE_COMPRESSED: - _mongoc_rpc_printf_compressed (&rpc->compressed); - break; - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode); - break; - } - printf ("\n"); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_decompress -- - * - * Takes a (little endian) rpc struct assumed to be OP_COMPRESSED - * and decompresses the opcode into its original opcode. - * The in-place updated rpc struct remains little endian. - * - * Side effects: - * Overwrites the RPC, along with the provided buf with the - * compressed results. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen) -{ - size_t uncompressed_size = - BSON_UINT32_FROM_LE (rpc_le->compressed.uncompressed_size); - bool ok; - size_t msg_len = BSON_UINT32_TO_LE (buflen); - const size_t original_uncompressed_size = uncompressed_size; - - BSON_ASSERT (uncompressed_size <= buflen); - memcpy (buf, (void *) (&msg_len), 4); - memcpy (buf + 4, (void *) (&rpc_le->header.request_id), 4); - memcpy (buf + 8, (void *) (&rpc_le->header.response_to), 4); - memcpy (buf + 12, (void *) (&rpc_le->compressed.original_opcode), 4); - - ok = mongoc_uncompress (rpc_le->compressed.compressor_id, - rpc_le->compressed.compressed_message, - rpc_le->compressed.compressed_message_len, - buf + 16, - &uncompressed_size); - - BSON_ASSERT (original_uncompressed_size == uncompressed_size); - - if (ok) { - return _mongoc_rpc_scatter (rpc_le, buf, buflen); - } - - return false; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_compress -- - * - * Takes a (little endian) rpc struct and creates a OP_COMPRESSED - * compressed opcode based on the provided compressor_id. - * The in-place updated rpc struct remains little endian. - * - * Side effects: - * Overwrites the RPC, and clears and overwrites the cluster buffer - * with the compressed results. - * - *-------------------------------------------------------------------------- - */ - -char * -_mongoc_rpc_compress (struct _mongoc_cluster_t *cluster, - int32_t compressor_id, - mongoc_rpc_t *rpc_le, - bson_error_t *error) -{ - char *output; - size_t output_length = 0; - size_t allocate = BSON_UINT32_FROM_LE (rpc_le->header.msg_len) - 16; - char *data; - int size; - int32_t compression_level = -1; - - if (compressor_id == MONGOC_COMPRESSOR_ZLIB_ID) { - compression_level = mongoc_uri_get_option_as_int32 ( - cluster->uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, -1); - } - - BSON_ASSERT (allocate > 0); - data = bson_malloc0 (allocate); - size = _mongoc_cluster_buffer_iovec ( - cluster->iov.data, cluster->iov.len, 16, data); - BSON_ASSERT (size); - - output_length = - mongoc_compressor_max_compressed_length (compressor_id, size); - if (!output_length) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Could not determine compression bounds for %s", - mongoc_compressor_id_to_name (compressor_id)); - bson_free (data); - return NULL; - } - - output = (char *) bson_malloc0 (output_length); - if (mongoc_compress (compressor_id, - compression_level, - data, - size, - output, - &output_length)) { - rpc_le->header.msg_len = 0; - rpc_le->compressed.original_opcode = - BSON_UINT32_FROM_LE (rpc_le->header.opcode); - rpc_le->header.opcode = MONGOC_OPCODE_COMPRESSED; - rpc_le->header.request_id = - BSON_UINT32_FROM_LE (rpc_le->header.request_id); - rpc_le->header.response_to = - BSON_UINT32_FROM_LE (rpc_le->header.response_to); - - rpc_le->compressed.uncompressed_size = size; - rpc_le->compressed.compressor_id = compressor_id; - rpc_le->compressed.compressed_message = (const uint8_t *) output; - rpc_le->compressed.compressed_message_len = output_length; - bson_free (data); - - - _mongoc_array_destroy (&cluster->iov); - _mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t)); - _mongoc_rpc_gather (rpc_le, &cluster->iov); - _mongoc_rpc_swab_to_le (rpc_le); - return output; - } else { - MONGOC_WARNING ("Could not compress data with %s", - mongoc_compressor_id_to_name (compressor_id)); - } - bson_free (data); - bson_free (output); - return NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_scatter -- - * - * Takes a (little endian) rpc struct and scatters the buffer. - * Caller should check if resulting opcode is OP_COMPRESSED - * BEFORE swabbing to native endianness. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen) -{ - mongoc_opcode_t opcode; - - memset (rpc, 0, sizeof *rpc); - - if (BSON_UNLIKELY (buflen < 16)) { - return false; - } - - mongoc_counter_op_ingress_total_inc (); - if (!_mongoc_rpc_scatter_header (&rpc->header, buf, 16)) { - return false; - } - - opcode = (mongoc_opcode_t) BSON_UINT32_FROM_LE (rpc->header.opcode); - - switch (opcode) { - case MONGOC_OPCODE_COMPRESSED: - mongoc_counter_op_ingress_compressed_inc (); - return _mongoc_rpc_scatter_compressed (&rpc->compressed, buf, buflen); - - case MONGOC_OPCODE_REPLY: - mongoc_counter_op_ingress_reply_inc (); - return _mongoc_rpc_scatter_reply (&rpc->reply, buf, buflen); - - case MONGOC_OPCODE_MSG: - mongoc_counter_op_ingress_msg_inc (); - return _mongoc_rpc_scatter_msg (&rpc->msg, buf, buflen); - - - /* useless, we are never *getting* these opcodes */ - case MONGOC_OPCODE_UPDATE: - return _mongoc_rpc_scatter_update (&rpc->update, buf, buflen); - - case MONGOC_OPCODE_INSERT: - return _mongoc_rpc_scatter_insert (&rpc->insert, buf, buflen); - - case MONGOC_OPCODE_QUERY: - return _mongoc_rpc_scatter_query (&rpc->query, buf, buflen); - - case MONGOC_OPCODE_GET_MORE: - return _mongoc_rpc_scatter_get_more (&rpc->get_more, buf, buflen); - - case MONGOC_OPCODE_DELETE: - return _mongoc_rpc_scatter_delete (&rpc->delete_, buf, buflen); - - case MONGOC_OPCODE_KILL_CURSORS: - return _mongoc_rpc_scatter_kill_cursors (&rpc->kill_cursors, buf, buflen); - - default: - MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode); - return false; - } -} - - -bool -_mongoc_rpc_scatter_reply_header_only (mongoc_rpc_t *rpc, - const uint8_t *buf, - size_t buflen) -{ - if (BSON_UNLIKELY (buflen < sizeof (mongoc_rpc_reply_header_t))) { - return false; - } - mongoc_counter_op_ingress_reply_inc (); - mongoc_counter_op_ingress_total_inc (); - return _mongoc_rpc_scatter_reply_header (&rpc->reply_header, buf, buflen); -} - -bool -_mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply) -{ - if (rpc->header.opcode == MONGOC_OPCODE_REPLY && - _mongoc_rpc_reply_get_first (&rpc->reply, reply)) { - return true; - } - - return false; -} - -bool -_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson) -{ - int32_t len; - - if (!reply->documents || reply->documents_len < 4) { - return false; - } - - memcpy (&len, reply->documents, 4); - len = BSON_UINT32_FROM_LE (len); - if (reply->documents_len < len) { - return false; - } - - return bson_init_static (bson, reply->documents, len); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_prep_command -- - * - * Prepare an RPC for mongoc_cluster_run_command_rpc. @cmd_ns and - * @cmd must not be freed or modified while the RPC is in use. - * - * Side effects: - * Fills out the RPC, including pointers into @cmd_ns and @command. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_rpc_prep_command (mongoc_rpc_t *rpc, - const char *cmd_ns, - mongoc_cmd_t *cmd) - -{ - rpc->header.msg_len = 0; - rpc->header.request_id = 0; - rpc->header.response_to = 0; - rpc->header.opcode = MONGOC_OPCODE_QUERY; - rpc->query.collection = cmd_ns; - rpc->query.skip = 0; - rpc->query.n_return = -1; - rpc->query.fields = NULL; - rpc->query.query = bson_get_data (cmd->command); - - /* Find, getMore And killCursors Commands Spec: "When sending a find command - * rather than a legacy OP_QUERY find, only the slaveOk flag is honored." - * For other cursor-typed commands like aggregate, only slaveOk can be set. - * Clear bits except slaveOk; leave slaveOk set only if it is already. - */ - rpc->query.flags = cmd->query_flags & MONGOC_QUERY_SLAVE_OK; -} - - -/* returns true if an error was found. */ -static bool -_parse_error_reply (const bson_t *doc, - bool check_wce, - uint32_t *code, - const char **msg) -{ - bson_iter_t iter; - bool found_error = false; - - ENTRY; - - BSON_ASSERT (doc); - BSON_ASSERT (code); - *code = 0; - - if (bson_iter_init_find (&iter, doc, "code") && - BSON_ITER_HOLDS_INT32 (&iter)) { - *code = (uint32_t) bson_iter_int32 (&iter); - found_error = true; - } - - if (bson_iter_init_find (&iter, doc, "errmsg") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - *msg = bson_iter_utf8 (&iter, NULL); - found_error = true; - } else if (bson_iter_init_find (&iter, doc, "$err") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - *msg = bson_iter_utf8 (&iter, NULL); - found_error = true; - } - - if (found_error) { - /* there was a command error */ - RETURN (true); - } - - if (check_wce) { - /* check for a write concern error */ - if (bson_iter_init_find (&iter, doc, "writeConcernError") && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - bson_iter_t child; - BSON_ASSERT (bson_iter_recurse (&iter, &child)); - if (bson_iter_find (&child, "code") && - BSON_ITER_HOLDS_INT32 (&child)) { - *code = (uint32_t) bson_iter_int32 (&child); - found_error = true; - } - BSON_ASSERT (bson_iter_recurse (&iter, &child)); - if (bson_iter_find (&child, "errmsg") && - BSON_ITER_HOLDS_UTF8 (&child)) { - *msg = bson_iter_utf8 (&child, NULL); - found_error = true; - } - } - } - - RETURN (found_error); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cmd_check_ok -- - * - * Check if a server reply document is an error message. - * Optionally fill out a bson_error_t from the server error. - * Does *not* check for writeConcernError. - * - * Returns: - * false if @doc is an error message, true otherwise. - * - * Side effects: - * If @doc is an error reply and @error is not NULL, set its - * domain, code, and message. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_cmd_check_ok (const bson_t *doc, - int32_t error_api_version, - bson_error_t *error) -{ - mongoc_error_domain_t domain = - error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER - : MONGOC_ERROR_QUERY; - uint32_t code; - bson_iter_t iter; - const char *msg = "Unknown command error"; - - ENTRY; - - BSON_ASSERT (doc); - - if (bson_iter_init_find (&iter, doc, "ok") && bson_iter_as_bool (&iter)) { - /* no error */ - RETURN (true); - } - - if (!_parse_error_reply (doc, false /* check_wce */, &code, &msg)) { - RETURN (true); - } - - if (code == MONGOC_ERROR_PROTOCOL_ERROR || code == 13390) { - code = MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND; - } else if (code == 0) { - code = MONGOC_ERROR_QUERY_FAILURE; - } - - bson_set_error (error, domain, code, "%s", msg); - - /* there was a command error */ - RETURN (false); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_cmd_check_ok_no_wce -- - * - * Check if a server reply document is an error message. - * Optionally fill out a bson_error_t from the server error. - * If the response contains a writeConcernError, this is considered - * an error and returns false. - * - * Returns: - * false if @doc is an error message, true otherwise. - * - * Side effects: - * If @doc is an error reply and @error is not NULL, set its - * domain, code, and message. - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_cmd_check_ok_no_wce (const bson_t *doc, - int32_t error_api_version, - bson_error_t *error) -{ - mongoc_error_domain_t domain = - error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER - : MONGOC_ERROR_QUERY; - uint32_t code; - const char *msg = "Unknown command error"; - - ENTRY; - - BSON_ASSERT (doc); - - if (!_parse_error_reply (doc, true /* check_wce */, &code, &msg)) { - RETURN (true); - } - - if (code == MONGOC_ERROR_PROTOCOL_ERROR || code == 13390) { - code = MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND; - } else if (code == 0) { - code = MONGOC_ERROR_QUERY_FAILURE; - } - - bson_set_error (error, domain, code, "%s", msg); - - /* there was a command error */ - RETURN (false); -} - - -/* helper function to parse error reply document to an OP_QUERY */ -static void -_mongoc_populate_query_error (const bson_t *doc, - int32_t error_api_version, - bson_error_t *error) -{ - mongoc_error_domain_t domain = - error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER - : MONGOC_ERROR_QUERY; - uint32_t code = MONGOC_ERROR_QUERY_FAILURE; - bson_iter_t iter; - const char *msg = "Unknown query failure"; - - ENTRY; - - BSON_ASSERT (doc); - - if (bson_iter_init_find (&iter, doc, "code") && - BSON_ITER_HOLDS_INT32 (&iter)) { - code = (uint32_t) bson_iter_int32 (&iter); - } - - if (bson_iter_init_find (&iter, doc, "$err") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - msg = bson_iter_utf8 (&iter, NULL); - } - - bson_set_error (error, domain, code, "%s", msg); - - EXIT; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_rpc_check_ok -- - * - * Check if a server OP_REPLY is an error message. - * Optionally fill out a bson_error_t from the server error. - * @error_document must be an initialized bson_t or NULL. - * Does *not* check for writeConcernError. - * - * Returns: - * false if the reply is an error message, true otherwise. - * - * Side effects: - * If rpc is an error reply and @error is not NULL, set its - * domain, code, and message. - * - * If rpc is an error reply and @error_document is not NULL, - * it is reinitialized with the server reply. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_rpc_check_ok (mongoc_rpc_t *rpc, - int32_t error_api_version, - bson_error_t *error /* OUT */, - bson_t *error_doc /* OUT */) -{ - bson_t b; - - ENTRY; - - BSON_ASSERT (rpc); - - if (rpc->header.opcode != MONGOC_OPCODE_REPLY) { - bson_set_error (error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_INVALID_REPLY, - "Received rpc other than OP_REPLY."); - RETURN (false); - } - - if (rpc->reply.flags & MONGOC_REPLY_QUERY_FAILURE) { - if (_mongoc_rpc_get_first_document (rpc, &b)) { - _mongoc_populate_query_error (&b, error_api_version, error); - - if (error_doc) { - bson_destroy (error_doc); - bson_copy_to (&b, error_doc); - } - - bson_destroy (&b); - } else { - bson_set_error (error, - MONGOC_ERROR_QUERY, - MONGOC_ERROR_QUERY_FAILURE, - "Unknown query failure."); - } - - RETURN (false); - } else if (rpc->reply.flags & MONGOC_REPLY_CURSOR_NOT_FOUND) { - bson_set_error (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "The cursor is invalid or has expired."); - - RETURN (false); - } - - - RETURN (true); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-sasl-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-sasl-private.h deleted file mode 100644 index 2e820fa9e0fd7400cdc79bc54ae5714690a51bc0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-sasl-private.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SASL_PRIVATE_H -#define MONGOC_SASL_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-uri.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-stream-socket.h" - -BSON_BEGIN_DECLS - - -typedef struct { - char *user; - char *pass; - char *service_name; - char *service_host; - bool canonicalize_host_name; - char *mechanism; -} mongoc_sasl_t; - - -void -_mongoc_sasl_set_pass (mongoc_sasl_t *sasl, const char *pass); -void -_mongoc_sasl_set_user (mongoc_sasl_t *sasl, const char *user); -void -_mongoc_sasl_set_service_name (mongoc_sasl_t *sasl, const char *service_name); -void -_mongoc_sasl_set_service_host (mongoc_sasl_t *sasl, const char *service_host); -void -_mongoc_sasl_set_properties (mongoc_sasl_t *sasl, const mongoc_uri_t *uri); -bool -_mongoc_sasl_get_canonicalized_name (mongoc_stream_t *node_stream, /* IN */ - char *name, /* OUT */ - size_t namelen); /* IN */ - -BSON_END_DECLS - - -#endif /* MONGOC_SASL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-sasl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-sasl.c deleted file mode 100644 index 44d3c4daf41d52e6fc9ee85d52e45cc38ad74f17..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-sasl.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SASL -#include "mongoc/mongoc-sasl-private.h" -#include "mongoc/mongoc-util-private.h" - -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-change-stream-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "SASL" - -void -_mongoc_sasl_set_user (mongoc_sasl_t *sasl, const char *user) -{ - BSON_ASSERT (sasl); - - bson_free (sasl->user); - sasl->user = user ? bson_strdup (user) : NULL; -} - - -void -_mongoc_sasl_set_pass (mongoc_sasl_t *sasl, const char *pass) -{ - BSON_ASSERT (sasl); - - bson_free (sasl->pass); - sasl->pass = pass ? bson_strdup (pass) : NULL; -} - - -void -_mongoc_sasl_set_service_host (mongoc_sasl_t *sasl, const char *service_host) -{ - BSON_ASSERT (sasl); - - bson_free (sasl->service_host); - sasl->service_host = service_host ? bson_strdup (service_host) : NULL; -} - - -void -_mongoc_sasl_set_service_name (mongoc_sasl_t *sasl, const char *service_name) -{ - BSON_ASSERT (sasl); - - bson_free (sasl->service_name); - sasl->service_name = service_name ? bson_strdup (service_name) : NULL; -} - - -void -_mongoc_sasl_set_properties (mongoc_sasl_t *sasl, const mongoc_uri_t *uri) -{ - const bson_t *options; - bson_iter_t iter; - bson_t properties; - const char *service_name = NULL; - bool canonicalize = false; - - _mongoc_sasl_set_pass(sasl, mongoc_uri_get_password(uri)); - _mongoc_sasl_set_user(sasl, mongoc_uri_get_username(uri)); - - options = mongoc_uri_get_options (uri); - - if (!mongoc_uri_get_mechanism_properties (uri, &properties)) { - bson_init (&properties); - } - - if (bson_iter_init_find_case ( - &iter, options, MONGOC_URI_GSSAPISERVICENAME) && - BSON_ITER_HOLDS_UTF8 (&iter)) { - service_name = bson_iter_utf8 (&iter, NULL); - } - - if (bson_iter_init_find_case (&iter, &properties, "SERVICE_NAME") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - /* newer "authMechanismProperties" URI syntax takes precedence */ - service_name = bson_iter_utf8 (&iter, NULL); - } - - _mongoc_sasl_set_service_name (sasl, service_name); - - /* - * Driver Authentication Spec: "Drivers MAY allow the user to request - * canonicalization of the hostname. This might be required when the hosts - * report different hostnames than what is used in the kerberos database. - * The default is "false". - * - * Some underlying GSSAPI layers will do this for us, but can be disabled in - * their config (krb.conf). - * - * See CDRIVER-323 for more information. - */ - if (bson_iter_init_find_case ( - &iter, options, MONGOC_URI_CANONICALIZEHOSTNAME) && - BSON_ITER_HOLDS_BOOL (&iter)) { - canonicalize = bson_iter_bool (&iter); - } - - if (bson_iter_init_find_case ( - &iter, &properties, "CANONICALIZE_HOST_NAME") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - /* newer "authMechanismProperties" URI syntax takes precedence */ - canonicalize = !strcasecmp (bson_iter_utf8 (&iter, NULL), "true"); - } - - sasl->canonicalize_host_name = canonicalize; - - bson_destroy (&properties); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_sasl_get_canonicalized_name -- - * - * Query the node to get the canonicalized name. This may happen if - * the node has been accessed via an alias. - * - * The gssapi code will use this if canonicalizeHostname is true. - * - * Some underlying layers of krb might do this for us, but they can - * be disabled in krb.conf. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_sasl_get_canonicalized_name (mongoc_stream_t *node_stream, /* IN */ - char *name, /* OUT */ - size_t namelen) /* OUT */ -{ - mongoc_stream_t *stream; - mongoc_socket_t *sock = NULL; - char *canonicalized; - - ENTRY; - - BSON_ASSERT (node_stream); - BSON_ASSERT (name); - - stream = mongoc_stream_get_root_stream (node_stream); - BSON_ASSERT (stream); - - if (stream->type == MONGOC_STREAM_SOCKET) { - sock = - mongoc_stream_socket_get_socket ((mongoc_stream_socket_t *) stream); - if (sock) { - canonicalized = mongoc_socket_getnameinfo (sock); - if (canonicalized) { - bson_snprintf (name, namelen, "%s", canonicalized); - bson_free (canonicalized); - RETURN (true); - } - } - } - - RETURN (false); -} -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-scram-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-scram-private.h deleted file mode 100644 index fd87a49fe7bcda7eaddb41650c1ad09370268946..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-scram-private.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_SCRAM_PRIVATE_H -#define MONGOC_SCRAM_PRIVATE_H - - -#include <bson/bson.h> -#include "mongoc/mongoc-crypto-private.h" - - -BSON_BEGIN_DECLS - -#define MONGOC_SCRAM_SHA_1_HASH_SIZE 20 -#define MONGOC_SCRAM_SHA_256_HASH_SIZE 32 -/* SCRAM-SHA-1 uses a hash size of 20, and SCRAM-SHA-256 uses a hash size - * of 32. Stack allocations should be large enough for either. */ -#define MONGOC_SCRAM_HASH_MAX_SIZE MONGOC_SCRAM_SHA_256_HASH_SIZE - -#define MONGOC_SCRAM_B64_ENCODED_SIZE(n) (2 * n) - -#define MONGOC_SCRAM_B64_HASH_MAX_SIZE \ - MONGOC_SCRAM_B64_ENCODED_SIZE (MONGOC_SCRAM_HASH_MAX_SIZE) - -typedef struct _mongoc_scram_cache_t { - /* pre-secrets */ - char *hashed_password; - uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE]; - uint32_t iterations; - /* secrets */ - uint8_t client_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - uint8_t server_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - uint8_t salted_password[MONGOC_SCRAM_HASH_MAX_SIZE]; -} mongoc_scram_cache_t; - -typedef struct _mongoc_scram_t { - bool done; - int step; - char *user; - char *pass; - char *hashed_password; - uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE]; - uint32_t iterations; - uint8_t client_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - uint8_t server_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - uint8_t salted_password[MONGOC_SCRAM_HASH_MAX_SIZE]; - char encoded_nonce[48]; - int32_t encoded_nonce_len; - uint8_t *auth_message; - uint32_t auth_messagemax; - uint32_t auth_messagelen; -#ifdef MONGOC_ENABLE_CRYPTO - mongoc_crypto_t crypto; -#endif - mongoc_scram_cache_t *cache; -} mongoc_scram_t; - -#ifdef MONGOC_ENABLE_CRYPTO -void -_mongoc_scram_init (mongoc_scram_t *scram, mongoc_crypto_hash_algorithm_t algo); -#endif - -mongoc_scram_cache_t * -_mongoc_scram_get_cache (mongoc_scram_t *scram); - -void -_mongoc_scram_set_cache (mongoc_scram_t *scram, mongoc_scram_cache_t *cache); - -void -_mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass); - -void -_mongoc_scram_set_user (mongoc_scram_t *scram, const char *user); - -void -_mongoc_scram_set_server_key (mongoc_scram_t *scram, - const uint8_t *server_key, - size_t len); - -void -_mongoc_scram_set_salted_password (mongoc_scram_t *scram, - const uint8_t *salted_password, - size_t len); - -void -_mongoc_scram_destroy (mongoc_scram_t *scram); - -bool -_mongoc_scram_step (mongoc_scram_t *scram, - const uint8_t *inbuf, - uint32_t inbuflen, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen, - bson_error_t *error); - -void -_mongoc_scram_cache_destroy (mongoc_scram_cache_t *cache); - -/* returns false if this string does not need SASLPrep. It returns true - * conservatively, if str might need to be SASLPrep'ed. */ -bool -_mongoc_sasl_prep_required (const char *str); - -/* returns the output of SASLPrep as a new string which must be freed. Returns - * null on error and sets err. - * `name` should be "username" or "password". */ -char * -_mongoc_sasl_prep (const char *in_utf8, int in_utf8_len, bson_error_t *err); - -BSON_END_DECLS - - -#endif /* MONGOC_SCRAM_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-scram.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-scram.c deleted file mode 100644 index 0d47cce8bd4b2c48c3f658eba6ce3d50e1e5baa7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-scram.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* Copyright 2014 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_CRYPTO - -#include <string.h> - -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-scram-private.h" -#include "mongoc/mongoc-rand-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-trace-private.h" - -#include "mongoc/mongoc-crypto-private.h" -#include "common-b64-private.h" - -#include "mongoc/mongoc-memcmp-private.h" - -#define MONGOC_SCRAM_SERVER_KEY "Server Key" -#define MONGOC_SCRAM_CLIENT_KEY "Client Key" - -static int -_scram_hash_size (mongoc_scram_t *scram) -{ - if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_1) { - return MONGOC_SCRAM_SHA_1_HASH_SIZE; - } else if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_256) { - return MONGOC_SCRAM_SHA_256_HASH_SIZE; - } - return 0; -} - -/* Copies the cache's secrets to scram */ -static void -_mongoc_scram_cache_apply_secrets (mongoc_scram_cache_t *cache, - mongoc_scram_t *scram) -{ - BSON_ASSERT (cache); - BSON_ASSERT (scram); - - memcpy (scram->client_key, cache->client_key, sizeof (scram->client_key)); - memcpy (scram->server_key, cache->server_key, sizeof (scram->server_key)); - memcpy (scram->salted_password, - cache->salted_password, - sizeof (scram->salted_password)); -} - - -static mongoc_scram_cache_t * -_mongoc_scram_cache_copy (const mongoc_scram_cache_t *cache) -{ - mongoc_scram_cache_t *ret = NULL; - - if (cache) { - ret = (mongoc_scram_cache_t *) bson_malloc0 (sizeof (*ret)); - ret->hashed_password = bson_strdup (cache->hashed_password); - memcpy ( - ret->decoded_salt, cache->decoded_salt, sizeof (ret->decoded_salt)); - ret->iterations = cache->iterations; - memcpy (ret->client_key, cache->client_key, sizeof (ret->client_key)); - memcpy (ret->server_key, cache->server_key, sizeof (ret->server_key)); - memcpy (ret->salted_password, - cache->salted_password, - sizeof (ret->salted_password)); - } - - return ret; -} - -#ifdef MONGOC_ENABLE_ICU -#include <unicode/usprep.h> -#include <unicode/ustring.h> -#endif - - -void -_mongoc_scram_cache_destroy (mongoc_scram_cache_t *cache) -{ - BSON_ASSERT (cache); - - if (cache->hashed_password) { - bson_zero_free (cache->hashed_password, strlen (cache->hashed_password)); - } - - bson_free (cache); -} - - -/* Checks whether the cache contains scram's pre-secrets */ -static bool -_mongoc_scram_cache_has_presecrets (mongoc_scram_cache_t *cache, - mongoc_scram_t *scram) -{ - BSON_ASSERT (cache); - BSON_ASSERT (scram); - - return cache->hashed_password && scram->hashed_password && - !strcmp (cache->hashed_password, scram->hashed_password) && - cache->iterations == scram->iterations && - !memcmp (cache->decoded_salt, - scram->decoded_salt, - sizeof (cache->decoded_salt)); -} - - -mongoc_scram_cache_t * -_mongoc_scram_get_cache (mongoc_scram_t *scram) -{ - BSON_ASSERT (scram); - - return _mongoc_scram_cache_copy (scram->cache); -} - - -void -_mongoc_scram_set_cache (mongoc_scram_t *scram, mongoc_scram_cache_t *cache) -{ - BSON_ASSERT (scram); - - if (scram->cache) { - _mongoc_scram_cache_destroy (scram->cache); - } - - scram->cache = _mongoc_scram_cache_copy (cache); -} - - -void -_mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass) -{ - BSON_ASSERT (scram); - - if (scram->pass) { - bson_zero_free (scram->pass, strlen (scram->pass)); - } - - scram->pass = pass ? bson_strdup (pass) : NULL; -} - - -void -_mongoc_scram_set_user (mongoc_scram_t *scram, const char *user) -{ - BSON_ASSERT (scram); - - bson_free (scram->user); - scram->user = user ? bson_strdup (user) : NULL; -} - - -void -_mongoc_scram_init (mongoc_scram_t *scram, mongoc_crypto_hash_algorithm_t algo) -{ - BSON_ASSERT (scram); - - memset (scram, 0, sizeof *scram); - - mongoc_crypto_init (&scram->crypto, algo); -} - - -void -_mongoc_scram_destroy (mongoc_scram_t *scram) -{ - BSON_ASSERT (scram); - - bson_free (scram->user); - - if (scram->pass) { - bson_zero_free (scram->pass, strlen (scram->pass)); - } - - if (scram->hashed_password) { - bson_zero_free (scram->hashed_password, strlen (scram->hashed_password)); - } - - bson_free (scram->auth_message); - - if (scram->cache) { - _mongoc_scram_cache_destroy (scram->cache); - } -} - - -/* Updates the cache with scram's last-used pre-secrets and secrets */ -static void -_mongoc_scram_update_cache (mongoc_scram_t *scram) -{ - mongoc_scram_cache_t *cache; - - BSON_ASSERT (scram); - - if (scram->cache) { - _mongoc_scram_cache_destroy (scram->cache); - } - - cache = (mongoc_scram_cache_t *) bson_malloc0 (sizeof (*cache)); - cache->hashed_password = bson_strdup (scram->hashed_password); - memcpy ( - cache->decoded_salt, scram->decoded_salt, sizeof (cache->decoded_salt)); - cache->iterations = scram->iterations; - memcpy (cache->client_key, scram->client_key, sizeof (cache->client_key)); - memcpy (cache->server_key, scram->server_key, sizeof (cache->server_key)); - memcpy (cache->salted_password, - scram->salted_password, - sizeof (cache->salted_password)); - - scram->cache = cache; -} - - -static bool -_mongoc_scram_buf_write (const char *src, - int32_t src_len, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen) -{ - if (src_len < 0) { - src_len = (int32_t) strlen (src); - } - - if (*outbuflen + src_len >= outbufmax) { - return false; - } - - memcpy (outbuf + *outbuflen, src, src_len); - - *outbuflen += src_len; - - return true; -} - - -/* generate client-first-message: - * n,a=authzid,n=encoded-username,r=client-nonce - * - * note that a= is optional, so we aren't dealing with that here - */ -static bool -_mongoc_scram_start (mongoc_scram_t *scram, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen, - bson_error_t *error) -{ - uint8_t nonce[24]; - const char *ptr; - bool rval = true; - - BSON_ASSERT (scram); - BSON_ASSERT (outbuf); - BSON_ASSERT (outbufmax); - BSON_ASSERT (outbuflen); - - if (!scram->user) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: username is not set"); - goto FAIL; - } - - /* auth message is as big as the outbuf just because */ - scram->auth_message = (uint8_t *) bson_malloc (outbufmax); - scram->auth_messagemax = outbufmax; - - /* the server uses a 24 byte random nonce. so we do as well */ - if (1 != _mongoc_rand_bytes (nonce, sizeof (nonce))) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: could not generate a cryptographically " - "secure nonce in sasl step 1"); - goto FAIL; - } - - scram->encoded_nonce_len = bson_b64_ntop (nonce, - sizeof (nonce), - scram->encoded_nonce, - sizeof (scram->encoded_nonce)); - - if (-1 == scram->encoded_nonce_len) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: could not encode nonce"); - goto FAIL; - } - - if (!_mongoc_scram_buf_write ("n,,n=", -1, outbuf, outbufmax, outbuflen)) { - goto BUFFER; - } - - for (ptr = scram->user; *ptr; ptr++) { - /* RFC 5802 specifies that ',' and '=' and encoded as '=2C' and '=3D' - * respectively in the user name */ - switch (*ptr) { - case ',': - - if (!_mongoc_scram_buf_write ( - "=2C", -1, outbuf, outbufmax, outbuflen)) { - goto BUFFER; - } - - break; - case '=': - - if (!_mongoc_scram_buf_write ( - "=3D", -1, outbuf, outbufmax, outbuflen)) { - goto BUFFER; - } - - break; - default: - - if (!_mongoc_scram_buf_write (ptr, 1, outbuf, outbufmax, outbuflen)) { - goto BUFFER; - } - - break; - } - } - - if (!_mongoc_scram_buf_write (",r=", -1, outbuf, outbufmax, outbuflen)) { - goto BUFFER; - } - - if (!_mongoc_scram_buf_write (scram->encoded_nonce, - scram->encoded_nonce_len, - outbuf, - outbufmax, - outbuflen)) { - goto BUFFER; - } - - /* we have to keep track of the conversation to create a client proof later - * on. This copies the message we're crafting from the 'n=' portion onwards - * into a buffer we're managing */ - if (!_mongoc_scram_buf_write ((char *) outbuf + 3, - *outbuflen - 3, - scram->auth_message, - scram->auth_messagemax, - &scram->auth_messagelen)) { - goto BUFFER_AUTH; - } - - if (!_mongoc_scram_buf_write (",", - -1, - scram->auth_message, - scram->auth_messagemax, - &scram->auth_messagelen)) { - goto BUFFER_AUTH; - } - - goto CLEANUP; - -BUFFER_AUTH: - bson_set_error ( - error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: could not buffer auth message in sasl step1"); - - goto FAIL; - -BUFFER: - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: could not buffer sasl step1"); - - goto FAIL; - -FAIL: - rval = false; - -CLEANUP: - - return rval; -} - - -/* Compute the SCRAM step Hi() as defined in RFC5802 */ -static void -_mongoc_scram_salt_password (mongoc_scram_t *scram, - const char *password, - uint32_t password_len, - const uint8_t *salt, - uint32_t salt_len, - uint32_t iterations) -{ - uint8_t intermediate_digest[MONGOC_SCRAM_HASH_MAX_SIZE]; - uint8_t start_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - - int i; - int k; - uint8_t *output = scram->salted_password; - - memcpy (start_key, salt, salt_len); - - start_key[salt_len] = 0; - start_key[salt_len + 1] = 0; - start_key[salt_len + 2] = 0; - start_key[salt_len + 3] = 1; - - mongoc_crypto_hmac (&scram->crypto, - password, - password_len, - start_key, - _scram_hash_size (scram), - output); - - memcpy (intermediate_digest, output, _scram_hash_size (scram)); - - /* intermediateDigest contains Ui and output contains the accumulated XOR:ed - * result */ - for (i = 2; i <= iterations; i++) { - mongoc_crypto_hmac (&scram->crypto, - password, - password_len, - intermediate_digest, - _scram_hash_size (scram), - intermediate_digest); - - for (k = 0; k < _scram_hash_size (scram); k++) { - output[k] ^= intermediate_digest[k]; - } - } -} - - -static bool -_mongoc_scram_generate_client_proof (mongoc_scram_t *scram, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen) -{ - uint8_t stored_key[MONGOC_SCRAM_HASH_MAX_SIZE]; - uint8_t client_signature[MONGOC_SCRAM_HASH_MAX_SIZE]; - unsigned char client_proof[MONGOC_SCRAM_HASH_MAX_SIZE]; - int i; - int r = 0; - - if (!*scram->client_key) { - /* ClientKey := HMAC(saltedPassword, "Client Key") */ - mongoc_crypto_hmac (&scram->crypto, - scram->salted_password, - _scram_hash_size (scram), - (uint8_t *) MONGOC_SCRAM_CLIENT_KEY, - (int) strlen (MONGOC_SCRAM_CLIENT_KEY), - scram->client_key); - } - - /* StoredKey := H(client_key) */ - mongoc_crypto_hash (&scram->crypto, - scram->client_key, - (size_t) _scram_hash_size (scram), - stored_key); - - /* ClientSignature := HMAC(StoredKey, AuthMessage) */ - mongoc_crypto_hmac (&scram->crypto, - stored_key, - _scram_hash_size (scram), - scram->auth_message, - scram->auth_messagelen, - client_signature); - - /* ClientProof := ClientKey XOR ClientSignature */ - - for (i = 0; i < _scram_hash_size (scram); i++) { - client_proof[i] = scram->client_key[i] ^ client_signature[i]; - } - - r = bson_b64_ntop (client_proof, - _scram_hash_size (scram), - (char *) outbuf + *outbuflen, - outbufmax - *outbuflen); - - if (-1 == r) { - return false; - } - - *outbuflen += r; - - return true; -} - - -/* Parse server-first-message of the form: - * r=client-nonce|server-nonce,s=user-salt,i=iteration-count - * - * Generate client-final-message of the form: - * c=channel-binding(base64),r=client-nonce|server-nonce,p=client-proof - */ -static bool -_mongoc_scram_step2 (mongoc_scram_t *scram, - const uint8_t *inbuf, - uint32_t inbuflen, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen, - bson_error_t *error) -{ - uint8_t *val_r = NULL; - uint32_t val_r_len; - uint8_t *val_s = NULL; - uint32_t val_s_len; - uint8_t *val_i = NULL; - uint32_t val_i_len; - - uint8_t **current_val; - uint32_t *current_val_len; - - const uint8_t *ptr; - const uint8_t *next_comma; - - char *tmp; - char *hashed_password; - - uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE] = {0}; - int32_t decoded_salt_len; - /* the decoded salt leaves four trailing bytes to add the int32 0x00000001 */ - const int32_t expected_salt_length = _scram_hash_size (scram) - 4; - bool rval = true; - - int iterations; - - - BSON_ASSERT (scram); - BSON_ASSERT (outbuf); - BSON_ASSERT (outbufmax); - BSON_ASSERT (outbuflen); - - if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_1) { - /* Auth spec for SCRAM-SHA-1: "The password variable MUST be the mongodb - * hashed variant. The mongo hashed variant is computed as hash = HEX( - * MD5( UTF8( username + ':mongo:' + plain_text_password )))" */ - tmp = bson_strdup_printf ("%s:mongo:%s", scram->user, scram->pass); - hashed_password = _mongoc_hex_md5 (tmp); - bson_zero_free (tmp, strlen (tmp)); - } else if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_256) { - /* Auth spec for SCRAM-SHA-256: "Passwords MUST be prepared with SASLprep, - * per RFC 5802. Passwords are used directly for key derivation; they - * MUST NOT be digested as they are in SCRAM-SHA-1." */ - hashed_password = - _mongoc_sasl_prep (scram->pass, (int) strlen (scram->pass), error); - if (!hashed_password) { - goto FAIL; - } - } else { - BSON_ASSERT (false); - } - - /* we need all of the incoming message for the final client proof */ - if (!_mongoc_scram_buf_write ((char *) inbuf, - inbuflen, - scram->auth_message, - scram->auth_messagemax, - &scram->auth_messagelen)) { - goto BUFFER_AUTH; - } - - if (!_mongoc_scram_buf_write (",", - -1, - scram->auth_message, - scram->auth_messagemax, - &scram->auth_messagelen)) { - goto BUFFER_AUTH; - } - - for (ptr = inbuf; ptr < inbuf + inbuflen;) { - switch (*ptr) { - case 'r': - current_val = &val_r; - current_val_len = &val_r_len; - break; - case 's': - current_val = &val_s; - current_val_len = &val_s_len; - break; - case 'i': - current_val = &val_i; - current_val_len = &val_i_len; - break; - default: - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: unknown key (%c) in sasl step 2", - *ptr); - goto FAIL; - } - - ptr++; - - if (*ptr != '=') { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: invalid parse state in sasl step 2"); - - goto FAIL; - } - - ptr++; - - next_comma = - (const uint8_t *) memchr (ptr, ',', (inbuf + inbuflen) - ptr); - - if (next_comma) { - *current_val_len = (uint32_t) (next_comma - ptr); - } else { - *current_val_len = (uint32_t) ((inbuf + inbuflen) - ptr); - } - - *current_val = (uint8_t *) bson_malloc (*current_val_len + 1); - memcpy (*current_val, ptr, *current_val_len); - (*current_val)[*current_val_len] = '\0'; - - if (next_comma) { - ptr = next_comma + 1; - } else { - break; - } - } - - if (!val_r) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: no r param in sasl step 2"); - - goto FAIL; - } - - if (!val_s) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: no s param in sasl step 2"); - - goto FAIL; - } - - if (!val_i) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: no i param in sasl step 2"); - - goto FAIL; - } - - /* verify our nonce */ - if (val_r_len < scram->encoded_nonce_len || - mongoc_memcmp (val_r, scram->encoded_nonce, scram->encoded_nonce_len)) { - bson_set_error ( - error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: client nonce not repeated in sasl step 2"); - } - - *outbuflen = 0; - - if (!_mongoc_scram_buf_write ( - "c=biws,r=", -1, outbuf, outbufmax, outbuflen)) { - goto BUFFER; - } - - if (!_mongoc_scram_buf_write ( - (char *) val_r, val_r_len, outbuf, outbufmax, outbuflen)) { - goto BUFFER; - } - - if (!_mongoc_scram_buf_write ((char *) outbuf, - *outbuflen, - scram->auth_message, - scram->auth_messagemax, - &scram->auth_messagelen)) { - goto BUFFER_AUTH; - } - - if (!_mongoc_scram_buf_write (",p=", -1, outbuf, outbufmax, outbuflen)) { - goto BUFFER; - } - - decoded_salt_len = - bson_b64_pton ((char *) val_s, decoded_salt, sizeof (decoded_salt)); - - if (-1 == decoded_salt_len) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: unable to decode salt in sasl step2"); - goto FAIL; - } - - if (expected_salt_length != decoded_salt_len) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: invalid salt length of %d in sasl step2", - decoded_salt_len); - goto FAIL; - } - - iterations = (int) bson_ascii_strtoll ((char *) val_i, &tmp, 10); - /* tmp holds the location of the failed to parse character. So if it's - * null, we got to the end of the string and didn't have a parse error */ - - if (*tmp) { - bson_set_error ( - error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: unable to parse iterations in sasl step2"); - goto FAIL; - } - - if (iterations < 0) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: iterations is negative in sasl step2"); - goto FAIL; - } - - /* drivers MUST enforce a minimum iteration count of 4096 and MUST error if - * the authentication conversation specifies a lower count. This mitigates - * downgrade attacks by a man-in-the-middle attacker. */ - if (iterations < 4096) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: iterations must be at least 4096"); - goto FAIL; - } - - /* Save the presecrets for caching */ - scram->hashed_password = bson_strdup (hashed_password); - scram->iterations = iterations; - memcpy (scram->decoded_salt, decoded_salt, sizeof (scram->decoded_salt)); - - if (scram->cache && - _mongoc_scram_cache_has_presecrets (scram->cache, scram)) { - _mongoc_scram_cache_apply_secrets (scram->cache, scram); - } - - if (!*scram->salted_password) { - _mongoc_scram_salt_password (scram, - hashed_password, - (uint32_t) strlen (hashed_password), - decoded_salt, - decoded_salt_len, - (uint32_t) iterations); - } - - _mongoc_scram_generate_client_proof (scram, outbuf, outbufmax, outbuflen); - - goto CLEANUP; - -BUFFER_AUTH: - bson_set_error ( - error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: could not buffer auth message in sasl step2"); - - goto FAIL; - -BUFFER: - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: could not buffer sasl step2"); - - goto FAIL; - -FAIL: - rval = false; - -CLEANUP: - bson_free (val_r); - bson_free (val_s); - bson_free (val_i); - - if (hashed_password) { - bson_zero_free (hashed_password, strlen (hashed_password)); - } - - return rval; -} - - -static bool -_mongoc_scram_verify_server_signature (mongoc_scram_t *scram, - uint8_t *verification, - uint32_t len) -{ - char encoded_server_signature[MONGOC_SCRAM_B64_HASH_MAX_SIZE]; - int32_t encoded_server_signature_len; - uint8_t server_signature[MONGOC_SCRAM_HASH_MAX_SIZE]; - - if (!*scram->server_key) { - /* ServerKey := HMAC(SaltedPassword, "Server Key") */ - mongoc_crypto_hmac (&scram->crypto, - scram->salted_password, - _scram_hash_size (scram), - (uint8_t *) MONGOC_SCRAM_SERVER_KEY, - strlen (MONGOC_SCRAM_SERVER_KEY), - scram->server_key); - } - - /* ServerSignature := HMAC(ServerKey, AuthMessage) */ - mongoc_crypto_hmac (&scram->crypto, - scram->server_key, - _scram_hash_size (scram), - scram->auth_message, - scram->auth_messagelen, - server_signature); - - encoded_server_signature_len = - bson_b64_ntop (server_signature, - _scram_hash_size (scram), - encoded_server_signature, - sizeof (encoded_server_signature)); - if (encoded_server_signature_len == -1) { - return false; - } - - return (len == encoded_server_signature_len) && - (mongoc_memcmp (verification, encoded_server_signature, len) == 0); -} - - -static bool -_mongoc_scram_step3 (mongoc_scram_t *scram, - const uint8_t *inbuf, - uint32_t inbuflen, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen, - bson_error_t *error) -{ - uint8_t *val_e = NULL; - uint32_t val_e_len; - uint8_t *val_v = NULL; - uint32_t val_v_len; - - uint8_t **current_val; - uint32_t *current_val_len; - - const uint8_t *ptr; - const uint8_t *next_comma; - - bool rval = true; - - BSON_ASSERT (scram); - BSON_ASSERT (outbuf); - BSON_ASSERT (outbufmax); - BSON_ASSERT (outbuflen); - - for (ptr = inbuf; ptr < inbuf + inbuflen;) { - switch (*ptr) { - case 'e': - current_val = &val_e; - current_val_len = &val_e_len; - break; - case 'v': - current_val = &val_v; - current_val_len = &val_v_len; - break; - default: - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: unknown key (%c) in sasl step 3", - *ptr); - goto FAIL; - } - - ptr++; - - if (*ptr != '=') { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: invalid parse state in sasl step 3"); - goto FAIL; - } - - ptr++; - - next_comma = - (const uint8_t *) memchr (ptr, ',', (inbuf + inbuflen) - ptr); - - if (next_comma) { - *current_val_len = (uint32_t) (next_comma - ptr); - } else { - *current_val_len = (uint32_t) ((inbuf + inbuflen) - ptr); - } - - *current_val = (uint8_t *) bson_malloc (*current_val_len + 1); - memcpy (*current_val, ptr, *current_val_len); - (*current_val)[*current_val_len] = '\0'; - - if (next_comma) { - ptr = next_comma + 1; - } else { - break; - } - } - - *outbuflen = 0; - - if (val_e) { - bson_set_error ( - error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: authentication failure in sasl step 3 : %s", - val_e); - goto FAIL; - } - - if (!val_v) { - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: no v param in sasl step 3"); - goto FAIL; - } - - if (!_mongoc_scram_verify_server_signature (scram, val_v, val_v_len)) { - bson_set_error ( - error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: could not verify server signature in sasl step 3"); - goto FAIL; - } - - /* Update the cache if authentication succeeds */ - _mongoc_scram_update_cache (scram); - - goto CLEANUP; - -FAIL: - rval = false; - -CLEANUP: - bson_free (val_e); - bson_free (val_v); - - return rval; -} - - -bool -_mongoc_scram_step (mongoc_scram_t *scram, - const uint8_t *inbuf, - uint32_t inbuflen, - uint8_t *outbuf, - uint32_t outbufmax, - uint32_t *outbuflen, - bson_error_t *error) -{ - BSON_ASSERT (scram); - BSON_ASSERT (inbuf); - BSON_ASSERT (outbuf); - BSON_ASSERT (outbuflen); - - scram->step++; - - switch (scram->step) { - case 1: - return _mongoc_scram_start (scram, outbuf, outbufmax, outbuflen, error); - case 2: - return _mongoc_scram_step2 ( - scram, inbuf, inbuflen, outbuf, outbufmax, outbuflen, error); - case 3: - return _mongoc_scram_step3 ( - scram, inbuf, inbuflen, outbuf, outbufmax, outbuflen, error); - default: - bson_set_error (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_NOT_DONE, - "SCRAM Failure: maximum steps detected"); - return false; - } -} - -bool -_mongoc_sasl_prep_required (const char *str) -{ - unsigned char c; - while (*str) { - c = (unsigned char) *str; - /* characters below 32 contain all of the control characters. - * characters above 127 are multibyte UTF-8 characters. - * character 127 is the DEL character. */ - if (c < 32 || c >= 127) { - return true; - } - str++; - } - return false; -} - -#ifdef MONGOC_ENABLE_ICU -char * -_mongoc_sasl_prep_impl (const char *name, - const char *in_utf8, - int in_utf8_len, - bson_error_t *err) -{ - /* The flow is in_utf8 -> in_utf16 -> SASLPrep -> out_utf16 -> out_utf8. */ - UChar *in_utf16, *out_utf16; - char *out_utf8; - int32_t in_utf16_len, out_utf16_len, out_utf8_len; - UErrorCode error_code = U_ZERO_ERROR; - UStringPrepProfile *prep; - -#define SASL_PREP_ERR_RETURN(msg) \ - do { \ - bson_set_error (err, \ - MONGOC_ERROR_SCRAM, \ - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, \ - (msg), \ - name); \ - return NULL; \ - } while (0) - - /* 1. convert str to UTF-16. */ - /* preflight to get the destination length. */ - (void) u_strFromUTF8 ( - NULL, 0, &in_utf16_len, in_utf8, in_utf8_len, &error_code); - if (error_code != U_BUFFER_OVERFLOW_ERROR) { - SASL_PREP_ERR_RETURN ("could not calculate UTF-16 length of %s"); - } - - /* convert to UTF-16. */ - error_code = U_ZERO_ERROR; - in_utf16 = bson_malloc (sizeof (UChar) * - (in_utf16_len + 1)); /* add one for null byte. */ - (void) u_strFromUTF8 ( - in_utf16, in_utf16_len + 1, NULL, in_utf8, in_utf8_len, &error_code); - if (error_code) { - bson_free (in_utf16); - SASL_PREP_ERR_RETURN ("could not convert %s to UTF-16"); - } - - /* 2. perform SASLPrep. */ - prep = usprep_openByType (USPREP_RFC4013_SASLPREP, &error_code); - if (error_code) { - bson_free (in_utf16); - SASL_PREP_ERR_RETURN ("could not start SASLPrep for %s"); - } - /* preflight. */ - out_utf16_len = usprep_prepare ( - prep, in_utf16, in_utf16_len, NULL, 0, USPREP_DEFAULT, NULL, &error_code); - if (error_code != U_BUFFER_OVERFLOW_ERROR) { - bson_free (in_utf16); - usprep_close (prep); - SASL_PREP_ERR_RETURN ("could not calculate SASLPrep length of %s"); - } - - /* convert. */ - error_code = U_ZERO_ERROR; - out_utf16 = bson_malloc (sizeof (UChar) * (out_utf16_len + 1)); - (void) usprep_prepare (prep, - in_utf16, - in_utf16_len, - out_utf16, - out_utf16_len + 1, - USPREP_DEFAULT, - NULL, - &error_code); - if (error_code) { - bson_free (in_utf16); - bson_free (out_utf16); - usprep_close (prep); - SASL_PREP_ERR_RETURN ("could not execute SASLPrep for %s"); - } - bson_free (in_utf16); - usprep_close (prep); - - /* 3. convert back to UTF-8. */ - /* preflight. */ - (void) u_strToUTF8 ( - NULL, 0, &out_utf8_len, out_utf16, out_utf16_len, &error_code); - if (error_code != U_BUFFER_OVERFLOW_ERROR) { - bson_free (out_utf16); - SASL_PREP_ERR_RETURN ("could not calculate UTF-8 length of %s"); - } - - /* convert. */ - error_code = U_ZERO_ERROR; - out_utf8 = (char *) bson_malloc ( - sizeof (char) * (out_utf8_len + 1)); /* add one for null byte. */ - (void) u_strToUTF8 ( - out_utf8, out_utf8_len + 1, NULL, out_utf16, out_utf16_len, &error_code); - if (error_code) { - bson_free (out_utf8); - bson_free (out_utf16); - SASL_PREP_ERR_RETURN ("could not convert %s back to UTF-8"); - } - bson_free (out_utf16); - return out_utf8; -#undef SASL_PREP_ERR_RETURN -} -#endif - -char * -_mongoc_sasl_prep (const char *in_utf8, int in_utf8_len, bson_error_t *err) -{ -#ifdef MONGOC_ENABLE_ICU - return _mongoc_sasl_prep_impl ("password", in_utf8, in_utf8_len, err); -#else - if (_mongoc_sasl_prep_required (in_utf8)) { - bson_set_error (err, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: ICU required to SASLPrep password"); - return NULL; - } - return bson_strdup (in_utf8); -#endif -} -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-channel-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-channel-private.h deleted file mode 100644 index 50686099b97eeb209a0f3de526da633ae460de79..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-channel-private.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SECURE_CHANNEL_PRIVATE_H -#define MONGOC_SECURE_CHANNEL_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-tls-secure-channel-private.h" - -#define SECURITY_WIN32 -#include <security.h> -#include <schnlsp.h> -#include <schannel.h> - -BSON_BEGIN_DECLS - - -char * -_mongoc_secure_channel_extract_subject (const char *filename, - const char *passphrase); - -bool -mongoc_secure_channel_setup_ca ( - mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); -bool -mongoc_secure_channel_setup_crl ( - mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); -size_t -mongoc_secure_channel_read (mongoc_stream_tls_t *tls, - void *data, - size_t data_length); -PCCERT_CONTEXT -mongoc_secure_channel_setup_certificate ( - mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); - - -/* it may require 16k + some overhead to hold one decryptable block of data - do - * what cURL does, add 1k */ -#define MONGOC_SCHANNEL_BUFFER_INIT_SIZE (17 * 1024) - -void -_mongoc_secure_channel_init_sec_buffer (SecBuffer *buffer, - unsigned long buf_type, - void *buf_data_ptr, - unsigned long buf_byte_size); - -void -_mongoc_secure_channel_init_sec_buffer_desc (SecBufferDesc *desc, - SecBuffer *buffer_array, - unsigned long buffer_count); - -void -mongoc_secure_channel_realloc_buf (size_t *size, - uint8_t **buf, - size_t new_size); - -bool -mongoc_secure_channel_handshake_step_1 (mongoc_stream_tls_t *tls, - char *hostname); -bool -mongoc_secure_channel_handshake_step_2 (mongoc_stream_tls_t *tls, - char *hostname); -bool -mongoc_secure_channel_handshake_step_3 (mongoc_stream_tls_t *tls, - char *hostname); - - -BSON_END_DECLS - - -#endif /* MONGOC_SECURE_CHANNEL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-channel.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-channel.c deleted file mode 100644 index 3f73ad2549dcb186db11f7eceef65b5347928b62..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-channel.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL - -#include <bson/bson.h> - -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-secure-channel-private.h" -#include "mongoc/mongoc-stream-tls-secure-channel-private.h" -#include "mongoc/mongoc-errno-private.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-secure-channel" - -/* mingw doesn't define this */ -#ifndef SECBUFFER_ALERT -#define SECBUFFER_ALERT 17 -#endif - - -PCCERT_CONTEXT -mongoc_secure_channel_setup_certificate_from_file (const char *filename) -{ - char *pem; - FILE *file; - bool success; - HCRYPTKEY hKey; - long pem_length; - HCRYPTPROV provider; - CERT_BLOB public_blob; - const char *pem_public; - const char *pem_private; - LPBYTE blob_private = NULL; - PCCERT_CONTEXT cert = NULL; - DWORD blob_private_len = 0; - HCERTSTORE cert_store = NULL; - DWORD encrypted_cert_len = 0; - LPBYTE encrypted_cert = NULL; - DWORD encrypted_private_len = 0; - LPBYTE encrypted_private = NULL; - - - file = fopen (filename, "rb"); - if (!file) { - MONGOC_ERROR ("Couldn't open file '%s'", filename); - return false; - } - - fseek (file, 0, SEEK_END); - pem_length = ftell (file); - fseek (file, 0, SEEK_SET); - if (pem_length < 1) { - MONGOC_ERROR ("Couldn't determine file size of '%s'", filename); - return false; - } - - pem = (char *) bson_malloc0 (pem_length); - fread ((void *) pem, 1, pem_length, file); - fclose (file); - - pem_public = strstr (pem, "-----BEGIN CERTIFICATE-----"); - pem_private = strstr (pem, "-----BEGIN ENCRYPTED PRIVATE KEY-----"); - - if (pem_private) { - MONGOC_ERROR ("Detected unsupported encrypted private key"); - goto fail; - } - - pem_private = strstr (pem, "-----BEGIN RSA PRIVATE KEY-----"); - if (!pem_private) { - pem_private = strstr (pem, "-----BEGIN PRIVATE KEY-----"); - } - - if (!pem_private) { - MONGOC_ERROR ("Can't find private key in '%s'", filename); - goto fail; - } - - public_blob.cbData = (DWORD) strlen (pem_public); - public_blob.pbData = (BYTE *) pem_public; - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380264%28v=vs.85%29.aspx - */ - CryptQueryObject ( - CERT_QUERY_OBJECT_BLOB, /* dwObjectType, blob or file */ - &public_blob, /* pvObject, Unicode filename */ - CERT_QUERY_CONTENT_FLAG_ALL, /* dwExpectedContentTypeFlags */ - CERT_QUERY_FORMAT_FLAG_ALL, /* dwExpectedFormatTypeFlags */ - 0, /* dwFlags, reserved for "future use" */ - NULL, /* pdwMsgAndCertEncodingType, OUT, unused */ - NULL, /* pdwContentType (dwExpectedContentTypeFlags), OUT, unused */ - NULL, /* pdwFormatType (dwExpectedFormatTypeFlags,), OUT, unused */ - NULL, /* phCertStore, OUT, HCERTSTORE.., unused, for now */ - NULL, /* phMsg, OUT, HCRYPTMSG, only for PKC7, unused */ - (const void **) &cert /* ppvContext, OUT, the Certificate Context */ - ); - - if (!cert) { - MONGOC_ERROR ("Failed to extract public key from '%s'. Error 0x%.8X", - filename, - GetLastError ()); - goto fail; - } - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380285%28v=vs.85%29.aspx - */ - success = - CryptStringToBinaryA (pem_private, /* pszString */ - 0, /* cchString */ - CRYPT_STRING_BASE64HEADER, /* dwFlags */ - NULL, /* pbBinary */ - &encrypted_private_len, /* pcBinary, IN/OUT */ - NULL, /* pdwSkip */ - NULL); /* pdwFlags */ - if (!success) { - MONGOC_ERROR ("Failed to convert base64 private key. Error 0x%.8X", - GetLastError ()); - goto fail; - } - - encrypted_private = (LPBYTE) bson_malloc0 (encrypted_private_len); - success = CryptStringToBinaryA (pem_private, - 0, - CRYPT_STRING_BASE64HEADER, - encrypted_private, - &encrypted_private_len, - NULL, - NULL); - if (!success) { - MONGOC_ERROR ("Failed to convert base64 private key. Error 0x%.8X", - GetLastError ()); - goto fail; - } - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa379912%28v=vs.85%29.aspx - */ - success = CryptDecodeObjectEx ( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* dwCertEncodingType */ - PKCS_RSA_PRIVATE_KEY, /* lpszStructType */ - encrypted_private, /* pbEncoded */ - encrypted_private_len, /* cbEncoded */ - 0, /* dwFlags */ - NULL, /* pDecodePara */ - NULL, /* pvStructInfo */ - &blob_private_len); /* pcbStructInfo */ - if (!success) { - LPTSTR msg = NULL; - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ARGUMENT_ARRAY, - NULL, - GetLastError (), - LANG_NEUTRAL, - (LPTSTR) &msg, - 0, - NULL); - MONGOC_ERROR ( - "Failed to parse private key. %s (0x%.8X)", msg, GetLastError ()); - LocalFree (msg); - goto fail; - } - - blob_private = (LPBYTE) bson_malloc0 (blob_private_len); - success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - PKCS_RSA_PRIVATE_KEY, - encrypted_private, - encrypted_private_len, - 0, - NULL, - blob_private, - &blob_private_len); - if (!success) { - MONGOC_ERROR ("Failed to parse private key. Error 0x%.8X", - GetLastError ()); - goto fail; - } - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa379886%28v=vs.85%29.aspx - */ - success = CryptAcquireContext (&provider, /* phProv */ - NULL, /* pszContainer */ - MS_ENHANCED_PROV, /* pszProvider */ - PROV_RSA_FULL, /* dwProvType */ - CRYPT_VERIFYCONTEXT); /* dwFlags */ - if (!success) { - MONGOC_ERROR ("CryptAcquireContext failed with error 0x%.8X", - GetLastError ()); - goto fail; - } - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380207%28v=vs.85%29.aspx - */ - success = CryptImportKey (provider, /* hProv */ - blob_private, /* pbData */ - blob_private_len, /* dwDataLen */ - 0, /* hPubKey */ - 0, /* dwFlags */ - &hKey); /* phKey, OUT */ - if (!success) { - MONGOC_ERROR ("CryptImportKey for private key failed with error 0x%.8X", - GetLastError ()); - goto fail; - } - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa376573%28v=vs.85%29.aspx - */ - success = CertSetCertificateContextProperty ( - cert, /* pCertContext */ - CERT_KEY_PROV_HANDLE_PROP_ID, /* dwPropId */ - 0, /* dwFlags */ - (const void *) provider); /* pvData */ - if (success) { - TRACE ("%s", "Successfully loaded client certificate"); - return cert; - } - - MONGOC_ERROR ("Can't associate private key with public key: 0x%.8X", - GetLastError ()); - -fail: - SecureZeroMemory (pem, pem_length); - bson_free (pem); - if (encrypted_private) { - SecureZeroMemory (encrypted_private, encrypted_private_len); - bson_free (encrypted_private); - } - - if (blob_private) { - SecureZeroMemory (blob_private, blob_private_len); - bson_free (blob_private); - } - - return NULL; -} - -PCCERT_CONTEXT -mongoc_secure_channel_setup_certificate ( - mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt) -{ - return mongoc_secure_channel_setup_certificate_from_file (opt->pem_file); -} - -void -_bson_append_szoid (bson_string_t *retval, - PCCERT_CONTEXT cert, - const char *label, - void *oid) -{ - DWORD oid_len = - CertGetNameString (cert, CERT_NAME_ATTR_TYPE, 0, oid, NULL, 0); - - if (oid_len > 1) { - char *tmp = bson_malloc0 (oid_len); - - CertGetNameString (cert, CERT_NAME_ATTR_TYPE, 0, oid, tmp, oid_len); - bson_string_append_printf (retval, "%s%s", label, tmp); - bson_free (tmp); - } -} -char * -_mongoc_secure_channel_extract_subject (const char *filename, - const char *passphrase) -{ - bson_string_t *retval; - PCCERT_CONTEXT cert; - - cert = mongoc_secure_channel_setup_certificate_from_file (filename); - if (!cert) { - return NULL; - } - - retval = bson_string_new (""); - ; - _bson_append_szoid (retval, cert, "C=", szOID_COUNTRY_NAME); - _bson_append_szoid (retval, cert, ",ST=", szOID_STATE_OR_PROVINCE_NAME); - _bson_append_szoid (retval, cert, ",L=", szOID_LOCALITY_NAME); - _bson_append_szoid (retval, cert, ",O=", szOID_ORGANIZATION_NAME); - _bson_append_szoid (retval, cert, ",OU=", szOID_ORGANIZATIONAL_UNIT_NAME); - _bson_append_szoid (retval, cert, ",CN=", szOID_COMMON_NAME); - _bson_append_szoid (retval, cert, ",STREET=", szOID_STREET_ADDRESS); - - return bson_string_free (retval, false); -} - -bool -mongoc_secure_channel_setup_ca ( - mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt) -{ - FILE *file; - long length; - const char *pem_key; - HCERTSTORE cert_store = NULL; - PCCERT_CONTEXT cert = NULL; - DWORD encrypted_cert_len = 0; - LPBYTE encrypted_cert = NULL; - - file = fopen (opt->ca_file, "rb"); - if (!file) { - MONGOC_ERROR ("Couldn't open file '%s'", opt->ca_file); - return false; - } - - fseek (file, 0, SEEK_END); - length = ftell (file); - fseek (file, 0, SEEK_SET); - if (length < 1) { - MONGOC_WARNING ("Couldn't determine file size of '%s'", opt->ca_file); - return false; - } - - pem_key = (const char *) bson_malloc0 (length); - fread ((void *) pem_key, 1, length, file); - fclose (file); - - /* If we have private keys or other fuzz, seek to the good stuff */ - pem_key = strstr (pem_key, "-----BEGIN CERTIFICATE-----"); - /*printf ("%s\n", pem_key);*/ - - if (!pem_key) { - MONGOC_WARNING ("Couldn't find certificate in '%d'", opt->ca_file); - return false; - } - - if (!CryptStringToBinaryA (pem_key, - 0, - CRYPT_STRING_BASE64HEADER, - NULL, - &encrypted_cert_len, - NULL, - NULL)) { - MONGOC_ERROR ("Failed to convert BASE64 public key. Error 0x%.8X", - GetLastError ()); - return false; - } - - encrypted_cert = (LPBYTE) LocalAlloc (0, encrypted_cert_len); - if (!CryptStringToBinaryA (pem_key, - 0, - CRYPT_STRING_BASE64HEADER, - encrypted_cert, - &encrypted_cert_len, - NULL, - NULL)) { - MONGOC_ERROR ("Failed to convert BASE64 public key. Error 0x%.8X", - GetLastError ()); - return false; - } - - cert = CertCreateCertificateContext ( - X509_ASN_ENCODING, encrypted_cert, encrypted_cert_len); - if (!cert) { - MONGOC_WARNING ("Could not convert certificate"); - return false; - } - - - cert_store = CertOpenStore ( - CERT_STORE_PROV_SYSTEM, /* provider */ - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */ - 0, /* unused */ - CERT_SYSTEM_STORE_LOCAL_MACHINE, /* dwFlags */ - L"Root"); /* system store name. "My" or "Root" */ - - if (cert_store == NULL) { - MONGOC_ERROR ("Error opening certificate store"); - return false; - } - - if (CertAddCertificateContextToStore ( - cert_store, cert, CERT_STORE_ADD_USE_EXISTING, NULL)) { - TRACE ("%s", "Added the certificate !"); - CertCloseStore (cert_store, 0); - return true; - } - MONGOC_WARNING ("Failed adding the cert"); - CertCloseStore (cert_store, 0); - - return false; -} - -bool -mongoc_secure_channel_setup_crl ( - mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt) -{ - HCERTSTORE cert_store = NULL; - PCCERT_CONTEXT cert = NULL; - LPWSTR str; - int chars; - - chars = MultiByteToWideChar (CP_ACP, 0, opt->crl_file, -1, NULL, 0); - if (chars < 1) { - MONGOC_WARNING ("Can't determine opt->crl_file length"); - return false; - } - str = (LPWSTR) bson_malloc0 (chars); - MultiByteToWideChar (CP_ACP, 0, opt->crl_file, -1, str, chars); - - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380264%28v=vs.85%29.aspx - */ - CryptQueryObject ( - CERT_QUERY_OBJECT_FILE, /* dwObjectType, blob or file */ - str, /* pvObject, Unicode filename */ - CERT_QUERY_CONTENT_FLAG_CRL, /* dwExpectedContentTypeFlags */ - CERT_QUERY_FORMAT_FLAG_ALL, /* dwExpectedFormatTypeFlags */ - 0, /* dwFlags, reserved for "future use" */ - NULL, /* pdwMsgAndCertEncodingType, OUT, unused */ - NULL, /* pdwContentType (dwExpectedContentTypeFlags), OUT, unused */ - NULL, /* pdwFormatType (dwExpectedFormatTypeFlags,), OUT, unused */ - NULL, /* phCertStore, OUT, HCERTSTORE.., unused, for now */ - NULL, /* phMsg, OUT, HCRYPTMSG, only for PKC7, unused */ - (const void **) &cert /* ppvContext, OUT, the Certificate Context */ - ); - bson_free (str); - - if (!cert) { - MONGOC_WARNING ("Can't extract CRL from '%s'", opt->crl_file); - return false; - } - - - cert_store = CertOpenStore ( - CERT_STORE_PROV_SYSTEM, /* provider */ - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */ - 0, /* unused */ - CERT_SYSTEM_STORE_LOCAL_MACHINE, /* dwFlags */ - L"Root"); /* system store name. "My" or "Root" */ - - if (cert_store == NULL) { - MONGOC_ERROR ("Error opening certificate store"); - CertFreeCertificateContext (cert); - return false; - } - - if (CertAddCertificateContextToStore ( - cert_store, cert, CERT_STORE_ADD_USE_EXISTING, NULL)) { - TRACE ("%s", "Added the certificate !"); - CertFreeCertificateContext (cert); - CertCloseStore (cert_store, 0); - return true; - } - - MONGOC_WARNING ("Failed adding the cert"); - CertFreeCertificateContext (cert); - CertCloseStore (cert_store, 0); - - return false; -} - -size_t -mongoc_secure_channel_read (mongoc_stream_tls_t *tls, - void *data, - size_t data_length) -{ - ssize_t length; - - errno = 0; - TRACE ("Wanting to read: %d, timeout is %d", data_length, tls->timeout_msec); - /* 4th argument is minimum bytes, while the data_length is the - * size of the buffer. We are totally fine with just one TLS record (few - *bytes) - **/ - length = mongoc_stream_read ( - tls->base_stream, data, data_length, 0, tls->timeout_msec); - - TRACE ("Got %d", length); - - if (length > 0) { - return length; - } - - return 0; -} - -size_t -mongoc_secure_channel_write (mongoc_stream_tls_t *tls, - const void *data, - size_t data_length) -{ - ssize_t length; - - errno = 0; - TRACE ("Wanting to write: %d", data_length); - length = mongoc_stream_write ( - tls->base_stream, (void *) data, data_length, tls->timeout_msec); - TRACE ("Wrote: %d", length); - - - return length; -} - -void -mongoc_secure_channel_realloc_buf (size_t *size, uint8_t **buf, size_t new_size) -{ - *size = bson_next_power_of_two (new_size); - *buf = bson_realloc (*buf, *size); -} - -/** - * The follow functions comes from one of my favorite project, cURL! - * Thank you so much for having gone through the Secure Channel pain for me. - * - * - * Copyright (C) 2012 - 2015, Marc Hoersken, <info@marc-hoersken.de> - * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> - * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Based upon the PolarSSL implementation in polarssl.c and polarssl.h: - * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com> - * - * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * Thanks for code and inspiration! - */ - -void -_mongoc_secure_channel_init_sec_buffer (SecBuffer *buffer, - unsigned long buf_type, - void *buf_data_ptr, - unsigned long buf_byte_size) -{ - buffer->cbBuffer = buf_byte_size; - buffer->BufferType = buf_type; - buffer->pvBuffer = buf_data_ptr; -} - -void -_mongoc_secure_channel_init_sec_buffer_desc (SecBufferDesc *desc, - SecBuffer *buffer_array, - unsigned long buffer_count) -{ - desc->ulVersion = SECBUFFER_VERSION; - desc->pBuffers = buffer_array; - desc->cBuffers = buffer_count; -} - - -bool -mongoc_secure_channel_handshake_step_1 (mongoc_stream_tls_t *tls, - char *hostname) -{ - SecBuffer outbuf; - ssize_t written = -1; - SecBufferDesc outbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - TRACE ("SSL/TLS connection with '%s' (step 1/3)", hostname); - - /* setup output buffer */ - _mongoc_secure_channel_init_sec_buffer (&outbuf, SECBUFFER_EMPTY, NULL, 0); - _mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, &outbuf, 1); - - /* setup request flags */ - secure_channel->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONFIDENTIALITY | - ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM; - - /* allocate memory for the security context handle */ - secure_channel->ctxt = (mongoc_secure_channel_ctxt *) bson_malloc0 ( - sizeof (mongoc_secure_channel_ctxt)); - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */ - sspi_status = InitializeSecurityContext ( - &secure_channel->cred->cred_handle, /* phCredential */ - NULL, /* phContext */ - hostname, /* pszTargetName */ - secure_channel->req_flags, /* fContextReq */ - 0, /* Reserved1, must be 0 */ - 0, /* TargetDataRep, unused */ - NULL, /* pInput */ - 0, /* Reserved2, must be 0 */ - &secure_channel->ctxt->ctxt_handle, /* phNewContext OUT param */ - &outbuf_desc, /* pOutput OUT param */ - &secure_channel->ret_flags, /* pfContextAttr OUT param */ - &secure_channel->ctxt->time_stamp /* ptsExpiry OUT param */ - ); - - if (sspi_status != SEC_I_CONTINUE_NEEDED) { - MONGOC_ERROR ("initial InitializeSecurityContext failed: %d", - sspi_status); - return false; - } - - TRACE ("sending initial handshake data: sending %lu bytes...", - outbuf.cbBuffer); - - /* send initial handshake data which is now stored in output buffer */ - written = - mongoc_secure_channel_write (tls, outbuf.pvBuffer, outbuf.cbBuffer); - FreeContextBuffer (outbuf.pvBuffer); - - if (outbuf.cbBuffer != (size_t) written) { - MONGOC_ERROR ("failed to send initial handshake data: " - "sent %zd of %lu bytes", - written, - outbuf.cbBuffer); - return false; - } - - TRACE ("sent initial handshake data: sent %zd bytes", written); - - secure_channel->recv_unrecoverable_err = 0; - secure_channel->recv_sspi_close_notify = false; - secure_channel->recv_connection_closed = false; - - /* continue to second handshake step */ - secure_channel->connecting_state = ssl_connect_2; - - return true; -} - -bool -mongoc_secure_channel_handshake_step_2 (mongoc_stream_tls_t *tls, - char *hostname) -{ - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - SECURITY_STATUS sspi_status = SEC_E_OK; - ssize_t nread = -1, written = -1; - SecBufferDesc outbuf_desc; - SecBufferDesc inbuf_desc; - SecBuffer outbuf[3]; - SecBuffer inbuf[2]; - bool doread; - int i; - - doread = (secure_channel->connecting_state != ssl_connect_2_writing) ? true - : false; - - TRACE ("%s", "SSL/TLS connection with endpoint (step 2/3)"); - - if (!secure_channel->cred || !secure_channel->ctxt) { - return false; - } - - /* grow the buffer if necessary */ - if (secure_channel->encdata_length == secure_channel->encdata_offset) { - mongoc_secure_channel_realloc_buf (&secure_channel->encdata_length, - &secure_channel->encdata_buffer, - secure_channel->encdata_length + 1); - } - - for (;;) { - if (doread) { - /* read encrypted handshake data from socket */ - nread = mongoc_secure_channel_read ( - tls, - (char *) (secure_channel->encdata_buffer + - secure_channel->encdata_offset), - secure_channel->encdata_length - secure_channel->encdata_offset); - - if (!nread) { - if (MONGOC_ERRNO_IS_AGAIN (errno)) { - if (secure_channel->connecting_state != ssl_connect_2_writing) { - secure_channel->connecting_state = ssl_connect_2_reading; - } - - TRACE ("%s", "failed to receive handshake, need more data"); - return true; - } - - MONGOC_ERROR ( - "failed to receive handshake, SSL/TLS connection failed"); - return false; - } - - /* increase encrypted data buffer offset */ - secure_channel->encdata_offset += nread; - } - - TRACE ("encrypted data buffer: offset %d length %d", - (int) secure_channel->encdata_offset, - (int) secure_channel->encdata_length); - - /* setup input buffers */ - _mongoc_secure_channel_init_sec_buffer ( - &inbuf[0], - SECBUFFER_TOKEN, - malloc (secure_channel->encdata_offset), - (unsigned long) (secure_channel->encdata_offset & - (size_t) 0xFFFFFFFFUL)); - _mongoc_secure_channel_init_sec_buffer ( - &inbuf[1], SECBUFFER_EMPTY, NULL, 0); - _mongoc_secure_channel_init_sec_buffer_desc (&inbuf_desc, inbuf, 2); - - /* setup output buffers */ - _mongoc_secure_channel_init_sec_buffer ( - &outbuf[0], SECBUFFER_TOKEN, NULL, 0); - _mongoc_secure_channel_init_sec_buffer ( - &outbuf[1], SECBUFFER_ALERT, NULL, 0); - _mongoc_secure_channel_init_sec_buffer ( - &outbuf[2], SECBUFFER_EMPTY, NULL, 0); - _mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, outbuf, 3); - - if (inbuf[0].pvBuffer == NULL) { - MONGOC_ERROR ("unable to allocate memory"); - return false; - } - - /* copy received handshake data into input buffer */ - memcpy (inbuf[0].pvBuffer, - secure_channel->encdata_buffer, - secure_channel->encdata_offset); - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx - */ - sspi_status = - InitializeSecurityContext (&secure_channel->cred->cred_handle, - &secure_channel->ctxt->ctxt_handle, - hostname, - secure_channel->req_flags, - 0, - 0, - &inbuf_desc, - 0, - NULL, - &outbuf_desc, - &secure_channel->ret_flags, - &secure_channel->ctxt->time_stamp); - - /* free buffer for received handshake data */ - free (inbuf[0].pvBuffer); - - /* check if the handshake was incomplete */ - if (sspi_status == SEC_E_INCOMPLETE_MESSAGE) { - secure_channel->connecting_state = ssl_connect_2_reading; - TRACE ("%s", "received incomplete message, need more data"); - return true; - } - - /* If the server has requested a client certificate, attempt to continue - * the handshake without one. This will allow connections to servers which - * request a client certificate but do not require it. */ - if (sspi_status == SEC_I_INCOMPLETE_CREDENTIALS && - !(secure_channel->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) { - secure_channel->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; - secure_channel->connecting_state = ssl_connect_2_writing; - TRACE ("%s", "A client certificate has been requested"); - return true; - } - - /* check if the handshake needs to be continued */ - if (sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) { - for (i = 0; i < 3; i++) { - /* search for handshake tokens that need to be send */ - if (outbuf[i].BufferType == SECBUFFER_TOKEN && - outbuf[i].cbBuffer > 0) { - TRACE ("sending next handshake data: sending %lu bytes...", - outbuf[i].cbBuffer); - - /* send handshake token to server */ - written = mongoc_secure_channel_write ( - tls, outbuf[i].pvBuffer, outbuf[i].cbBuffer); - - if (outbuf[i].cbBuffer != (size_t) written) { - MONGOC_ERROR ("failed to send next handshake data: " - "sent %zd of %lu bytes", - written, - outbuf[i].cbBuffer); - return false; - } - } - - /* free obsolete buffer */ - if (outbuf[i].pvBuffer != NULL) { - FreeContextBuffer (outbuf[i].pvBuffer); - } - } - } else { - switch (sspi_status) { - case SEC_E_WRONG_PRINCIPAL: - MONGOC_ERROR ("SSL Certification verification failed: hostname " - "doesn't match certificate"); - break; - - case SEC_E_UNTRUSTED_ROOT: - MONGOC_ERROR ("SSL Certification verification failed: Untrusted " - "root certificate"); - break; - - case SEC_E_CERT_EXPIRED: - MONGOC_ERROR ("SSL Certification verification failed: certificate " - "has expired"); - break; - case CRYPT_E_NO_REVOCATION_CHECK: - /* This seems to be raised also when hostname doesn't match the - * certificate */ - MONGOC_ERROR ("SSL Certification verification failed: failed " - "revocation/hostname check"); - break; - - case SEC_E_INSUFFICIENT_MEMORY: - case SEC_E_INTERNAL_ERROR: - case SEC_E_INVALID_HANDLE: - case SEC_E_INVALID_TOKEN: - case SEC_E_LOGON_DENIED: - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - case SEC_E_NO_CREDENTIALS: - case SEC_E_TARGET_UNKNOWN: - case SEC_E_UNSUPPORTED_FUNCTION: -#ifdef SEC_E_APPLICATION_PROTOCOL_MISMATCH - /* Not available in VS2010 */ - case SEC_E_APPLICATION_PROTOCOL_MISMATCH: -#endif - - - default: { - LPTSTR msg = NULL; - - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ARGUMENT_ARRAY, - NULL, - GetLastError (), - LANG_NEUTRAL, - (LPTSTR) &msg, - 0, - NULL); - MONGOC_ERROR ("Failed to initialize security context, error code: " - "0x%04X%04X: %s", - (sspi_status >> 16) & 0xffff, - sspi_status & 0xffff, - msg); - LocalFree (msg); - } - } - return false; - } - - /* check if there was additional remaining encrypted data */ - if (inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) { - TRACE ("encrypted data length: %lu", inbuf[1].cbBuffer); - - /* - * There are two cases where we could be getting extra data here: - * 1) If we're renegotiating a connection and the handshake is already - * complete (from the server perspective), it can encrypted app data - * (not handshake data) in an extra buffer at this point. - * 2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a - * connection and this extra data is part of the handshake. - * We should process the data immediately; waiting for the socket to - * be ready may fail since the server is done sending handshake data. - */ - /* check if the remaining data is less than the total amount - * and therefore begins after the already processed data */ - if (secure_channel->encdata_offset > inbuf[1].cbBuffer) { - memmove (secure_channel->encdata_buffer, - (secure_channel->encdata_buffer + - secure_channel->encdata_offset) - - inbuf[1].cbBuffer, - inbuf[1].cbBuffer); - secure_channel->encdata_offset = inbuf[1].cbBuffer; - - if (sspi_status == SEC_I_CONTINUE_NEEDED) { - doread = FALSE; - continue; - } - } - } else { - secure_channel->encdata_offset = 0; - } - - break; - } - - /* check if the handshake needs to be continued */ - if (sspi_status == SEC_I_CONTINUE_NEEDED) { - secure_channel->connecting_state = ssl_connect_2_reading; - return true; - } - - /* check if the handshake is complete */ - if (sspi_status == SEC_E_OK) { - secure_channel->connecting_state = ssl_connect_3; - TRACE ("%s", "SSL/TLS handshake complete"); - } - - return true; -} - -bool -mongoc_secure_channel_handshake_step_3 (mongoc_stream_tls_t *tls, - char *hostname) -{ - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - BSON_ASSERT (ssl_connect_3 == secure_channel->connecting_state); - - TRACE ("SSL/TLS connection with %s (step 3/3)", hostname); - - if (!secure_channel->cred) { - return false; - } - - /* check if the required context attributes are met */ - if (secure_channel->ret_flags != secure_channel->req_flags) { - MONGOC_ERROR ("Failed handshake"); - - return false; - } - - secure_channel->connecting_state = ssl_connect_done; - - return true; -} -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-transport-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-transport-private.h deleted file mode 100644 index 1e35e85ece94a16f853fb395383e794f32a6ef7b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-transport-private.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SECURE_TRANSPORT_PRIVATE_H -#define MONGOC_SECURE_TRANSPORT_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-stream-tls-secure-transport-private.h" -#include <Security/Security.h> - - -BSON_BEGIN_DECLS - -char * -_mongoc_cfstringref_to_cstring (CFStringRef ref); - -char * -_mongoc_secure_transport_extract_subject (const char *filename, - const char *passphrase); - -OSStatus -mongoc_secure_transport_write (SSLConnectionRef connection, - const void *data, - size_t *data_length); -OSStatus -mongoc_secure_transport_read (SSLConnectionRef connection, - void *data, - size_t *data_length); - -bool -mongoc_secure_transport_setup_ca ( - mongoc_stream_tls_secure_transport_t *secure_transport, - mongoc_ssl_opt_t *opt); - -bool -mongoc_secure_transport_setup_certificate ( - mongoc_stream_tls_secure_transport_t *secure_transport, - mongoc_ssl_opt_t *opt); - -BSON_END_DECLS - - -#endif /* MONGOC_SECURE_TRANSPORT_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-transport.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-transport.c deleted file mode 100644 index 9d8524e6d7979ed048f3afb3c56ede6e764f96b5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-secure-transport.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT - -#include <bson/bson.h> - -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-secure-transport-private.h" -#include "mongoc/mongoc-stream-tls-secure-transport-private.h" - -#include <CoreFoundation/CoreFoundation.h> -#include <Security/Security.h> -#include <Security/SecKey.h> -#include <Security/SecureTransport.h> -#include <CommonCrypto/CommonDigest.h> -#include <Security/Security.h> -#include <Security/SecureTransport.h> -#include <CoreFoundation/CoreFoundation.h> - -/* Jailbreak Darwin Private API */ -/* - * An alternative to using SecIdentityCreate is to use - * SecIdentityCreateWithCertificate with a temporary keychain. However, doing so - * leads to memory bugs. Unfortunately, using this private API seems to be the - * best solution. - */ -SecIdentityRef -SecIdentityCreate (CFAllocatorRef allocator, - SecCertificateRef certificate, - SecKeyRef privateKey); - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-secure_transport" - -char * -_mongoc_cfstringref_to_cstring (CFStringRef str) -{ - CFIndex length; - CFStringEncoding encoding; - CFIndex max_size; - char *cs; - - if (!str) { - return NULL; - } - - if (CFGetTypeID (str) != CFStringGetTypeID ()) { - return NULL; - } - - length = CFStringGetLength (str); - encoding = kCFStringEncodingASCII; - max_size = CFStringGetMaximumSizeForEncoding (length, encoding) + 1; - cs = bson_malloc ((size_t) max_size); - - if (CFStringGetCString (str, cs, max_size, encoding)) { - return cs; - } - - bson_free (cs); - return NULL; -} - -static void -_bson_append_cftyperef (bson_string_t *retval, const char *label, CFTypeRef str) -{ - char *cs; - - if (str) { - cs = _mongoc_cfstringref_to_cstring (str); - - if (cs) { - bson_string_append_printf (retval, "%s%s", label, cs); - bson_free (cs); - } else { - bson_string_append_printf (retval, "%s(null)", label); - } - } -} - -CFTypeRef -_mongoc_secure_transport_dict_get (CFArrayRef values, CFStringRef label) -{ - if (!values || CFGetTypeID (values) != CFArrayGetTypeID ()) { - return NULL; - } - - for (CFIndex i = 0; i < CFArrayGetCount (values); ++i) { - CFStringRef item_label; - CFDictionaryRef item = CFArrayGetValueAtIndex (values, i); - - if (CFGetTypeID (item) != CFDictionaryGetTypeID ()) { - continue; - } - - item_label = CFDictionaryGetValue (item, kSecPropertyKeyLabel); - if (item_label && - CFStringCompare (item_label, label, 0) == kCFCompareEqualTo) { - return CFDictionaryGetValue (item, kSecPropertyKeyValue); - } - } - - return NULL; -} - -char * -_mongoc_secure_transport_RFC2253_from_cert (SecCertificateRef cert) -{ - CFTypeRef value; - bson_string_t *retval; - CFTypeRef subject_name; - CFDictionaryRef cert_dict; - - cert_dict = SecCertificateCopyValues (cert, NULL, NULL); - if (!cert_dict) { - return NULL; - } - - subject_name = CFDictionaryGetValue (cert_dict, kSecOIDX509V1SubjectName); - if (!subject_name) { - CFRelease (cert_dict); - return NULL; - } - - subject_name = CFDictionaryGetValue (subject_name, kSecPropertyKeyValue); - if (!subject_name) { - CFRelease (cert_dict); - return NULL; - } - - retval = bson_string_new (""); - ; - - value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDCountryName); - _bson_append_cftyperef (retval, "C=", value); - - value = _mongoc_secure_transport_dict_get (subject_name, - kSecOIDStateProvinceName); - _bson_append_cftyperef (retval, ",ST=", value); - - value = - _mongoc_secure_transport_dict_get (subject_name, kSecOIDLocalityName); - _bson_append_cftyperef (retval, ",L=", value); - - value = - _mongoc_secure_transport_dict_get (subject_name, kSecOIDOrganizationName); - _bson_append_cftyperef (retval, ",O=", value); - - value = _mongoc_secure_transport_dict_get (subject_name, - kSecOIDOrganizationalUnitName); - if (value) { - /* Can be either one unit name, or array of unit names */ - if (CFGetTypeID (value) == CFStringGetTypeID ()) { - _bson_append_cftyperef (retval, ",OU=", value); - } else if (CFGetTypeID (value) == CFArrayGetTypeID ()) { - CFIndex len = CFArrayGetCount (value); - - if (len > 0) { - _bson_append_cftyperef ( - retval, ",OU=", CFArrayGetValueAtIndex (value, 0)); - } - if (len > 1) { - _bson_append_cftyperef ( - retval, ",", CFArrayGetValueAtIndex (value, 1)); - } - if (len > 2) { - _bson_append_cftyperef ( - retval, ",", CFArrayGetValueAtIndex (value, 2)); - } - } - } - - value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDCommonName); - _bson_append_cftyperef (retval, ",CN=", value); - - value = - _mongoc_secure_transport_dict_get (subject_name, kSecOIDStreetAddress); - _bson_append_cftyperef (retval, ",STREET", value); - - CFRelease (cert_dict); - return bson_string_free (retval, false); -} - - -static void -safe_release (CFTypeRef ref) -{ - if (ref) { - CFRelease (ref); - } -} - - -bool -_mongoc_secure_transport_import_pem (const char *filename, - const char *passphrase, - CFArrayRef *items, - SecExternalItemType *type) -{ - SecExternalFormat format = kSecFormatPEMSequence; - SecItemImportExportKeyParameters params = {0}; - SecTransformRef sec_transform = NULL; - CFReadStreamRef read_stream = NULL; - CFDataRef dataref = NULL; - CFErrorRef error = NULL; - CFURLRef url = NULL; - OSStatus res; - bool r = false; - - if (!filename) { - TRACE ("%s", "No certificate provided"); - return false; - } - - params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - params.flags = 0; - params.passphrase = NULL; - params.alertTitle = NULL; - params.alertPrompt = NULL; - params.accessRef = NULL; - params.keyUsage = NULL; - params.keyAttributes = NULL; - - if (passphrase) { - params.passphrase = CFStringCreateWithCString ( - kCFAllocatorDefault, passphrase, kCFStringEncodingUTF8); - } - - url = CFURLCreateFromFileSystemRepresentation ( - kCFAllocatorDefault, (const UInt8 *) filename, strlen (filename), false); - read_stream = CFReadStreamCreateWithFile (kCFAllocatorDefault, url); - if (!CFReadStreamOpen (read_stream)) { - MONGOC_ERROR ("Cannot find certificate in '%s', error reading file", - filename); - goto done; - } - - sec_transform = SecTransformCreateReadTransformWithReadStream (read_stream); - dataref = SecTransformExecute (sec_transform, &error); - - if (error) { - CFStringRef str = CFErrorCopyDescription (error); - MONGOC_ERROR ( - "Failed importing PEM '%s': %s", - filename, - CFStringGetCStringPtr (str, CFStringGetFastestEncoding (str))); - - CFRelease (str); - goto done; - } - - res = SecItemImport ( - dataref, CFSTR (".pem"), &format, type, 0, ¶ms, NULL, items); - - if (res) { - MONGOC_ERROR ("Failed importing PEM '%s' (code: %d)", filename, res); - goto done; - } - - r = true; - -done: - safe_release (dataref); - safe_release (sec_transform); - safe_release (read_stream); - safe_release (url); - safe_release (params.passphrase); - - return r; -} - -char * -_mongoc_secure_transport_extract_subject (const char *filename, - const char *passphrase) -{ - bool success; - char *retval = NULL; - CFArrayRef items = NULL; - SecExternalItemType type = kSecItemTypeCertificate; - - - success = - _mongoc_secure_transport_import_pem (filename, passphrase, &items, &type); - - if (!success) { - return NULL; - } - - if (type == kSecItemTypeAggregate) { - for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { - CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); - - if (item_id == SecCertificateGetTypeID ()) { - retval = _mongoc_secure_transport_RFC2253_from_cert ( - (SecCertificateRef) CFArrayGetValueAtIndex (items, i)); - break; - } - } - } else if (type == kSecItemTypeCertificate) { - retval = - _mongoc_secure_transport_RFC2253_from_cert ((SecCertificateRef) items); - } - - if (items) { - CFRelease (items); - } - - return retval; -} - -bool -mongoc_secure_transport_setup_certificate ( - mongoc_stream_tls_secure_transport_t *secure_transport, - mongoc_ssl_opt_t *opt) -{ - bool success; - CFArrayRef items; - SecIdentityRef id; - SecKeyRef key = NULL; - SecCertificateRef cert = NULL; - SecExternalItemType type = kSecItemTypeCertificate; - - if (!opt->pem_file) { - TRACE ("%s", - "No private key provided, the server won't be able to verify us"); - return false; - } - - success = _mongoc_secure_transport_import_pem ( - opt->pem_file, opt->pem_pwd, &items, &type); - if (!success) { - /* caller will log an error */ - return false; - } - - if (type != kSecItemTypeAggregate) { - MONGOC_ERROR ("Cannot work with keys of type \"%d\". Please file a JIRA", - type); - CFRelease (items); - return false; - } - - for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { - CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); - - if (item_id == SecCertificateGetTypeID ()) { - cert = (SecCertificateRef) CFArrayGetValueAtIndex (items, i); - } else if (item_id == SecKeyGetTypeID ()) { - key = (SecKeyRef) CFArrayGetValueAtIndex (items, i); - } - } - - if (!cert || !key) { - MONGOC_ERROR ("Couldn't find valid private key"); - CFRelease (items); - return false; - } - - id = SecIdentityCreate (kCFAllocatorDefault, cert, key); - secure_transport->my_cert = - CFArrayCreateMutable (kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks); - - CFArrayAppendValue (secure_transport->my_cert, id); - CFArrayAppendValue (secure_transport->my_cert, cert); - CFRelease (id); - - /* - * Secure Transport assumes the following: - * * The certificate references remain valid for the lifetime of the - * session. - * * The identity specified in certRefs[0] is capable of signing. - */ - success = !SSLSetCertificate (secure_transport->ssl_ctx_ref, - secure_transport->my_cert); - TRACE ("Setting client certificate %s", success ? "succeeded" : "failed"); - - CFRelease (items); - return true; -} - -bool -mongoc_secure_transport_setup_ca ( - mongoc_stream_tls_secure_transport_t *secure_transport, - mongoc_ssl_opt_t *opt) -{ - CFArrayRef items; - SecExternalItemType type = kSecItemTypeCertificate; - bool success; - - if (!opt->ca_file) { - TRACE ("%s", "No CA provided, using defaults"); - return false; - } - - success = - _mongoc_secure_transport_import_pem (opt->ca_file, NULL, &items, &type); - - if (!success) { - MONGOC_ERROR ("Cannot load Certificate Authorities from file \'%s\'", - opt->ca_file); - return false; - } - - if (type == kSecItemTypeAggregate) { - CFMutableArrayRef anchors = - CFArrayCreateMutable (kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { - CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); - - if (item_id == SecCertificateGetTypeID ()) { - CFArrayAppendValue (anchors, CFArrayGetValueAtIndex (items, i)); - } - } - secure_transport->anchors = anchors; - CFRelease (items); - } else if (type == kSecItemTypeCertificate) { - secure_transport->anchors = items; - } else { - CFRelease (items); - } - - /* This should be SSLSetCertificateAuthorities But the /TLS/ tests fail - * when it is */ - success = !SSLSetTrustedRoots ( - secure_transport->ssl_ctx_ref, secure_transport->anchors, true); - TRACE ("Setting certificate authority %s (%s)", - success ? "succeeded" : "failed", - opt->ca_file); - return true; -} - -OSStatus -mongoc_secure_transport_read (SSLConnectionRef connection, - void *data, - size_t *data_length) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) connection; - ssize_t length; - ENTRY; - - errno = 0; - /* 4 arguments is *min_bytes* -- This is not a negotiation. - * Secure Transport wants all or nothing. We must continue reading until - * we get this amount, or timeout */ - length = mongoc_stream_read ( - tls->base_stream, data, *data_length, *data_length, tls->timeout_msec); - - if (length > 0) { - *data_length = length; - RETURN (noErr); - } - - if (length == 0) { - RETURN (errSSLClosedGraceful); - } - - switch (errno) { - case ENOENT: - RETURN (errSSLClosedGraceful); - break; - case ECONNRESET: - RETURN (errSSLClosedAbort); - break; - case EAGAIN: - RETURN (errSSLWouldBlock); - break; - default: - RETURN (-36); /* ioErr */ - break; - } -} - -OSStatus -mongoc_secure_transport_write (SSLConnectionRef connection, - const void *data, - size_t *data_length) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) connection; - ssize_t length; - ENTRY; - - errno = 0; - length = mongoc_stream_write ( - tls->base_stream, (void *) data, *data_length, tls->timeout_msec); - - if (length >= 0) { - *data_length = length; - RETURN (noErr); - } - - switch (errno) { - case EAGAIN: - RETURN (errSSLWouldBlock); - default: - RETURN (-36); /* ioErr */ - } -} -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description-private.h deleted file mode 100644 index 16b8ae0882690c55a794e03f333768e2e210e9c6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description-private.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SERVER_DESCRIPTION_PRIVATE_H -#define MONGOC_SERVER_DESCRIPTION_PRIVATE_H - -#include "mongoc/mongoc-server-description.h" - - -#define MONGOC_DEFAULT_WIRE_VERSION 0 -#define MONGOC_DEFAULT_WRITE_BATCH_SIZE 1000 -#define MONGOC_DEFAULT_BSON_OBJ_SIZE 16 * 1024 * 1024 -#define MONGOC_DEFAULT_MAX_MSG_SIZE 48000000 -/* This is slightly out-of-spec as of the current version of the spec (1.0.0), - * but SPEC-1397 plans to amend "Size limits and Wire Protocol Considerations" - * to say that drivers MAY split with a reduced maxBsonObjectSize or - * maxMessageSizeBytes - * depending on the implementation. It is less invasive for libmongoc to split - * OP_MSG payload type 1 with a reduced maxMessageSizeBytes and convert it to a - * payload type 0 - * rather than split a payload type 0 with a reduced maxBsonObjectSize. - */ -#define MONGOC_REDUCED_MAX_MSG_SIZE_FOR_FLE 2097152 -#define MONGOC_NO_SESSIONS -1 -#define MONGOC_IDLE_WRITE_PERIOD_MS 10 * 1000 - -/* represent a server or topology with no replica set config version */ -#define MONGOC_NO_SET_VERSION -1 - -typedef enum { - MONGOC_SERVER_UNKNOWN, - MONGOC_SERVER_STANDALONE, - MONGOC_SERVER_MONGOS, - MONGOC_SERVER_POSSIBLE_PRIMARY, - MONGOC_SERVER_RS_PRIMARY, - MONGOC_SERVER_RS_SECONDARY, - MONGOC_SERVER_RS_ARBITER, - MONGOC_SERVER_RS_OTHER, - MONGOC_SERVER_RS_GHOST, - MONGOC_SERVER_DESCRIPTION_TYPES, -} mongoc_server_description_type_t; - -struct _mongoc_server_description_t { - uint32_t id; - mongoc_host_list_t host; - int64_t round_trip_time_msec; - int64_t last_update_time_usec; - bson_t last_is_master; - bool has_is_master; - const char *connection_address; - const char *me; - - /* whether an APM server-opened callback has been fired before */ - bool opened; - - const char *set_name; - bson_error_t error; - mongoc_server_description_type_t type; - - int32_t min_wire_version; - int32_t max_wire_version; - int32_t max_msg_size; - int32_t max_bson_obj_size; - int32_t max_write_batch_size; - int64_t session_timeout_minutes; - - bson_t hosts; - bson_t passives; - bson_t arbiters; - - bson_t tags; - const char *current_primary; - int64_t set_version; - bson_oid_t election_id; - int64_t last_write_date_ms; - - bson_t compressors; -}; - -void -mongoc_server_description_init (mongoc_server_description_t *sd, - const char *address, - uint32_t id); -bool -mongoc_server_description_has_rs_member ( - mongoc_server_description_t *description, const char *address); - - -bool -mongoc_server_description_has_set_version ( - mongoc_server_description_t *description); - -bool -mongoc_server_description_has_election_id ( - mongoc_server_description_t *description); - -void -mongoc_server_description_cleanup (mongoc_server_description_t *sd); - -void -mongoc_server_description_reset (mongoc_server_description_t *sd); - -void -mongoc_server_description_set_state (mongoc_server_description_t *description, - mongoc_server_description_type_t type); -void -mongoc_server_description_set_set_version ( - mongoc_server_description_t *description, int64_t set_version); -void -mongoc_server_description_set_election_id ( - mongoc_server_description_t *description, const bson_oid_t *election_id); -void -mongoc_server_description_update_rtt (mongoc_server_description_t *server, - int64_t rtt_msec); - -void -mongoc_server_description_handle_ismaster (mongoc_server_description_t *sd, - const bson_t *reply, - int64_t rtt_msec, - const bson_error_t *error /* IN */); - -void -mongoc_server_description_filter_stale (mongoc_server_description_t **sds, - size_t sds_len, - mongoc_server_description_t *primary, - int64_t heartbeat_frequency_ms, - const mongoc_read_prefs_t *read_prefs); - -void -mongoc_server_description_filter_tags ( - mongoc_server_description_t **descriptions, - size_t description_len, - const mongoc_read_prefs_t *read_prefs); - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description.c deleted file mode 100644 index 7585feaf827c84c22b8cdc0bcb5f08c5a4e7ae31..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-config.h" -#include "mongoc/mongoc-host-list.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-server-description-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-uri.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-compression-private.h" - -#include <stdio.h> - -#define ALPHA 0.2 - -static bson_oid_t kObjectIdZero = {{0}}; - -static bool -_match_tag_set (const mongoc_server_description_t *sd, - bson_iter_t *tag_set_iter); - -/* Destroy allocated resources within @description, but don't free it */ -void -mongoc_server_description_cleanup (mongoc_server_description_t *sd) -{ - BSON_ASSERT (sd); - - bson_destroy (&sd->last_is_master); - bson_destroy (&sd->hosts); - bson_destroy (&sd->passives); - bson_destroy (&sd->arbiters); - bson_destroy (&sd->tags); - bson_destroy (&sd->compressors); -} - -/* Reset fields inside this sd, but keep same id, host information, and RTT, - and leave ismaster in empty inited state */ -void -mongoc_server_description_reset (mongoc_server_description_t *sd) -{ - BSON_ASSERT (sd); - - memset (&sd->error, 0, sizeof sd->error); - sd->set_name = NULL; - sd->type = MONGOC_SERVER_UNKNOWN; - - sd->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION; - sd->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION; - sd->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE; - sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE; - sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE; - sd->session_timeout_minutes = MONGOC_NO_SESSIONS; - sd->last_write_date_ms = -1; - - /* always leave last ismaster in an init-ed state until we destroy sd */ - bson_destroy (&sd->last_is_master); - bson_init (&sd->last_is_master); - sd->has_is_master = false; - sd->last_update_time_usec = bson_get_monotonic_time (); - - bson_destroy (&sd->hosts); - bson_destroy (&sd->passives); - bson_destroy (&sd->arbiters); - bson_destroy (&sd->tags); - bson_destroy (&sd->compressors); - - bson_init (&sd->hosts); - bson_init (&sd->passives); - bson_init (&sd->arbiters); - bson_init (&sd->tags); - bson_init (&sd->compressors); - - sd->me = NULL; - sd->current_primary = NULL; - sd->set_version = MONGOC_NO_SET_VERSION; - bson_oid_copy_unsafe (&kObjectIdZero, &sd->election_id); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_init -- - * - * Initialize a new server_description_t. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_server_description_init (mongoc_server_description_t *sd, - const char *address, - uint32_t id) -{ - ENTRY; - - BSON_ASSERT (sd); - BSON_ASSERT (address); - - sd->id = id; - sd->type = MONGOC_SERVER_UNKNOWN; - sd->round_trip_time_msec = -1; - - if (!_mongoc_host_list_from_string (&sd->host, address)) { - MONGOC_WARNING ("Failed to parse uri for %s", address); - return; - } - - sd->connection_address = sd->host.host_and_port; - bson_init (&sd->last_is_master); - bson_init (&sd->hosts); - bson_init (&sd->passives); - bson_init (&sd->arbiters); - bson_init (&sd->tags); - bson_init (&sd->compressors); - - mongoc_server_description_reset (sd); - - EXIT; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_destroy -- - * - * Destroy allocated resources within @description and free - * @description. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_server_description_destroy (mongoc_server_description_t *description) -{ - ENTRY; - - if (!description) { - EXIT; - } - - mongoc_server_description_cleanup (description); - - bson_free (description); - - EXIT; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_has_rs_member -- - * - * Return true if this address is included in server's list of rs - * members, false otherwise. - * - * Returns: - * true, false - * - * Side effects: - * None - * - *-------------------------------------------------------------------------- - */ -bool -mongoc_server_description_has_rs_member (mongoc_server_description_t *server, - const char *address) -{ - bson_iter_t member_iter; - const bson_t *rs_members[3]; - int i; - - if (server->type != MONGOC_SERVER_UNKNOWN) { - rs_members[0] = &server->hosts; - rs_members[1] = &server->arbiters; - rs_members[2] = &server->passives; - - for (i = 0; i < 3; i++) { - BSON_ASSERT (bson_iter_init (&member_iter, rs_members[i])); - - while (bson_iter_next (&member_iter)) { - if (strcasecmp (address, bson_iter_utf8 (&member_iter, NULL)) == - 0) { - return true; - } - } - } - } - - return false; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_has_set_version -- - * - * Did this server's ismaster response have a "setVersion" field? - * - * Returns: - * True if the server description's setVersion is set. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_server_description_has_set_version ( - mongoc_server_description_t *description) -{ - return description->set_version != MONGOC_NO_SET_VERSION; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_has_election_id -- - * - * Did this server's ismaster response have an "electionId" field? - * - * Returns: - * True if the server description's electionId is set. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_server_description_has_election_id ( - mongoc_server_description_t *description) -{ - return 0 != bson_oid_compare (&description->election_id, &kObjectIdZero); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_id -- - * - * Get the id of this server. - * - * Returns: - * Server's id. - * - *-------------------------------------------------------------------------- - */ - -uint32_t -mongoc_server_description_id (const mongoc_server_description_t *description) -{ - return description->id; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_host -- - * - * Return a reference to the host associated with this server description. - * - * Returns: - * This server description's host, a mongoc_host_list_t * you must - * not modify or free. - * - *-------------------------------------------------------------------------- - */ - -mongoc_host_list_t * -mongoc_server_description_host (const mongoc_server_description_t *description) -{ - return &((mongoc_server_description_t *) description)->host; -} - -int64_t -mongoc_server_description_last_update_time ( - const mongoc_server_description_t *description) -{ - return description->last_update_time_usec; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_round_trip_time -- - * - * Get the round trip time of this server, which is the client's - * measurement of the duration of an "ismaster" command. - * - * Returns: - * The server's round trip time in milliseconds. - * - *-------------------------------------------------------------------------- - */ - -int64_t -mongoc_server_description_round_trip_time ( - const mongoc_server_description_t *description) -{ - return description->round_trip_time_msec; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_type -- - * - * Get this server's type, one of the types defined in the Server - * Discovery And Monitoring Spec. - * - * Returns: - * A string. - * - *-------------------------------------------------------------------------- - */ - -const char * -mongoc_server_description_type (const mongoc_server_description_t *description) -{ - switch (description->type) { - case MONGOC_SERVER_UNKNOWN: - return "Unknown"; - case MONGOC_SERVER_STANDALONE: - return "Standalone"; - case MONGOC_SERVER_MONGOS: - return "Mongos"; - case MONGOC_SERVER_POSSIBLE_PRIMARY: - return "PossiblePrimary"; - case MONGOC_SERVER_RS_PRIMARY: - return "RSPrimary"; - case MONGOC_SERVER_RS_SECONDARY: - return "RSSecondary"; - case MONGOC_SERVER_RS_ARBITER: - return "RSArbiter"; - case MONGOC_SERVER_RS_OTHER: - return "RSOther"; - case MONGOC_SERVER_RS_GHOST: - return "RSGhost"; - case MONGOC_SERVER_DESCRIPTION_TYPES: - default: - MONGOC_ERROR ("Invalid mongoc_server_description_t type"); - return "Invalid"; - } -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_ismaster -- - * - * Return this server's most recent "ismaster" command response. - * - * Returns: - * A reference to a BSON document, owned by the server description. - * - *-------------------------------------------------------------------------- - */ - -const bson_t * -mongoc_server_description_ismaster ( - const mongoc_server_description_t *description) -{ - return &description->last_is_master; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_set_state -- - * - * Set the server description's server type. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_server_description_set_state (mongoc_server_description_t *description, - mongoc_server_description_type_t type) -{ - description->type = type; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_set_set_version -- - * - * Set the replica set version of this server. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_server_description_set_set_version ( - mongoc_server_description_t *description, int64_t set_version) -{ - description->set_version = set_version; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_set_election_id -- - * - * Set the election_id of this server. Copies the given ObjectId or, - * if it is NULL, zeroes description's election_id. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_server_description_set_election_id ( - mongoc_server_description_t *description, const bson_oid_t *election_id) -{ - if (election_id) { - bson_oid_copy_unsafe (election_id, &description->election_id); - } else { - bson_oid_copy_unsafe (&kObjectIdZero, &description->election_id); - } -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_server_description_update_rtt -- - * - * Calculate this server's rtt calculation using an exponentially- - * weighted moving average formula. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ -void -mongoc_server_description_update_rtt (mongoc_server_description_t *server, - int64_t rtt_msec) -{ - if (server->round_trip_time_msec == -1) { - server->round_trip_time_msec = rtt_msec; - } else { - server->round_trip_time_msec = (int64_t) ( - ALPHA * rtt_msec + (1 - ALPHA) * server->round_trip_time_msec); - } -} - - -static void -_mongoc_server_description_set_error (mongoc_server_description_t *sd, - const bson_error_t *error) -{ - if (error && error->code) { - memcpy (&sd->error, error, sizeof (bson_error_t)); - } else { - bson_set_error (&sd->error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "unknown error calling ismaster"); - } - - /* Server Discovery and Monitoring Spec: if the server type changes from a - * known type to Unknown its RTT is set to null. */ - sd->round_trip_time_msec = -1; -} - - -/* - *------------------------------------------------------------------------- - * - * Called during SDAM, from topology description's ismaster handler, or - * when handshaking a connection in _mongoc_cluster_stream_for_server. - * - * If @ismaster_response is empty, @error must say why ismaster failed. - * - *------------------------------------------------------------------------- - */ - -void -mongoc_server_description_handle_ismaster (mongoc_server_description_t *sd, - const bson_t *ismaster_response, - int64_t rtt_msec, - const bson_error_t *error /* IN */) -{ - bson_iter_t iter; - bson_iter_t child; - bool is_master = false; - bool is_shard = false; - bool is_secondary = false; - bool is_arbiter = false; - bool is_replicaset = false; - bool is_hidden = false; - const uint8_t *bytes; - uint32_t len; - int num_keys = 0; - ENTRY; - - BSON_ASSERT (sd); - - mongoc_server_description_reset (sd); - if (!ismaster_response) { - _mongoc_server_description_set_error (sd, error); - EXIT; - } - - bson_destroy (&sd->last_is_master); - bson_copy_to (ismaster_response, &sd->last_is_master); - sd->has_is_master = true; - - BSON_ASSERT (bson_iter_init (&iter, &sd->last_is_master)); - - while (bson_iter_next (&iter)) { - num_keys++; - if (strcmp ("ok", bson_iter_key (&iter)) == 0) { - if (!bson_iter_as_bool (&iter)) { - /* it doesn't really matter what error API we use. the code and - * domain will be overwritten. */ - (void) _mongoc_cmd_check_ok ( - ismaster_response, MONGOC_ERROR_API_VERSION_2, &sd->error); - /* ismaster response returned ok: 0. According to auth spec: "If the - * isMaster of the MongoDB Handshake fails with an error, drivers - * MUST treat this an authentication error." */ - sd->error.domain = MONGOC_ERROR_CLIENT; - sd->error.code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - goto failure; - } - } else if (strcmp ("ismaster", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; - is_master = bson_iter_bool (&iter); - } else if (strcmp ("me", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) - goto failure; - sd->me = bson_iter_utf8 (&iter, NULL); - } else if (strcmp ("maxMessageSizeBytes", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; - sd->max_msg_size = bson_iter_int32 (&iter); - } else if (strcmp ("maxBsonObjectSize", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; - sd->max_bson_obj_size = bson_iter_int32 (&iter); - } else if (strcmp ("maxWriteBatchSize", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; - sd->max_write_batch_size = bson_iter_int32 (&iter); - } else if (strcmp ("logicalSessionTimeoutMinutes", - bson_iter_key (&iter)) == 0) { - if (BSON_ITER_HOLDS_NUMBER (&iter)) { - sd->session_timeout_minutes = bson_iter_as_int64 (&iter); - } else if (BSON_ITER_HOLDS_NULL (&iter)) { - /* this arises executing standard JSON tests */ - sd->session_timeout_minutes = MONGOC_NO_SESSIONS; - } else { - goto failure; - } - } else if (strcmp ("minWireVersion", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; - sd->min_wire_version = bson_iter_int32 (&iter); - } else if (strcmp ("maxWireVersion", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_INT32 (&iter)) - goto failure; - sd->max_wire_version = bson_iter_int32 (&iter); - } else if (strcmp ("msg", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) - goto failure; - is_shard = !!bson_iter_utf8 (&iter, NULL); - } else if (strcmp ("setName", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) - goto failure; - sd->set_name = bson_iter_utf8 (&iter, NULL); - } else if (strcmp ("setVersion", bson_iter_key (&iter)) == 0) { - mongoc_server_description_set_set_version (sd, - bson_iter_as_int64 (&iter)); - } else if (strcmp ("electionId", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_OID (&iter)) - goto failure; - mongoc_server_description_set_election_id (sd, bson_iter_oid (&iter)); - } else if (strcmp ("secondary", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; - is_secondary = bson_iter_bool (&iter); - } else if (strcmp ("hosts", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_ARRAY (&iter)) - goto failure; - bson_iter_array (&iter, &len, &bytes); - bson_destroy (&sd->hosts); - BSON_ASSERT (bson_init_static (&sd->hosts, bytes, len)); - } else if (strcmp ("passives", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_ARRAY (&iter)) - goto failure; - bson_iter_array (&iter, &len, &bytes); - bson_destroy (&sd->passives); - BSON_ASSERT (bson_init_static (&sd->passives, bytes, len)); - } else if (strcmp ("arbiters", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_ARRAY (&iter)) - goto failure; - bson_iter_array (&iter, &len, &bytes); - bson_destroy (&sd->arbiters); - BSON_ASSERT (bson_init_static (&sd->arbiters, bytes, len)); - } else if (strcmp ("primary", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_UTF8 (&iter)) - goto failure; - sd->current_primary = bson_iter_utf8 (&iter, NULL); - } else if (strcmp ("arbiterOnly", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; - is_arbiter = bson_iter_bool (&iter); - } else if (strcmp ("isreplicaset", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_BOOL (&iter)) - goto failure; - is_replicaset = bson_iter_bool (&iter); - } else if (strcmp ("tags", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) - goto failure; - bson_iter_document (&iter, &len, &bytes); - bson_destroy (&sd->tags); - BSON_ASSERT (bson_init_static (&sd->tags, bytes, len)); - } else if (strcmp ("hidden", bson_iter_key (&iter)) == 0) { - is_hidden = bson_iter_bool (&iter); - } else if (strcmp ("lastWrite", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_DOCUMENT (&iter) || - !bson_iter_recurse (&iter, &child) || - !bson_iter_find (&child, "lastWriteDate") || - !BSON_ITER_HOLDS_DATE_TIME (&child)) { - goto failure; - } - - sd->last_write_date_ms = bson_iter_date_time (&child); - } else if (strcmp ("idleWritePeriodMillis", bson_iter_key (&iter)) == 0) { - sd->last_write_date_ms = bson_iter_as_int64 (&iter); - } else if (strcmp ("compression", bson_iter_key (&iter)) == 0) { - if (!BSON_ITER_HOLDS_ARRAY (&iter)) - goto failure; - bson_iter_array (&iter, &len, &bytes); - bson_destroy (&sd->compressors); - BSON_ASSERT (bson_init_static (&sd->compressors, bytes, len)); - } - } - - if (is_shard) { - sd->type = MONGOC_SERVER_MONGOS; - } else if (sd->set_name) { - if (is_hidden) { - sd->type = MONGOC_SERVER_RS_OTHER; - } else if (is_master) { - sd->type = MONGOC_SERVER_RS_PRIMARY; - } else if (is_secondary) { - sd->type = MONGOC_SERVER_RS_SECONDARY; - } else if (is_arbiter) { - sd->type = MONGOC_SERVER_RS_ARBITER; - } else { - sd->type = MONGOC_SERVER_RS_OTHER; - } - } else if (is_replicaset) { - sd->type = MONGOC_SERVER_RS_GHOST; - } else if (num_keys > 0) { - sd->type = MONGOC_SERVER_STANDALONE; - } else { - sd->type = MONGOC_SERVER_UNKNOWN; - } - - if (!num_keys) { - /* empty reply means ismaster failed */ - _mongoc_server_description_set_error (sd, error); - } - - mongoc_server_description_update_rtt (sd, rtt_msec); - - EXIT; - -failure: - sd->type = MONGOC_SERVER_UNKNOWN; - sd->round_trip_time_msec = -1; - - EXIT; -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_server_description_new_copy -- - * - * A copy of a server description that you must destroy, or NULL. - * - *------------------------------------------------------------------------- - */ -mongoc_server_description_t * -mongoc_server_description_new_copy ( - const mongoc_server_description_t *description) -{ - mongoc_server_description_t *copy; - - if (!description) { - return NULL; - } - - copy = (mongoc_server_description_t *) bson_malloc0 (sizeof (*copy)); - - copy->id = description->id; - copy->opened = description->opened; - memcpy (©->host, &description->host, sizeof (copy->host)); - copy->round_trip_time_msec = -1; - - copy->connection_address = copy->host.host_and_port; - bson_init (©->last_is_master); - bson_init (©->hosts); - bson_init (©->passives); - bson_init (©->arbiters); - bson_init (©->tags); - bson_init (©->compressors); - - if (description->has_is_master) { - /* calls mongoc_server_description_reset */ - mongoc_server_description_handle_ismaster ( - copy, - &description->last_is_master, - description->round_trip_time_msec, - &description->error); - } else { - mongoc_server_description_reset (copy); - } - - /* Preserve the error */ - memcpy (©->error, &description->error, sizeof copy->error); - return copy; -} - - -/* - *------------------------------------------------------------------------- - * - * mongoc_server_description_filter_stale -- - * - * Estimate servers' staleness according to the Server Selection Spec. - * Determines the number of eligible servers, and sets any servers that - * are too stale to NULL in the descriptions set. - * - *------------------------------------------------------------------------- - */ - -void -mongoc_server_description_filter_stale (mongoc_server_description_t **sds, - size_t sds_len, - mongoc_server_description_t *primary, - int64_t heartbeat_frequency_ms, - const mongoc_read_prefs_t *read_prefs) -{ - int64_t max_staleness_seconds; - size_t i; - - int64_t heartbeat_frequency_usec; - int64_t max_last_write_date_usec; - int64_t staleness_usec; - int64_t max_staleness_usec; - - if (!read_prefs) { - /* NULL read_prefs is PRIMARY, no maxStalenessSeconds to filter by */ - return; - } - - max_staleness_seconds = - mongoc_read_prefs_get_max_staleness_seconds (read_prefs); - - if (max_staleness_seconds == MONGOC_NO_MAX_STALENESS) { - return; - } - - BSON_ASSERT (max_staleness_seconds > 0); - max_staleness_usec = max_staleness_seconds * 1000 * 1000; - heartbeat_frequency_usec = heartbeat_frequency_ms * 1000; - - if (primary) { - for (i = 0; i < sds_len; i++) { - if (!sds[i] || sds[i]->type != MONGOC_SERVER_RS_SECONDARY) { - continue; - } - - /* See max-staleness.rst for explanation of these formulae. */ - staleness_usec = - primary->last_write_date_ms * 1000 + - (sds[i]->last_update_time_usec - primary->last_update_time_usec) - - sds[i]->last_write_date_ms * 1000 + heartbeat_frequency_usec; - - if (staleness_usec > max_staleness_usec) { - TRACE ("Rejected stale RSSecondary [%s]", - sds[i]->host.host_and_port); - sds[i] = NULL; - } - } - } else { - /* find max last_write_date */ - max_last_write_date_usec = 0; - for (i = 0; i < sds_len; i++) { - if (sds[i] && sds[i]->type == MONGOC_SERVER_RS_SECONDARY) { - max_last_write_date_usec = BSON_MAX ( - max_last_write_date_usec, sds[i]->last_write_date_ms * 1000); - } - } - - /* use max last_write_date to estimate each secondary's staleness */ - for (i = 0; i < sds_len; i++) { - if (!sds[i] || sds[i]->type != MONGOC_SERVER_RS_SECONDARY) { - continue; - } - - staleness_usec = max_last_write_date_usec - - sds[i]->last_write_date_ms * 1000 + - heartbeat_frequency_usec; - - if (staleness_usec > max_staleness_usec) { - TRACE ("Rejected stale RSSecondary [%s]", - sds[i]->host.host_and_port); - sds[i] = NULL; - } - } - } -} - - -/* - *------------------------------------------------------------------------- - * - * mongoc_server_description_filter_tags -- - * - * Given a set of server descriptions, set to NULL any that don't - * match the read preference's tag sets. - * - * https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#tag-set - * - *------------------------------------------------------------------------- - */ - -void -mongoc_server_description_filter_tags ( - mongoc_server_description_t **descriptions, - size_t description_len, - const mongoc_read_prefs_t *read_prefs) -{ - const bson_t *rp_tags; - bson_iter_t rp_tagset_iter; - bson_iter_t tag_set_iter; - bool *sd_matched = NULL; - bool found; - size_t i; - - if (!read_prefs) { - /* NULL read_prefs is PRIMARY, no tags to filter by */ - return; - } - - rp_tags = mongoc_read_prefs_get_tags (read_prefs); - - if (bson_count_keys (rp_tags) == 0) { - /* no tags to filter by */ - return; - } - - sd_matched = (bool *) bson_malloc0 (sizeof (bool) * description_len); - - bson_iter_init (&rp_tagset_iter, rp_tags); - - /* for each read preference tag set */ - while (bson_iter_next (&rp_tagset_iter)) { - found = false; - - for (i = 0; i < description_len; i++) { - if (!descriptions[i]) { - /* NULLed earlier in mongoc_topology_description_suitable_servers */ - continue; - } - - BSON_ASSERT (bson_iter_recurse (&rp_tagset_iter, &tag_set_iter)); - sd_matched[i] = _match_tag_set (descriptions[i], &tag_set_iter); - if (sd_matched[i]) { - found = true; - } - } - - if (found) { - for (i = 0; i < description_len; i++) { - if (!sd_matched[i] && descriptions[i]) { - TRACE ("Rejected [%s] [%s], doesn't match tags", - mongoc_server_description_type (descriptions[i]), - descriptions[i]->host.host_and_port); - descriptions[i] = NULL; - } - } - - goto CLEANUP; - } - } - - /* tried each */ - for (i = 0; i < description_len; i++) { - if (!sd_matched[i]) { - TRACE ("Rejected [%s] [%s], reached end of tags array without match", - mongoc_server_description_type (descriptions[i]), - descriptions[i]->host.host_and_port); - - descriptions[i] = NULL; - } - } - -CLEANUP: - bson_free (sd_matched); -} - - -/* - *------------------------------------------------------------------------- - * - * _match_tag_set -- - * - * Check if a server's tags match one tag set, like - * {'tag1': 'value1', 'tag2': 'value2'}. - * - *------------------------------------------------------------------------- - */ -static bool -_match_tag_set (const mongoc_server_description_t *sd, - bson_iter_t *tag_set_iter) -{ - bson_iter_t sd_iter; - uint32_t read_pref_tag_len; - uint32_t sd_len; - const char *read_pref_tag; - const char *read_pref_val; - const char *server_val; - - while (bson_iter_next (tag_set_iter)) { - /* one {'tag': 'value'} pair from the read preference's tag set */ - read_pref_tag = bson_iter_key (tag_set_iter); - read_pref_val = bson_iter_utf8 (tag_set_iter, &read_pref_tag_len); - - if (bson_iter_init_find (&sd_iter, &sd->tags, read_pref_tag)) { - /* The server has this tag - does it have the right value? */ - server_val = bson_iter_utf8 (&sd_iter, &sd_len); - if (sd_len != read_pref_tag_len || - memcmp (read_pref_val, server_val, read_pref_tag_len)) { - /* If the values don't match, no match */ - return false; - } - } else { - /* If the server description doesn't have that key, no match */ - return false; - } - } - - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_description_compressor_id -- - * - * Get the compressor id if compression was negotiated. - * - * Returns: - * The compressor ID, or -1 if none was negotiated. - * - *-------------------------------------------------------------------------- - */ - -int32_t -mongoc_server_description_compressor_id ( - const mongoc_server_description_t *description) -{ - int id; - bson_iter_t iter; - BSON_ASSERT (bson_iter_init (&iter, &description->compressors)); - - while (bson_iter_next (&iter)) { - id = mongoc_compressor_name_to_id (bson_iter_utf8 (&iter, NULL)); - if (id != -1) { - return id; - } - } - - return -1; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description.h deleted file mode 100644 index e644d899815dbf46142b54e203c90bda25e71cbb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-description.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SERVER_DESCRIPTION_H -#define MONGOC_SERVER_DESCRIPTION_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-host-list.h" - -BSON_BEGIN_DECLS - -typedef struct _mongoc_server_description_t mongoc_server_description_t; - -MONGOC_EXPORT (void) -mongoc_server_description_destroy (mongoc_server_description_t *description); - -MONGOC_EXPORT (mongoc_server_description_t *) -mongoc_server_description_new_copy ( - const mongoc_server_description_t *description); - -MONGOC_EXPORT (uint32_t) -mongoc_server_description_id (const mongoc_server_description_t *description); - -MONGOC_EXPORT (mongoc_host_list_t *) -mongoc_server_description_host (const mongoc_server_description_t *description); - -MONGOC_EXPORT (int64_t) -mongoc_server_description_last_update_time ( - const mongoc_server_description_t *description); - -MONGOC_EXPORT (int64_t) -mongoc_server_description_round_trip_time ( - const mongoc_server_description_t *description); - -MONGOC_EXPORT (const char *) -mongoc_server_description_type (const mongoc_server_description_t *description); - -MONGOC_EXPORT (const bson_t *) -mongoc_server_description_ismaster ( - const mongoc_server_description_t *description); - -MONGOC_EXPORT (int32_t) -mongoc_server_description_compressor_id ( - const mongoc_server_description_t *description); - -BSON_END_DECLS - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-stream-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-server-stream-private.h deleted file mode 100644 index 2e9d591e6db70282419f3ab73f7c35ad254857e7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-stream-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SERVER_STREAM_H -#define MONGOC_SERVER_STREAM_H - -#include "mongoc/mongoc-config.h" - -#include <bson/bson.h> - -#include "mongoc/mongoc-topology-description-private.h" -#include "mongoc/mongoc-server-description-private.h" -#include "mongoc/mongoc-stream.h" - -BSON_BEGIN_DECLS - -typedef struct _mongoc_server_stream_t { - mongoc_topology_description_type_t topology_type; - mongoc_server_description_t *sd; /* owned */ - bson_t cluster_time; /* owned */ - mongoc_stream_t *stream; /* borrowed */ -} mongoc_server_stream_t; - - -mongoc_server_stream_t * -mongoc_server_stream_new (const mongoc_topology_description_t *td, - mongoc_server_description_t *sd, - mongoc_stream_t *stream); - -int32_t -mongoc_server_stream_max_bson_obj_size (mongoc_server_stream_t *server_stream); - -int32_t -mongoc_server_stream_max_msg_size (mongoc_server_stream_t *server_stream); - -int32_t -mongoc_server_stream_max_write_batch_size ( - mongoc_server_stream_t *server_stream); - -void -mongoc_server_stream_cleanup (mongoc_server_stream_t *server_stream); - -BSON_END_DECLS - - -#endif /* MONGOC_SERVER_STREAM_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-stream.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-server-stream.c deleted file mode 100644 index d0c095c68f1d2819080f5613409534e30f78a88b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-server-stream.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-server-stream-private.h" -#include "mongoc/mongoc-util-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "server-stream" - -mongoc_server_stream_t * -mongoc_server_stream_new (const mongoc_topology_description_t *td, - mongoc_server_description_t *sd, - mongoc_stream_t *stream) -{ - mongoc_server_stream_t *server_stream; - - BSON_ASSERT (sd); - BSON_ASSERT (stream); - - server_stream = bson_malloc (sizeof (mongoc_server_stream_t)); - server_stream->topology_type = td->type; - bson_copy_to (&td->cluster_time, &server_stream->cluster_time); - server_stream->sd = sd; /* becomes owned */ - server_stream->stream = stream; /* merely borrowed */ - - return server_stream; -} - -void -mongoc_server_stream_cleanup (mongoc_server_stream_t *server_stream) -{ - if (server_stream) { - mongoc_server_description_destroy (server_stream->sd); - bson_destroy (&server_stream->cluster_time); - bson_free (server_stream); - } -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_stream_max_bson_obj_size -- - * - * Return the max bson object size for the given server stream. - * - *-------------------------------------------------------------------------- - */ - -int32_t -mongoc_server_stream_max_bson_obj_size (mongoc_server_stream_t *server_stream) -{ - return COALESCE (server_stream->sd->max_bson_obj_size, - MONGOC_DEFAULT_BSON_OBJ_SIZE); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_stream_max_msg_size -- - * - * Return the max message size for the given server stream. - * - *-------------------------------------------------------------------------- - */ - -int32_t -mongoc_server_stream_max_msg_size (mongoc_server_stream_t *server_stream) -{ - return COALESCE (server_stream->sd->max_msg_size, - MONGOC_DEFAULT_MAX_MSG_SIZE); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_server_stream_max_write_batch_size -- - * - * Return the max write batch size for the given server stream. - * - *-------------------------------------------------------------------------- - */ - -int32_t -mongoc_server_stream_max_write_batch_size ( - mongoc_server_stream_t *server_stream) -{ - return COALESCE (server_stream->sd->max_write_batch_size, - MONGOC_DEFAULT_WRITE_BATCH_SIZE); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-set-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-set-private.h deleted file mode 100644 index f2a334308b8ff5435d3ef5f7a543ba535420a244..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-set-private.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SET_PRIVATE_H -#define MONGOC_SET_PRIVATE_H - -#include <bson/bson.h> - -BSON_BEGIN_DECLS - -typedef void (*mongoc_set_item_dtor) (void *item, void *ctx); - -/* return true to continue iteration, false to stop */ -typedef bool (*mongoc_set_for_each_cb_t) (void *item, void *ctx); -typedef bool (*mongoc_set_for_each_with_id_cb_t) (uint32_t id, - void *item, - void *ctx); - -typedef struct { - uint32_t id; - void *item; -} mongoc_set_item_t; - -typedef struct { - mongoc_set_item_t *items; - size_t items_len; - size_t items_allocated; - mongoc_set_item_dtor dtor; - void *dtor_ctx; -} mongoc_set_t; - -mongoc_set_t * -mongoc_set_new (size_t nitems, mongoc_set_item_dtor dtor, void *dtor_ctx); - -void -mongoc_set_add (mongoc_set_t *set, uint32_t id, void *item); - -void -mongoc_set_rm (mongoc_set_t *set, uint32_t id); - -void * -mongoc_set_get (mongoc_set_t *set, uint32_t id); - -void * -mongoc_set_get_item (mongoc_set_t *set, int idx); - -void * -mongoc_set_get_item_and_id (mongoc_set_t *set, int idx, uint32_t *id /* OUT */); - -void -mongoc_set_destroy (mongoc_set_t *set); - -/* loops over the set safe-ish. - * - * Caveats: - * - you can add items at any iteration - * - if you remove elements other than the one you're currently looking at, - * you may see it later in the iteration - */ -void -mongoc_set_for_each (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx); - -void -mongoc_set_for_each_with_id (mongoc_set_t *set, - mongoc_set_for_each_with_id_cb_t cb, - void *ctx); - -/* first item in set for which "cb" returns true */ -void * -mongoc_set_find_item (mongoc_set_t *set, - mongoc_set_for_each_cb_t cb, - void *ctx); - -/* id of first item in set for which "cb" returns true, or 0. */ -uint32_t -mongoc_set_find_id (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx); - -BSON_END_DECLS - -#endif /* MONGOC_SET_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-set.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-set.c deleted file mode 100644 index aad0cc5f7cccbba74013bc7b47f27c8e1d886e87..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-set.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2014 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 <bson/bson.h> - -#include "mongoc/mongoc-set-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "set" - -mongoc_set_t * -mongoc_set_new (size_t nitems, mongoc_set_item_dtor dtor, void *dtor_ctx) -{ - mongoc_set_t *set = (mongoc_set_t *) bson_malloc (sizeof (*set)); - - set->items_allocated = nitems; - set->items = (mongoc_set_item_t *) bson_malloc (sizeof (*set->items) * - set->items_allocated); - set->items_len = 0; - - set->dtor = dtor; - set->dtor_ctx = dtor_ctx; - - return set; -} - -static int -mongoc_set_id_cmp (const void *a_, const void *b_) -{ - mongoc_set_item_t *a = (mongoc_set_item_t *) a_; - mongoc_set_item_t *b = (mongoc_set_item_t *) b_; - - if (a->id == b->id) { - return 0; - } - - return a->id < b->id ? -1 : 1; -} - -void -mongoc_set_add (mongoc_set_t *set, uint32_t id, void *item) -{ - if (set->items_len >= set->items_allocated) { - set->items_allocated *= 2; - set->items = (mongoc_set_item_t *) bson_realloc ( - set->items, sizeof (*set->items) * set->items_allocated); - } - - set->items[set->items_len].id = id; - set->items[set->items_len].item = item; - - set->items_len++; - - if (set->items_len > 1 && set->items[set->items_len - 2].id > id) { - qsort ( - set->items, set->items_len, sizeof (*set->items), mongoc_set_id_cmp); - } -} - -void -mongoc_set_rm (mongoc_set_t *set, uint32_t id) -{ - mongoc_set_item_t *ptr; - mongoc_set_item_t key; - int i; - - key.id = id; - - ptr = (mongoc_set_item_t *) bsearch ( - &key, set->items, set->items_len, sizeof (key), mongoc_set_id_cmp); - - if (ptr) { - if (set->dtor) { - set->dtor (ptr->item, set->dtor_ctx); - } - - i = ptr - set->items; - - if (i != set->items_len - 1) { - memmove (set->items + i, - set->items + i + 1, - (set->items_len - (i + 1)) * sizeof (key)); - } - - set->items_len--; - } -} - -void * -mongoc_set_get (mongoc_set_t *set, uint32_t id) -{ - mongoc_set_item_t *ptr; - mongoc_set_item_t key; - - key.id = id; - - ptr = (mongoc_set_item_t *) bsearch ( - &key, set->items, set->items_len, sizeof (key), mongoc_set_id_cmp); - - return ptr ? ptr->item : NULL; -} - -void * -mongoc_set_get_item (mongoc_set_t *set, int idx) -{ - BSON_ASSERT (set); - BSON_ASSERT (idx < set->items_len); - - return set->items[idx].item; -} - - -void * -mongoc_set_get_item_and_id (mongoc_set_t *set, int idx, uint32_t *id /* OUT */) -{ - BSON_ASSERT (set); - BSON_ASSERT (id); - BSON_ASSERT (idx < set->items_len); - - *id = set->items[idx].id; - - return set->items[idx].item; -} - - -void -mongoc_set_destroy (mongoc_set_t *set) -{ - int i; - - if (set->dtor) { - for (i = 0; i < set->items_len; i++) { - set->dtor (set->items[i].item, set->dtor_ctx); - } - } - - bson_free (set->items); - bson_free (set); -} - - -typedef struct { - mongoc_set_for_each_cb_t cb; - void *ctx; -} _mongoc_set_for_each_helper_t; - - -static bool -_mongoc_set_for_each_helper (uint32_t id, void *item, void *ctx) -{ - _mongoc_set_for_each_helper_t *helper = - (_mongoc_set_for_each_helper_t *) ctx; - return helper->cb (item, helper->ctx); -} - - -void -mongoc_set_for_each (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx) -{ - _mongoc_set_for_each_helper_t helper; - helper.cb = cb; - helper.ctx = ctx; - - mongoc_set_for_each_with_id (set, _mongoc_set_for_each_helper, &helper); -} - -void -mongoc_set_for_each_with_id (mongoc_set_t *set, - mongoc_set_for_each_with_id_cb_t cb, - void *ctx) -{ - size_t i; - mongoc_set_item_t *old_set; - size_t items_len; - - items_len = set->items_len; - - /* prevent undefined behavior of memcpy(NULL) */ - if (items_len == 0) { - return; - } - - old_set = (mongoc_set_item_t *) bson_malloc (sizeof (*old_set) * items_len); - memcpy (old_set, set->items, sizeof (*old_set) * items_len); - - for (i = 0; i < items_len; i++) { - if (!cb (i, old_set[i].item, ctx)) { - break; - } - } - - bson_free (old_set); -} - - -static mongoc_set_item_t * -_mongoc_set_find (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx) -{ - size_t i; - size_t items_len; - mongoc_set_item_t *item; - - items_len = set->items_len; - - for (i = 0; i < items_len; i++) { - item = &set->items[i]; - if (cb (item->item, ctx)) { - return item; - } - } - - return NULL; -} - - -void * -mongoc_set_find_item (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx) -{ - mongoc_set_item_t *item; - - if ((item = _mongoc_set_find (set, cb, ctx))) { - return item->item; - } - - return NULL; -} - - -uint32_t -mongoc_set_find_id (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx) -{ - mongoc_set_item_t *item; - - if ((item = _mongoc_set_find (set, cb, ctx))) { - return item->id; - } - - return 0; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-socket-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-socket-private.h deleted file mode 100644 index d8f5398b7987954f69860fd2b453083c8fbf1590..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-socket-private.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SOCKET_PRIVATE_H -#define MONGOC_SOCKET_PRIVATE_H - -#include "mongoc/mongoc-socket.h" - -BSON_BEGIN_DECLS - -struct _mongoc_socket_t { -#ifdef _WIN32 - SOCKET sd; -#else - int sd; -#endif - int errno_; - int domain; - int pid; -}; - -mongoc_socket_t * -mongoc_socket_accept_ex (mongoc_socket_t *sock, - int64_t expire_at, - uint16_t *port); - -BSON_END_DECLS - -#endif /* MONGOC_SOCKET_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-socket.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-socket.c deleted file mode 100644 index cebdfdc848e6a5cedaf8b4fa4b78184269dd8cb4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-socket.c +++ /dev/null @@ -1,1569 +0,0 @@ -/* - * Copyright 2014 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 <errno.h> -#include <string.h> - -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-errno-private.h" -#include "mongoc/mongoc-socket-private.h" -#include "mongoc/mongoc-host-list.h" -#include "mongoc/mongoc-socket-private.h" -#include "mongoc/mongoc-trace-private.h" -#ifdef _WIN32 -#include <Mstcpip.h> -#include <process.h> -#endif - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "socket" - - -#define OPERATION_EXPIRED(expire_at) \ - ((expire_at >= 0) && (expire_at < (bson_get_monotonic_time ()))) - - -/* either struct sockaddr or void, depending on platform */ -typedef MONGOC_SOCKET_ARG2 mongoc_sockaddr_t; - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_socket_capture_errno -- - * - * Save the errno state for contextual use. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static void -_mongoc_socket_capture_errno (mongoc_socket_t *sock) /* IN */ -{ -#ifdef _WIN32 - errno = sock->errno_ = WSAGetLastError (); -#else - sock->errno_ = errno; -#endif - TRACE ("setting errno: %d %s", sock->errno_, strerror (sock->errno_)); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_socket_setflags -- - * - * A helper to set socket flags. Sets to nonblocking mode. On - * POSIX sets closeonexec. - * - * - * Returns: - * true if successful; otherwise false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -#ifdef _WIN32 -_mongoc_socket_setflags (SOCKET sd) -#else -_mongoc_socket_setflags (int sd) -#endif -{ -#ifdef _WIN32 - u_long io_mode = 1; - return (NO_ERROR == ioctlsocket (sd, FIONBIO, &io_mode)); -#else - int flags; - - flags = fcntl (sd, F_GETFL, sd); - - if (-1 == fcntl (sd, F_SETFL, (flags | O_NONBLOCK))) { - return false; - } - -#ifdef FD_CLOEXEC - flags = fcntl (sd, F_GETFD, sd); - if (-1 == fcntl (sd, F_SETFD, (flags | FD_CLOEXEC))) { - return false; - } -#endif - return true; -#endif -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_socket_wait -- - * - * A single socket poll helper. - * - * @events: in most cases should be POLLIN or POLLOUT. - * - * @expire_at should be an absolute time at which to expire using - * the monotonic clock (bson_get_monotonic_time(), which is in - * microseconds). Or zero to not block at all. Or -1 to block - * forever. - * - * Returns: - * true if an event matched. otherwise false. - * a timeout will return false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_socket_wait (mongoc_socket_t *sock, /* IN */ - int events, /* IN */ - int64_t expire_at) /* IN */ -{ -#ifdef _WIN32 - fd_set read_fds; - fd_set write_fds; - fd_set error_fds; - struct timeval timeout_tv; -#else - struct pollfd pfd; -#endif - int ret; - int timeout; - int64_t now; - - ENTRY; - - BSON_ASSERT (sock); - BSON_ASSERT (events); - -#ifdef _WIN32 - FD_ZERO (&read_fds); - FD_ZERO (&write_fds); - FD_ZERO (&error_fds); - - if (events & POLLIN) { - FD_SET (sock->sd, &read_fds); - } - - if (events & POLLOUT) { - FD_SET (sock->sd, &write_fds); - } - - FD_SET (sock->sd, &error_fds); -#else - pfd.fd = sock->sd; - pfd.events = events | POLLERR | POLLHUP; - pfd.revents = 0; -#endif - now = bson_get_monotonic_time (); - - for (;;) { - if (expire_at < 0) { - timeout = -1; - } else if (expire_at == 0) { - timeout = 0; - } else { - timeout = (int) ((expire_at - now) / 1000L); - if (timeout < 0) { - timeout = 0; - } - } - -#ifdef _WIN32 - if (timeout == -1) { - /* not WSAPoll: daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken */ - ret = select (0 /*unused*/, &read_fds, &write_fds, &error_fds, NULL); - } else { - timeout_tv.tv_sec = timeout / 1000; - timeout_tv.tv_usec = (timeout % 1000) * 1000; - ret = select ( - 0 /*unused*/, &read_fds, &write_fds, &error_fds, &timeout_tv); - } - if (ret == SOCKET_ERROR) { - _mongoc_socket_capture_errno (sock); - ret = -1; - } else if (FD_ISSET (sock->sd, &error_fds)) { - errno = WSAECONNRESET; - ret = -1; - } -#else - ret = poll (&pfd, 1, timeout); -#endif - - if (ret > 0) { -/* Something happened, so return that */ -#ifdef _WIN32 - return (FD_ISSET (sock->sd, &read_fds) || - FD_ISSET (sock->sd, &write_fds)); -#else - RETURN (0 != (pfd.revents & events)); -#endif - } else if (ret < 0) { - /* poll itself failed */ - - TRACE ("errno is: %d", errno); - if (MONGOC_ERRNO_IS_AGAIN (errno)) { - if (OPERATION_EXPIRED (expire_at)) { - _mongoc_socket_capture_errno (sock); - RETURN (false); - } else { - continue; - } - } else { - /* poll failed for some non-transient reason */ - _mongoc_socket_capture_errno (sock); - RETURN (false); - } - } else { - /* ret == 0, poll timed out */ - if (timeout) { - mongoc_counter_streams_timeout_inc (); - } -#ifdef _WIN32 - sock->errno_ = timeout ? WSAETIMEDOUT : EAGAIN; -#else - sock->errno_ = timeout ? ETIMEDOUT : EAGAIN; -#endif - RETURN (false); - } - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_poll -- - * - * A multi-socket poll helper. - * - * @expire_at should be an absolute time at which to expire using - * the monotonic clock (bson_get_monotonic_time(), which is in - * microseconds). Or zero to not block at all. Or -1 to block - * forever. - * - * Returns: - * The number of sockets ready. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -ssize_t -mongoc_socket_poll (mongoc_socket_poll_t *sds, /* IN */ - size_t nsds, /* IN */ - int32_t timeout) /* IN */ -{ -#ifdef _WIN32 - fd_set read_fds; - fd_set write_fds; - fd_set error_fds; - struct timeval timeout_tv; -#else - struct pollfd *pfds; -#endif - int ret; - int i; - - ENTRY; - - BSON_ASSERT (sds); - -#ifdef _WIN32 - FD_ZERO (&read_fds); - FD_ZERO (&write_fds); - FD_ZERO (&error_fds); - - for (i = 0; i < nsds; i++) { - if (sds[i].events & POLLIN) { - FD_SET (sds[i].socket->sd, &read_fds); - } - - if (sds[i].events & POLLOUT) { - FD_SET (sds[i].socket->sd, &write_fds); - } - - FD_SET (sds[i].socket->sd, &error_fds); - } - - timeout_tv.tv_sec = timeout / 1000; - timeout_tv.tv_usec = (timeout % 1000) * 1000; - - /* not WSAPoll: daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken */ - ret = select (0 /*unused*/, &read_fds, &write_fds, &error_fds, &timeout_tv); - if (ret == SOCKET_ERROR) { - errno = WSAGetLastError (); - return -1; - } - - for (i = 0; i < nsds; i++) { - if (FD_ISSET (sds[i].socket->sd, &read_fds)) { - sds[i].revents = POLLIN; - } else if (FD_ISSET (sds[i].socket->sd, &write_fds)) { - sds[i].revents = POLLOUT; - } else if (FD_ISSET (sds[i].socket->sd, &error_fds)) { - sds[i].revents = POLLHUP; - } else { - sds[i].revents = 0; - } - } -#else - pfds = (struct pollfd *) bson_malloc (sizeof (*pfds) * nsds); - - for (i = 0; i < nsds; i++) { - pfds[i].fd = sds[i].socket->sd; - pfds[i].events = sds[i].events | POLLERR | POLLHUP; - pfds[i].revents = 0; - } - - ret = poll (pfds, nsds, timeout); - for (i = 0; i < nsds; i++) { - sds[i].revents = pfds[i].revents; - } - - bson_free (pfds); -#endif - - return ret; -} - - -/* https://jira.mongodb.org/browse/CDRIVER-2176 */ -#define MONGODB_KEEPALIVEINTVL 10 -#define MONGODB_KEEPIDLE 300 -#define MONGODB_KEEPALIVECNT 9 - -#ifdef _WIN32 -static void -_mongoc_socket_setkeepalive_windows (SOCKET sd) -{ - struct tcp_keepalive keepalive; - DWORD lpcbBytesReturned = 0; - HKEY hKey; - DWORD type; - DWORD data; - DWORD data_size = sizeof data; - const char *reg_key = - "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"; - keepalive.onoff = true; - keepalive.keepalivetime = MONGODB_KEEPIDLE * 1000; - keepalive.keepaliveinterval = MONGODB_KEEPALIVEINTVL * 1000; - /* - * Windows hardcodes probes to 10: - * https://msdn.microsoft.com/en-us/library/windows/desktop/dd877220(v=vs.85).aspx - * "On Windows Vista and later, the number of keep-alive probes (data - * retransmissions) is set to 10 and cannot be changed." - * - * Note that win2k (and seeminly all versions thereafter) do not set the - * registry value by default so there is no way to derive the default value - * programmatically. It is however listed in the docs. A user can however - * change the default value by setting the registry values. - */ - - if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, reg_key, 0, KEY_QUERY_VALUE, &hKey) == - ERROR_SUCCESS) { - /* https://technet.microsoft.com/en-us/library/cc957549.aspx */ - DWORD default_keepalivetime = 7200000; /* 2 hours */ - /* https://technet.microsoft.com/en-us/library/cc957548.aspx */ - DWORD default_keepaliveinterval = 1000; /* 1 second */ - - if (RegQueryValueEx ( - hKey, "KeepAliveTime", NULL, &type, (LPBYTE) &data, &data_size) == - ERROR_SUCCESS) { - if (type == REG_DWORD && data < keepalive.keepalivetime) { - keepalive.keepalivetime = data; - } - } else if (default_keepalivetime < keepalive.keepalivetime) { - keepalive.keepalivetime = default_keepalivetime; - } - - if (RegQueryValueEx (hKey, - "KeepAliveInterval", - NULL, - &type, - (LPBYTE) &data, - &data_size) == ERROR_SUCCESS) { - if (type == REG_DWORD && data < keepalive.keepaliveinterval) { - keepalive.keepaliveinterval = data; - } - } else if (default_keepaliveinterval < keepalive.keepaliveinterval) { - keepalive.keepaliveinterval = default_keepaliveinterval; - } - RegCloseKey (hKey); - } - if (WSAIoctl (sd, - SIO_KEEPALIVE_VALS, - &keepalive, - sizeof keepalive, - NULL, - 0, - &lpcbBytesReturned, - NULL, - NULL) == SOCKET_ERROR) { - TRACE ("%s", "Could not set keepalive values"); - } else { - TRACE ("%s", "KeepAlive values updated"); - TRACE ("KeepAliveTime: %d", keepalive.keepalivetime); - TRACE ("KeepAliveInterval: %d", keepalive.keepaliveinterval); - } -} -#else -#ifdef MONGOC_TRACE -static const char * -_mongoc_socket_sockopt_value_to_name (int value) -{ - switch (value) { -#ifdef TCP_KEEPIDLE - case TCP_KEEPIDLE: - return "TCP_KEEPIDLE"; -#endif -#ifdef TCP_KEEPALIVE - case TCP_KEEPALIVE: - return "TCP_KEEPALIVE"; -#endif -#ifdef TCP_KEEPINTVL - case TCP_KEEPINTVL: - return "TCP_KEEPINTVL"; -#endif -#ifdef TCP_KEEPCNT - case TCP_KEEPCNT: - return "TCP_KEEPCNT"; -#endif - default: - MONGOC_WARNING ("Don't know what socketopt %d is", value); - return "Unknown option name"; - } -} -#endif -static void -_mongoc_socket_set_sockopt_if_less (int sd, int name, int value) -{ - int optval = 1; - mongoc_socklen_t optlen; - - optlen = sizeof optval; - if (getsockopt (sd, IPPROTO_TCP, name, (char *) &optval, &optlen)) { - TRACE ("Getting '%s' failed, errno: %d", - _mongoc_socket_sockopt_value_to_name (name), - errno); - } else { - TRACE ("'%s' is %d, target value is %d", - _mongoc_socket_sockopt_value_to_name (name), - optval, - value); - if (optval > value) { - optval = value; - if (setsockopt ( - sd, IPPROTO_TCP, name, (char *) &optval, sizeof optval)) { - TRACE ("Setting '%s' failed, errno: %d", - _mongoc_socket_sockopt_value_to_name (name), - errno); - } else { - TRACE ("'%s' value changed to %d", - _mongoc_socket_sockopt_value_to_name (name), - optval); - } - } - } -} - -static void -_mongoc_socket_setkeepalive_nix (int sd) -{ -#if defined(TCP_KEEPIDLE) - _mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPIDLE, MONGODB_KEEPIDLE); -#elif defined(TCP_KEEPALIVE) - _mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPALIVE, MONGODB_KEEPIDLE); -#else - TRACE ("%s", "Neither TCP_KEEPIDLE nor TCP_KEEPALIVE available"); -#endif - -#ifdef TCP_KEEPINTVL - _mongoc_socket_set_sockopt_if_less ( - sd, TCP_KEEPINTVL, MONGODB_KEEPALIVEINTVL); -#else - TRACE ("%s", "TCP_KEEPINTVL not available"); -#endif - -#ifdef TCP_KEEPCNT - _mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPCNT, MONGODB_KEEPALIVECNT); -#else - TRACE ("%s", "TCP_KEEPCNT not available"); -#endif -} - -#endif -static void -#ifdef _WIN32 -_mongoc_socket_setkeepalive (SOCKET sd) /* IN */ -#else -_mongoc_socket_setkeepalive (int sd) /* IN */ -#endif -{ -#ifdef SO_KEEPALIVE - int optval = 1; - - ENTRY; -#ifdef SO_KEEPALIVE - if (!setsockopt ( - sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof optval)) { - TRACE ("%s", "Setting SO_KEEPALIVE"); -#ifdef _WIN32 - _mongoc_socket_setkeepalive_windows (sd); -#else - _mongoc_socket_setkeepalive_nix (sd); -#endif - } else { - TRACE ("%s", "Failed setting SO_KEEPALIVE"); - } -#else - TRACE ("%s", "SO_KEEPALIVE not available"); -#endif - EXIT; -#endif -} - - -static bool -#ifdef _WIN32 -_mongoc_socket_setnodelay (SOCKET sd) /* IN */ -#else -_mongoc_socket_setnodelay (int sd) /* IN */ -#endif -{ -#ifdef _WIN32 - BOOL optval = 1; -#else - int optval = 1; -#endif - int ret; - - ENTRY; - - errno = 0; - ret = setsockopt ( - sd, IPPROTO_TCP, TCP_NODELAY, (char *) &optval, sizeof optval); - -#ifdef _WIN32 - if (ret == SOCKET_ERROR) { - MONGOC_WARNING ("WSAGetLastError(): %d", (int) WSAGetLastError ()); - } -#endif - - RETURN (ret == 0); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_errno -- - * - * Returns the last error on the socket. - * - * Returns: - * An integer errno, or 0 on no error. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_socket_errno (mongoc_socket_t *sock) /* IN */ -{ - BSON_ASSERT (sock); - TRACE ("Current errno: %d", sock->errno_); - return sock->errno_; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_socket_errno_is_again -- - * - * Check to see if we should attempt to make further progress - * based on the error of the last operation. - * - * Returns: - * true if we should try again. otherwise false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_socket_errno_is_again (mongoc_socket_t *sock) /* IN */ -{ - TRACE ("errno is: %d", sock->errno_); - return MONGOC_ERRNO_IS_AGAIN (sock->errno_); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_accept -- - * - * Wrapper for BSD socket accept(). Handles portability between - * BSD sockets and WinSock2 on Windows Vista and newer. - * - * Returns: - * NULL upon failure to accept or timeout. - * A newly allocated mongoc_socket_t on success. - * - * Side effects: - * *port contains the client port number. - * - *-------------------------------------------------------------------------- - */ - -mongoc_socket_t * -mongoc_socket_accept (mongoc_socket_t *sock, /* IN */ - int64_t expire_at) /* IN */ -{ - return mongoc_socket_accept_ex (sock, expire_at, NULL); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_accept_ex -- - * - * Private synonym for mongoc_socket_accept, returning client port. - * - * Returns: - * NULL upon failure to accept or timeout. - * A newly allocated mongoc_socket_t on success. - * - * Side effects: - * *port contains the client port number. - * - *-------------------------------------------------------------------------- - */ - -mongoc_socket_t * -mongoc_socket_accept_ex (mongoc_socket_t *sock, /* IN */ - int64_t expire_at, /* IN */ - uint16_t *port) /* OUT */ -{ - mongoc_socket_t *client; - struct sockaddr_storage addr = {0}; - mongoc_socklen_t addrlen = sizeof addr; - bool try_again = false; - bool failed = false; -#ifdef _WIN32 - SOCKET sd; -#else - int sd; -#endif - - ENTRY; - - BSON_ASSERT (sock); - -again: - errno = 0; - sd = accept (sock->sd, (mongoc_sockaddr_t *) &addr, &addrlen); - - _mongoc_socket_capture_errno (sock); -#ifdef _WIN32 - failed = (sd == INVALID_SOCKET); -#else - failed = (sd == -1); -#endif - try_again = (failed && _mongoc_socket_errno_is_again (sock)); - - if (failed && try_again) { - if (_mongoc_socket_wait (sock, POLLIN, expire_at)) { - GOTO (again); - } - RETURN (NULL); - } else if (failed) { - RETURN (NULL); - } else if (!_mongoc_socket_setflags (sd)) { -#ifdef _WIN32 - closesocket (sd); -#else - close (sd); -#endif - RETURN (NULL); - } - - client = (mongoc_socket_t *) bson_malloc0 (sizeof *client); - client->sd = sd; - - if (port) { - if (addr.ss_family == AF_INET) { - struct sockaddr_in *tmp = (struct sockaddr_in *) &addr; - *port = ntohs (tmp->sin_port); - } else { - struct sockaddr_in6 *tmp = (struct sockaddr_in6 *) &addr; - *port = ntohs (tmp->sin6_port); - } - } - - if (!_mongoc_socket_setnodelay (client->sd)) { - MONGOC_WARNING ("Failed to enable TCP_NODELAY."); - } - - RETURN (client); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongo_socket_bind -- - * - * A wrapper around bind(). - * - * Returns: - * 0 on success, -1 on failure and errno is set. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_socket_bind (mongoc_socket_t *sock, /* IN */ - const struct sockaddr *addr, /* IN */ - mongoc_socklen_t addrlen) /* IN */ -{ - int ret; - - ENTRY; - - BSON_ASSERT (sock); - BSON_ASSERT (addr); - BSON_ASSERT (addrlen); - - ret = bind (sock->sd, addr, addrlen); - - _mongoc_socket_capture_errno (sock); - - RETURN (ret); -} - - -int -mongoc_socket_close (mongoc_socket_t *sock) /* IN */ -{ - bool owned; - - ENTRY; - - BSON_ASSERT (sock); - -#ifdef _WIN32 - owned = (sock->pid == (int) _getpid ()); - - if (sock->sd != INVALID_SOCKET) { - if (owned) { - shutdown (sock->sd, SD_BOTH); - } - - if (0 == closesocket (sock->sd)) { - sock->sd = INVALID_SOCKET; - } else { - _mongoc_socket_capture_errno (sock); - RETURN (-1); - } - } - RETURN (0); -#else - owned = (sock->pid == (int) getpid ()); - - if (sock->sd != -1) { - if (owned) { - shutdown (sock->sd, SHUT_RDWR); - } - - if (0 == close (sock->sd)) { - sock->sd = -1; - } else { - _mongoc_socket_capture_errno (sock); - RETURN (-1); - } - } - RETURN (0); -#endif -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_connect -- - * - * Performs a socket connection but will fail if @expire_at is - * reached by the monotonic clock. - * - * Returns: - * 0 if success, otherwise -1 and errno is set. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_socket_connect (mongoc_socket_t *sock, /* IN */ - const struct sockaddr *addr, /* IN */ - mongoc_socklen_t addrlen, /* IN */ - int64_t expire_at) /* IN */ -{ - bool try_again = false; - bool failed = false; - int ret; - int optval; - /* getsockopt parameter types vary, we check in CheckCompiler.m4 */ - mongoc_socklen_t optlen = (mongoc_socklen_t) sizeof optval; - - ENTRY; - - BSON_ASSERT (sock); - BSON_ASSERT (addr); - BSON_ASSERT (addrlen); - - ret = connect (sock->sd, addr, addrlen); - -#ifdef _WIN32 - if (ret == SOCKET_ERROR) { -#else - if (ret == -1) { -#endif - _mongoc_socket_capture_errno (sock); - - failed = true; - try_again = _mongoc_socket_errno_is_again (sock); - } - - if (failed && try_again) { - if (_mongoc_socket_wait (sock, POLLOUT, expire_at)) { - optval = -1; - ret = getsockopt ( - sock->sd, SOL_SOCKET, SO_ERROR, (char *) &optval, &optlen); - if ((ret == 0) && (optval == 0)) { - RETURN (0); - } else { - errno = sock->errno_ = optval; - } - } - RETURN (-1); - } else if (failed) { - RETURN (-1); - } else { - RETURN (0); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_destroy -- - * - * Cleanup after a mongoc_socket_t structure, possibly closing - * underlying sockets. - * - * Returns: - * None. - * - * Side effects: - * @sock is freed and should be considered invalid. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_socket_destroy (mongoc_socket_t *sock) /* IN */ -{ - if (sock) { - mongoc_socket_close (sock); - bson_free (sock); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_listen -- - * - * Listen for incoming requests with a backlog up to @backlog. - * - * If @backlog is zero, a sensible default will be chosen. - * - * Returns: - * true if successful; otherwise false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_socket_listen (mongoc_socket_t *sock, /* IN */ - unsigned int backlog) /* IN */ -{ - int ret; - - ENTRY; - - BSON_ASSERT (sock); - - if (backlog == 0) { - backlog = 10; - } - - ret = listen (sock->sd, backlog); - - _mongoc_socket_capture_errno (sock); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_new -- - * - * Create a new socket and store the current process id on it. - * - * Free the result with mongoc_socket_destroy(). - * - * Returns: - * A newly allocated socket. - * NULL on failure. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_socket_t * -mongoc_socket_new (int domain, /* IN */ - int type, /* IN */ - int protocol) /* IN */ -{ - mongoc_socket_t *sock; -#ifdef _WIN32 - SOCKET sd; -#else - int sd; -#endif - - ENTRY; - - sd = socket (domain, type, protocol); - -#ifdef _WIN32 - if (sd == INVALID_SOCKET) { -#else - if (sd == -1) { -#endif - RETURN (NULL); - } - - if (!_mongoc_socket_setflags (sd)) { - GOTO (fail); - } - - if (domain != AF_UNIX) { - if (!_mongoc_socket_setnodelay (sd)) { - MONGOC_WARNING ("Failed to enable TCP_NODELAY."); - } - _mongoc_socket_setkeepalive (sd); - } - - sock = (mongoc_socket_t *) bson_malloc0 (sizeof *sock); - sock->sd = sd; - sock->domain = domain; -#ifdef _WIN32 - sock->pid = (int) _getpid (); -#else - sock->pid = (int) getpid (); -#endif - - RETURN (sock); - -fail: -#ifdef _WIN32 - closesocket (sd); -#else - close (sd); -#endif - - RETURN (NULL); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_recv -- - * - * A portable wrapper around recv() that also respects an absolute - * timeout. - * - * @expire_at is 0 for no blocking, -1 for infinite blocking, - * or a time using the monotonic clock to expire. Calculate this - * using bson_get_monotonic_time() + N_MICROSECONDS. - * - * Returns: - * The number of bytes received on success. - * 0 on end of stream. - * -1 on failure. - * - * Side effects: - * @buf will be read into. - * - *-------------------------------------------------------------------------- - */ - -ssize_t -mongoc_socket_recv (mongoc_socket_t *sock, /* IN */ - void *buf, /* OUT */ - size_t buflen, /* IN */ - int flags, /* IN */ - int64_t expire_at) /* IN */ -{ - ssize_t ret = 0; - bool failed = false; - - ENTRY; - - BSON_ASSERT (sock); - BSON_ASSERT (buf); - BSON_ASSERT (buflen); - -again: - sock->errno_ = 0; -#ifdef _WIN32 - ret = recv (sock->sd, (char *) buf, (int) buflen, flags); - failed = (ret == SOCKET_ERROR); -#else - ret = recv (sock->sd, buf, buflen, flags); - failed = (ret == -1); -#endif - if (failed) { - _mongoc_socket_capture_errno (sock); - if (_mongoc_socket_errno_is_again (sock) && - _mongoc_socket_wait (sock, POLLIN, expire_at)) { - GOTO (again); - } - } - - if (failed) { - RETURN (-1); - } - - mongoc_counter_streams_ingress_add (ret); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_setsockopt -- - * - * A wrapper around setsockopt(). - * - * Returns: - * 0 on success, -1 on failure. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_socket_setsockopt (mongoc_socket_t *sock, /* IN */ - int level, /* IN */ - int optname, /* IN */ - const void *optval, /* IN */ - mongoc_socklen_t optlen) /* IN */ -{ - int ret; - - ENTRY; - - BSON_ASSERT (sock); - - ret = setsockopt (sock->sd, level, optname, optval, optlen); - - _mongoc_socket_capture_errno (sock); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_send -- - * - * A simplified wrapper around mongoc_socket_sendv(). - * - * @expire_at is 0 for no blocking, -1 for infinite blocking, - * or a time using the monotonic clock to expire. Calculate this - * using bson_get_monotonic_time() + N_MICROSECONDS. - * - * Returns: - * -1 on failure. number of bytes written on success. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -ssize_t -mongoc_socket_send (mongoc_socket_t *sock, /* IN */ - const void *buf, /* IN */ - size_t buflen, /* IN */ - int64_t expire_at) /* IN */ -{ - mongoc_iovec_t iov; - - BSON_ASSERT (sock); - BSON_ASSERT (buf); - BSON_ASSERT (buflen); - - iov.iov_base = (void *) buf; - iov.iov_len = buflen; - - return mongoc_socket_sendv (sock, &iov, 1, expire_at); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_socket_try_sendv_slow -- - * - * A slow variant of _mongoc_socket_try_sendv() that sends each - * iovec entry one by one. This can happen if we hit EMSGSIZE - * with sendmsg() on various POSIX systems or WSASend()+WSAEMSGSIZE - * on Windows. - * - * Returns: - * the number of bytes sent or -1 and errno is set. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static ssize_t -_mongoc_socket_try_sendv_slow (mongoc_socket_t *sock, /* IN */ - mongoc_iovec_t *iov, /* IN */ - size_t iovcnt) /* IN */ -{ - ssize_t ret = 0; - size_t i; - ssize_t wrote; - - ENTRY; - - BSON_ASSERT (sock); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - for (i = 0; i < iovcnt; i++) { - wrote = send (sock->sd, iov[i].iov_base, iov[i].iov_len, 0); -#ifdef _WIN32 - if (wrote == SOCKET_ERROR) { -#else - if (wrote == -1) { -#endif - _mongoc_socket_capture_errno (sock); - - if (!_mongoc_socket_errno_is_again (sock)) { - RETURN (-1); - } - RETURN (ret ? ret : -1); - } - - ret += wrote; - - if (wrote != iov[i].iov_len) { - RETURN (ret); - } - } - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_socket_try_sendv -- - * - * Helper used by mongoc_socket_sendv() to try to write as many - * bytes to the underlying socket until the socket buffer is full. - * - * This is performed in a non-blocking fashion. - * - * Returns: - * -1 on failure. the number of bytes written on success. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static ssize_t -_mongoc_socket_try_sendv (mongoc_socket_t *sock, /* IN */ - mongoc_iovec_t *iov, /* IN */ - size_t iovcnt) /* IN */ -{ -#ifdef _WIN32 - DWORD dwNumberofBytesSent = 0; - int ret; -#else - struct msghdr msg; - ssize_t ret; -#endif - - ENTRY; - - BSON_ASSERT (sock); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - DUMP_IOVEC (sendbuf, iov, iovcnt); - -#ifdef _WIN32 - ret = WSASend ( - sock->sd, (LPWSABUF) iov, iovcnt, &dwNumberofBytesSent, 0, NULL, NULL); - TRACE ("WSASend sent: %ld (out of: %ld), ret: %d", - dwNumberofBytesSent, - iov->iov_len, - ret); -#else - memset (&msg, 0, sizeof msg); - msg.msg_iov = iov; - msg.msg_iovlen = (int) iovcnt; - ret = sendmsg (sock->sd, - &msg, -#ifdef MSG_NOSIGNAL - MSG_NOSIGNAL); -#else - 0); -#endif - TRACE ("Send %ld out of %ld bytes", ret, iov->iov_len); -#endif - - -#ifdef _WIN32 - if (ret == SOCKET_ERROR) { -#else - if (ret == -1) { -#endif - _mongoc_socket_capture_errno (sock); - -/* - * Check to see if we have sent an iovec too large for sendmsg to - * complete. If so, we need to fallback to the slow path of multiple - * send() commands. - */ -#ifdef _WIN32 - if (mongoc_socket_errno (sock) == WSAEMSGSIZE) { -#else - if (mongoc_socket_errno (sock) == EMSGSIZE) { -#endif - RETURN (_mongoc_socket_try_sendv_slow (sock, iov, iovcnt)); - } - - RETURN (-1); - } - -#ifdef _WIN32 - RETURN (dwNumberofBytesSent); -#else - RETURN (ret); -#endif -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_socket_sendv -- - * - * A wrapper around using sendmsg() to send an iovec. - * This also deals with the structure differences between - * WSABUF and struct iovec. - * - * @expire_at is 0 for no blocking, -1 for infinite blocking, - * or a time using the monotonic clock to expire. Calculate this - * using bson_get_monotonic_time() + N_MICROSECONDS. - * - * Returns: - * -1 on failure. - * the number of bytes written on success. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -ssize_t -mongoc_socket_sendv (mongoc_socket_t *sock, /* IN */ - mongoc_iovec_t *in_iov, /* IN */ - size_t iovcnt, /* IN */ - int64_t expire_at) /* IN */ -{ - ssize_t ret = 0; - ssize_t sent; - size_t cur = 0; - mongoc_iovec_t *iov; - - ENTRY; - - BSON_ASSERT (sock); - BSON_ASSERT (in_iov); - BSON_ASSERT (iovcnt); - - iov = bson_malloc (sizeof (*iov) * iovcnt); - memcpy (iov, in_iov, sizeof (*iov) * iovcnt); - - for (;;) { - sent = _mongoc_socket_try_sendv (sock, &iov[cur], iovcnt - cur); - TRACE ( - "Sent %ld (of %ld) out of iovcnt=%ld", sent, iov[cur].iov_len, iovcnt); - - /* - * If we failed with anything other than EAGAIN or EWOULDBLOCK, - * we should fail immediately as there is another issue with the - * underlying socket. - */ - if (sent == -1) { - if (!_mongoc_socket_errno_is_again (sock)) { - ret = -1; - GOTO (CLEANUP); - } - } - - /* - * Update internal stream counters. - */ - if (sent > 0) { - ret += sent; - mongoc_counter_streams_egress_add (sent); - - /* - * Subtract the sent amount from what we still need to send. - */ - while ((cur < iovcnt) && (sent >= (ssize_t) iov[cur].iov_len)) { - TRACE ("still got bytes left: sent -= iov_len: %ld -= %ld", - sent, - iov[cur].iov_len); - sent -= iov[cur++].iov_len; - } - - /* - * Check if that made us finish all of the iovecs. If so, we are done - * sending data over the socket. - */ - if (cur == iovcnt) { - TRACE ("%s", "Finished the iovecs"); - break; - } - - /* - * Increment the current iovec buffer to its proper offset and adjust - * the number of bytes to write. - */ - TRACE ("Seeked io_base+%ld", sent); - TRACE ( - "Subtracting iov_len -= sent; %ld -= %ld", iov[cur].iov_len, sent); - iov[cur].iov_base = ((char *) iov[cur].iov_base) + sent; - iov[cur].iov_len -= sent; - TRACE ("iov_len remaining %ld", iov[cur].iov_len); - - BSON_ASSERT (iovcnt - cur); - BSON_ASSERT (iov[cur].iov_len); - } else if (OPERATION_EXPIRED (expire_at)) { - if (expire_at > 0) { - mongoc_counter_streams_timeout_inc (); - } - GOTO (CLEANUP); - } - - /* - * Block on poll() until our desired condition is met. - */ - if (!_mongoc_socket_wait (sock, POLLOUT, expire_at)) { - GOTO (CLEANUP); - } - } - -CLEANUP: - bson_free (iov); - - RETURN (ret); -} - - -int -mongoc_socket_getsockname (mongoc_socket_t *sock, /* IN */ - struct sockaddr *addr, /* OUT */ - mongoc_socklen_t *addrlen) /* INOUT */ -{ - int ret; - - ENTRY; - - BSON_ASSERT (sock); - - ret = getsockname (sock->sd, addr, addrlen); - - _mongoc_socket_capture_errno (sock); - - RETURN (ret); -} - - -char * -mongoc_socket_getnameinfo (mongoc_socket_t *sock) /* IN */ -{ - /* getpeername parameter types vary, we check in CheckCompiler.m4 */ - struct sockaddr_storage addr; - mongoc_socklen_t len = (mongoc_socklen_t) sizeof addr; - char *ret; - char host[BSON_HOST_NAME_MAX + 1]; - - ENTRY; - - BSON_ASSERT (sock); - - if (getpeername (sock->sd, (struct sockaddr *) &addr, &len)) { - RETURN (NULL); - } - - if (getnameinfo ( - (struct sockaddr *) &addr, len, host, sizeof host, NULL, 0, 0)) { - RETURN (NULL); - } - - ret = bson_strdup (host); - RETURN (ret); -} - - -bool -mongoc_socket_check_closed (mongoc_socket_t *sock) /* IN */ -{ - bool closed = false; - char buf[1]; - ssize_t r; - - if (_mongoc_socket_wait (sock, POLLIN, 0)) { - sock->errno_ = 0; - - r = recv (sock->sd, buf, 1, MSG_PEEK); - - if (r < 0) { - _mongoc_socket_capture_errno (sock); - } - - if (r < 1) { - closed = true; - } - } - - return closed; -} - -/* - * - *-------------------------------------------------------------------------- - * - * mongoc_socket_inet_ntop -- - * - * Convert the ip from addrinfo into a c string. - * - * Returns: - * The value is returned into 'buffer'. The memory has to be allocated - * by the caller - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_socket_inet_ntop (struct addrinfo *rp, /* IN */ - char *buf, /* INOUT */ - size_t buflen) /* IN */ -{ - void *ptr; - char tmp[256]; - - switch (rp->ai_family) { - case AF_INET: - ptr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr; - inet_ntop (rp->ai_family, ptr, tmp, sizeof (tmp)); - bson_snprintf (buf, buflen, "ipv4 %s", tmp); - break; - case AF_INET6: - ptr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr; - inet_ntop (rp->ai_family, ptr, tmp, sizeof (tmp)); - bson_snprintf (buf, buflen, "ipv6 %s", tmp); - break; - default: - bson_snprintf (buf, buflen, "unknown ip %d", rp->ai_family); - break; - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-socket.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-socket.h deleted file mode 100644 index 41f3a92a456ba72fbc4f4c682b3ae9ff0202ff0f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-socket.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SOCKET_H -#define MONGOC_SOCKET_H - -#include <bson/bson.h> -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-config.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#else -#include <arpa/inet.h> -#include <poll.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/un.h> -#endif - -#if defined(_AIX) && !defined(HAVE_SA_SS_FAMILY) -# define ss_family __ss_family -#endif - -#include "mongoc/mongoc-iovec.h" - - -BSON_BEGIN_DECLS - - -typedef MONGOC_SOCKET_ARG3 mongoc_socklen_t; - -typedef struct _mongoc_socket_t mongoc_socket_t; - -typedef struct { - mongoc_socket_t *socket; - int events; - int revents; -} mongoc_socket_poll_t; - -MONGOC_EXPORT (mongoc_socket_t *) -mongoc_socket_accept (mongoc_socket_t *sock, int64_t expire_at); -MONGOC_EXPORT (int) -mongoc_socket_bind (mongoc_socket_t *sock, - const struct sockaddr *addr, - mongoc_socklen_t addrlen); -MONGOC_EXPORT (int) -mongoc_socket_close (mongoc_socket_t *socket); -MONGOC_EXPORT (int) -mongoc_socket_connect (mongoc_socket_t *sock, - const struct sockaddr *addr, - mongoc_socklen_t addrlen, - int64_t expire_at); -MONGOC_EXPORT (char *) -mongoc_socket_getnameinfo (mongoc_socket_t *sock); -MONGOC_EXPORT (void) -mongoc_socket_destroy (mongoc_socket_t *sock); -MONGOC_EXPORT (int) -mongoc_socket_errno (mongoc_socket_t *sock); -MONGOC_EXPORT (int) -mongoc_socket_getsockname (mongoc_socket_t *sock, - struct sockaddr *addr, - mongoc_socklen_t *addrlen); -MONGOC_EXPORT (int) -mongoc_socket_listen (mongoc_socket_t *sock, unsigned int backlog); -MONGOC_EXPORT (mongoc_socket_t *) -mongoc_socket_new (int domain, int type, int protocol); -MONGOC_EXPORT (ssize_t) -mongoc_socket_recv (mongoc_socket_t *sock, - void *buf, - size_t buflen, - int flags, - int64_t expire_at); -MONGOC_EXPORT (int) -mongoc_socket_setsockopt (mongoc_socket_t *sock, - int level, - int optname, - const void *optval, - mongoc_socklen_t optlen); -MONGOC_EXPORT (ssize_t) -mongoc_socket_send (mongoc_socket_t *sock, - const void *buf, - size_t buflen, - int64_t expire_at); -MONGOC_EXPORT (ssize_t) -mongoc_socket_sendv (mongoc_socket_t *sock, - mongoc_iovec_t *iov, - size_t iovcnt, - int64_t expire_at); -MONGOC_EXPORT (bool) -mongoc_socket_check_closed (mongoc_socket_t *sock); -MONGOC_EXPORT (void) -mongoc_socket_inet_ntop (struct addrinfo *rp, char *buf, size_t buflen); -MONGOC_EXPORT (ssize_t) -mongoc_socket_poll (mongoc_socket_poll_t *sds, size_t nsds, int32_t timeout); - - -BSON_END_DECLS - - -#endif /* MONGOC_SOCKET_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl-private.h deleted file mode 100644 index d404614642da02582b8a31ed67aea7d02e780bbe..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SSL_PRIVATE_H -#define MONGOC_SSL_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-uri-private.h" - - -BSON_BEGIN_DECLS - - -char * -mongoc_ssl_extract_subject (const char *filename, const char *passphrase); - -void -_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt, mongoc_uri_t *uri); -void -_mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src, mongoc_ssl_opt_t *dst); -void -_mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt); - -BSON_END_DECLS - - -#endif /* MONGOC_SSL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl.c deleted file mode 100644 index 4dc7b3f624b78c0df7685e93c72b2da888683efd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL - -#include <bson/bson.h> -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-ssl-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-uri.h" - -#if defined(MONGOC_ENABLE_SSL_OPENSSL) -#include "mongoc/mongoc-openssl-private.h" -#elif defined(MONGOC_ENABLE_SSL_LIBRESSL) -#include "mongoc/mongoc-libressl-private.h" -#elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) -#include "mongoc/mongoc-secure-transport-private.h" -#elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) -#include "mongoc/mongoc-secure-channel-private.h" -#endif - -/* TODO: we could populate these from a config or something further down the - * road for providing defaults */ -#ifndef MONGOC_SSL_DEFAULT_TRUST_FILE -#define MONGOC_SSL_DEFAULT_TRUST_FILE NULL -#endif -#ifndef MONGOC_SSL_DEFAULT_TRUST_DIR -#define MONGOC_SSL_DEFAULT_TRUST_DIR NULL -#endif - -static mongoc_ssl_opt_t gMongocSslOptDefault = { - NULL, NULL, MONGOC_SSL_DEFAULT_TRUST_FILE, MONGOC_SSL_DEFAULT_TRUST_DIR, -}; - -const mongoc_ssl_opt_t * -mongoc_ssl_opt_get_default (void) -{ - return &gMongocSslOptDefault; -} - -char * -mongoc_ssl_extract_subject (const char *filename, const char *passphrase) -{ - char *retval; - - if (!filename) { - MONGOC_ERROR ("No filename provided to extract subject from"); - return NULL; - } - -#ifdef _WIN32 - if (_access (filename, 0) != 0) { -#else - if (access (filename, R_OK) != 0) { -#endif - MONGOC_ERROR ("Can't extract subject from unreadable file: '%s'", - filename); - return NULL; - } - -#if defined(MONGOC_ENABLE_SSL_OPENSSL) - retval = _mongoc_openssl_extract_subject (filename, passphrase); -#elif defined(MONGOC_ENABLE_SSL_LIBRESSL) - MONGOC_WARNING ( - "libtls doesn't support automatically extracting subject from " - "certificate to use with authentication"); - retval = NULL; -#elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) -retval = _mongoc_secure_transport_extract_subject (filename, passphrase); -#elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) -retval = _mongoc_secure_channel_extract_subject (filename, passphrase); -#endif - - if (!retval) { - MONGOC_ERROR ("Can't extract subject from file '%s'", filename); - } - - return retval; -} - -void -_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt, mongoc_uri_t *uri) -{ - bool insecure = - mongoc_uri_get_option_as_bool (uri, MONGOC_URI_TLSINSECURE, false); - - ssl_opt->pem_file = mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, NULL); - ssl_opt->pem_pwd = mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, NULL); - ssl_opt->ca_file = - mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCAFILE, NULL); - ssl_opt->weak_cert_validation = mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, insecure); - ssl_opt->allow_invalid_hostname = mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, insecure); -} - -void -_mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src, mongoc_ssl_opt_t *dst) -{ - BSON_ASSERT (src); - BSON_ASSERT (dst); - - dst->pem_file = bson_strdup (src->pem_file); - dst->pem_pwd = bson_strdup (src->pem_pwd); - dst->ca_file = bson_strdup (src->ca_file); - dst->ca_dir = bson_strdup (src->ca_dir); - dst->crl_file = bson_strdup (src->crl_file); - dst->weak_cert_validation = src->weak_cert_validation; - dst->allow_invalid_hostname = src->allow_invalid_hostname; -} - -void -_mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt) -{ - bson_free ((char *) opt->pem_file); - bson_free ((char *) opt->pem_pwd); - bson_free ((char *) opt->ca_file); - bson_free ((char *) opt->ca_dir); - bson_free ((char *) opt->crl_file); -} - - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl.h deleted file mode 100644 index 8010f3d7107b7d9c65bfd3e2eaec86c93583d462..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-ssl.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SSL_H -#define MONGOC_SSL_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_ssl_opt_t mongoc_ssl_opt_t; - - -struct _mongoc_ssl_opt_t { - const char *pem_file; - const char *pem_pwd; - const char *ca_file; - const char *ca_dir; - const char *crl_file; - bool weak_cert_validation; - bool allow_invalid_hostname; - void *padding[7]; -}; - - -MONGOC_EXPORT (const mongoc_ssl_opt_t *) -mongoc_ssl_opt_get_default (void) BSON_GNUC_PURE; - - -BSON_END_DECLS - - -#endif /* MONGOC_SSL_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-sspi-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-sspi-private.h deleted file mode 100644 index 64bad053768dc8478b01617b6c897ed870935b10..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-sspi-private.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2017 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_SSPI_PRIVATE_H -#define MONGOC_SSPI_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-sasl-private.h" - - -BSON_BEGIN_DECLS - - -#define SECURITY_WIN32 1 /* Required for SSPI */ - -#include <Windows.h> -#include <limits.h> -#include <sspi.h> -#include <string.h> - -#define MONGOC_SSPI_AUTH_GSS_ERROR -1 -#define MONGOC_SSPI_AUTH_GSS_COMPLETE 1 -#define MONGOC_SSPI_AUTH_GSS_CONTINUE 0 - -typedef struct { - mongoc_sasl_t sasl; - CredHandle cred; - CtxtHandle ctx; - WCHAR *spn; - SEC_CHAR *response; - SEC_CHAR *username; - ULONG flags; - UCHAR haveCred; - UCHAR haveCtx; - ULONG qop; -} mongoc_sspi_client_state_t; - -void -_mongoc_sspi_set_gsserror (DWORD errCode, const SEC_CHAR *msg); - -void -_mongoc_sspi_destroy_sspi_client_state (mongoc_sspi_client_state_t *state); - -int -_mongoc_sspi_auth_sspi_client_init (WCHAR *service, - ULONG flags, - WCHAR *user, - ULONG ulen, - WCHAR *domain, - ULONG dlen, - WCHAR *password, - ULONG plen, - mongoc_sspi_client_state_t *state); -int -_mongoc_sspi_auth_sspi_client_step (mongoc_sspi_client_state_t *state, - SEC_CHAR *challenge); - -int -_mongoc_sspi_auth_sspi_client_unwrap (mongoc_sspi_client_state_t *state, - SEC_CHAR *challenge); - -int -_mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, - SEC_CHAR *data, - SEC_CHAR *user, - ULONG ulen, - INT protect); - - -BSON_END_DECLS - - -#endif /* MONGOC_SSPI_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-sspi.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-sspi.c deleted file mode 100644 index efd8a08d92de50387197b52b9e00184aeae501d2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-sspi.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Copyright 2017 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. - * - * This file originates from https://github.com/mongodb-labs/winkerberos - */ - -#include "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SASL_SSPI - -/* mingw doesn't define this */ -#ifndef CRYPT_STRING_NOCRLF -#define CRYPT_STRING_NOCRLF 0x40000000 -#endif - -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-sspi-private.h" - -void -_mongoc_sspi_destroy_sspi_client_state (mongoc_sspi_client_state_t *state) -{ - if (state->haveCtx) { - DeleteSecurityContext (&state->ctx); - state->haveCtx = 0; - } - if (state->haveCred) { - FreeCredentialsHandle (&state->cred); - state->haveCred = 0; - } - if (state->spn != NULL) { - free (state->spn); - state->spn = NULL; - } - if (state->response != NULL) { - free (state->response); - state->response = NULL; - } - if (state->username != NULL) { - free (state->username); - state->username = NULL; - } -} - -void -_mongoc_sspi_set_gsserror (DWORD errCode, const SEC_CHAR *msg) -{ - SEC_CHAR *err; - DWORD status; - DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS; - status = FormatMessageA (flags, - NULL, - errCode, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &err, - 0, - NULL); - if (status) { - MONGOC_ERROR ("SSPI: %s: %s", msg, err); - LocalFree (err); - } else { - MONGOC_ERROR ("SSPI: %s", msg); - } -} - -static SEC_CHAR * -_mongoc_sspi_base64_encode (const SEC_CHAR *value, DWORD vlen) -{ - SEC_CHAR *out = NULL; - DWORD len; - /* Get the correct size for the out buffer. */ - if (CryptBinaryToStringA ((BYTE *) value, - vlen, - CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, - NULL, - &len)) { - out = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * len); - if (out) { - /* Encode to the out buffer. */ - if (CryptBinaryToStringA ((BYTE *) value, - vlen, - CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, - out, - &len)) { - return out; - } else { - free (out); - } - } - } - MONGOC_ERROR ("%s", "CryptBinaryToString failed."); - return NULL; -} - -static SEC_CHAR * -_mongoc_sspi_base64_decode (const SEC_CHAR *value, DWORD *rlen) -{ - SEC_CHAR *out = NULL; - /* Get the correct size for the out buffer. */ - if (CryptStringToBinaryA ( - value, 0, CRYPT_STRING_BASE64, NULL, rlen, NULL, NULL)) { - out = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * *rlen); - if (out) { - /* Decode to the out buffer. */ - if (CryptStringToBinaryA (value, - 0, - CRYPT_STRING_BASE64, - (BYTE *) out, - rlen, - NULL, - NULL)) { - return out; - } else { - free (out); - } - } - } - MONGOC_ERROR ("%s", "CryptStringToBinary failed."); - return NULL; -} - -static CHAR * -_mongoc_sspi_wide_to_utf8 (WCHAR *value) -{ - CHAR *out; - int len = WideCharToMultiByte (CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL); - if (len) { - out = (CHAR *) malloc (sizeof (CHAR) * len); - if (WideCharToMultiByte (CP_UTF8, 0, value, -1, out, len, NULL, NULL)) { - return out; - } else { - free (out); - } - } - _mongoc_sspi_set_gsserror (GetLastError (), "WideCharToMultiByte"); - return NULL; -} - -int -_mongoc_sspi_auth_sspi_client_init (WCHAR *service, - ULONG flags, - WCHAR *user, - ULONG ulen, - WCHAR *domain, - ULONG dlen, - WCHAR *password, - ULONG plen, - mongoc_sspi_client_state_t *state) -{ - SECURITY_STATUS status; - SEC_WINNT_AUTH_IDENTITY_W authIdentity; - TimeStamp ignored; - - state->response = NULL; - state->username = NULL; - state->qop = SECQOP_WRAP_NO_ENCRYPT; - state->flags = flags; - state->haveCred = 0; - state->haveCtx = 0; - state->spn = _wcsdup (service); - if (state->spn == NULL) { - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - /* Convert RFC-2078 format to SPN */ - if (!wcschr (state->spn, L'/')) { - WCHAR *ptr = wcschr (state->spn, L'@'); - if (ptr) { - *ptr = L'/'; - } - } - - if (user) { - authIdentity.User = user; - authIdentity.UserLength = ulen; - authIdentity.Domain = domain; - authIdentity.DomainLength = dlen; - authIdentity.Password = password; - authIdentity.PasswordLength = plen; - authIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - } - - /* Note that the first parameter, pszPrincipal, appears to be - * completely ignored in the Kerberos SSP. For more details see - * https://github.com/mongodb-labs/winkerberos/issues/11. - * */ - status = AcquireCredentialsHandleW (/* Principal */ - NULL, - /* Security package name */ - L"kerberos", - /* Credentials Use */ - SECPKG_CRED_OUTBOUND, - /* LogonID (We don't use this) */ - NULL, - /* AuthData */ - user ? &authIdentity : NULL, - /* Always NULL */ - NULL, - /* Always NULL */ - NULL, - /* CredHandle */ - &state->cred, - /* Expiry (Required but unused by us) */ - &ignored); - if (status != SEC_E_OK) { - _mongoc_sspi_set_gsserror (status, "AcquireCredentialsHandle"); - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - state->haveCred = 1; - return MONGOC_SSPI_AUTH_GSS_COMPLETE; -} - -int -_mongoc_sspi_auth_sspi_client_step (mongoc_sspi_client_state_t *state, - SEC_CHAR *challenge) -{ - SecBufferDesc inbuf; - SecBuffer inBufs[1]; - SecBufferDesc outbuf; - SecBuffer outBufs[1]; - ULONG ignored; - SECURITY_STATUS status = MONGOC_SSPI_AUTH_GSS_CONTINUE; - DWORD len; - - if (state->response != NULL) { - free (state->response); - state->response = NULL; - } - - inbuf.ulVersion = SECBUFFER_VERSION; - inbuf.cBuffers = 1; - inbuf.pBuffers = inBufs; - inBufs[0].pvBuffer = NULL; - inBufs[0].cbBuffer = 0; - inBufs[0].BufferType = SECBUFFER_TOKEN; - if (state->haveCtx) { - inBufs[0].pvBuffer = _mongoc_sspi_base64_decode (challenge, &len); - if (!inBufs[0].pvBuffer) { - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - inBufs[0].cbBuffer = len; - } - - outbuf.ulVersion = SECBUFFER_VERSION; - outbuf.cBuffers = 1; - outbuf.pBuffers = outBufs; - outBufs[0].pvBuffer = NULL; - outBufs[0].cbBuffer = 0; - outBufs[0].BufferType = SECBUFFER_TOKEN; - - status = InitializeSecurityContextW (/* CredHandle */ - &state->cred, - /* CtxtHandle (NULL on first call) */ - state->haveCtx ? &state->ctx : NULL, - /* Service Principal Name */ - state->spn, - /* Flags */ - ISC_REQ_ALLOCATE_MEMORY | state->flags, - /* Always 0 */ - 0, - /* Target data representation */ - SECURITY_NETWORK_DREP, - /* Challenge (NULL on first call) */ - state->haveCtx ? &inbuf : NULL, - /* Always 0 */ - 0, - /* CtxtHandle (Set on first call) */ - &state->ctx, - /* Output */ - &outbuf, - /* Context attributes */ - &ignored, - /* Expiry (We don't use this) */ - NULL); - if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { - _mongoc_sspi_set_gsserror (status, "InitializeSecurityContext"); - status = MONGOC_SSPI_AUTH_GSS_ERROR; - goto done; - } - state->haveCtx = 1; - if (outBufs[0].cbBuffer) { - state->response = - _mongoc_sspi_base64_encode (outBufs[0].pvBuffer, outBufs[0].cbBuffer); - if (!state->response) { - status = MONGOC_SSPI_AUTH_GSS_ERROR; - goto done; - } - } - if (status == SEC_E_OK) { - /* Get authenticated username. */ - SecPkgContext_NamesW names; - status = QueryContextAttributesW (&state->ctx, SECPKG_ATTR_NAMES, &names); - if (status != SEC_E_OK) { - _mongoc_sspi_set_gsserror (status, "QueryContextAttributesW"); - status = MONGOC_SSPI_AUTH_GSS_ERROR; - goto done; - } - state->username = _mongoc_sspi_wide_to_utf8 (names.sUserName); - if (state->username == NULL) { - FreeContextBuffer (names.sUserName); - status = MONGOC_SSPI_AUTH_GSS_ERROR; - goto done; - } - FreeContextBuffer (names.sUserName); - status = MONGOC_SSPI_AUTH_GSS_COMPLETE; - } else { - status = MONGOC_SSPI_AUTH_GSS_CONTINUE; - } -done: - if (inBufs[0].pvBuffer) { - free (inBufs[0].pvBuffer); - } - if (outBufs[0].pvBuffer) { - FreeContextBuffer (outBufs[0].pvBuffer); - } - return status; -} - -int -_mongoc_sspi_auth_sspi_client_unwrap (mongoc_sspi_client_state_t *state, - SEC_CHAR *challenge) -{ - SECURITY_STATUS status; - DWORD len; - SecBuffer wrapBufs[2]; - SecBufferDesc wrapBufDesc; - wrapBufDesc.ulVersion = SECBUFFER_VERSION; - wrapBufDesc.cBuffers = 2; - wrapBufDesc.pBuffers = wrapBufs; - - if (state->response != NULL) { - free (state->response); - state->response = NULL; - state->qop = SECQOP_WRAP_NO_ENCRYPT; - } - - if (!state->haveCtx) { - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - - wrapBufs[0].pvBuffer = _mongoc_sspi_base64_decode (challenge, &len); - if (!wrapBufs[0].pvBuffer) { - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - wrapBufs[0].cbBuffer = len; - wrapBufs[0].BufferType = SECBUFFER_STREAM; - - wrapBufs[1].pvBuffer = NULL; - wrapBufs[1].cbBuffer = 0; - wrapBufs[1].BufferType = SECBUFFER_DATA; - - status = DecryptMessage (&state->ctx, &wrapBufDesc, 0, &state->qop); - if (status == SEC_E_OK) { - status = MONGOC_SSPI_AUTH_GSS_COMPLETE; - } else { - _mongoc_sspi_set_gsserror (status, "DecryptMessage"); - status = MONGOC_SSPI_AUTH_GSS_ERROR; - goto done; - } - if (wrapBufs[1].cbBuffer) { - state->response = _mongoc_sspi_base64_encode (wrapBufs[1].pvBuffer, - wrapBufs[1].cbBuffer); - if (!state->response) { - status = MONGOC_SSPI_AUTH_GSS_ERROR; - } - } -done: - if (wrapBufs[0].pvBuffer) { - free (wrapBufs[0].pvBuffer); - } - return status; -} - -int -_mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, - SEC_CHAR *data, - SEC_CHAR *user, - ULONG ulen, - int protect) -{ - SECURITY_STATUS status; - SecPkgContext_Sizes sizes; - SecBuffer wrapBufs[3]; - SecBufferDesc wrapBufDesc; - SEC_CHAR *decodedData = NULL; - SEC_CHAR *inbuf; - SIZE_T inbufSize; - SEC_CHAR *outbuf; - DWORD outbufSize; - SEC_CHAR *plaintextMessage; - ULONG plaintextMessageSize; - - if (state->response != NULL) { - free (state->response); - state->response = NULL; - } - - if (!state->haveCtx) { - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - - status = QueryContextAttributes (&state->ctx, SECPKG_ATTR_SIZES, &sizes); - if (status != SEC_E_OK) { - _mongoc_sspi_set_gsserror (status, "QueryContextAttributes"); - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - - if (user) { - /* Length of user + 4 bytes for security layer (see below). */ - plaintextMessageSize = ulen + 4; - } else { - decodedData = _mongoc_sspi_base64_decode (data, &plaintextMessageSize); - if (!decodedData) { - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - } - - inbufSize = - sizes.cbSecurityTrailer + plaintextMessageSize + sizes.cbBlockSize; - inbuf = (SEC_CHAR *) malloc (inbufSize); - if (inbuf == NULL) { - free (decodedData); - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - - plaintextMessage = inbuf + sizes.cbSecurityTrailer; - if (user) { - /* Authenticate the provided user. Unlike pykerberos, we don't - * need any information from "data" to do that. - * */ - plaintextMessage[0] = 1; /* No security layer */ - plaintextMessage[1] = 0; - plaintextMessage[2] = 0; - plaintextMessage[3] = 0; - memcpy_s (plaintextMessage + 4, - inbufSize - sizes.cbSecurityTrailer - 4, - user, - strlen (user)); - } else { - /* No user provided. Just rewrap data. */ - memcpy_s (plaintextMessage, - inbufSize - sizes.cbSecurityTrailer, - decodedData, - plaintextMessageSize); - free (decodedData); - } - - wrapBufDesc.cBuffers = 3; - wrapBufDesc.pBuffers = wrapBufs; - wrapBufDesc.ulVersion = SECBUFFER_VERSION; - - wrapBufs[0].cbBuffer = sizes.cbSecurityTrailer; - wrapBufs[0].BufferType = SECBUFFER_TOKEN; - wrapBufs[0].pvBuffer = inbuf; - - wrapBufs[1].cbBuffer = (ULONG) plaintextMessageSize; - wrapBufs[1].BufferType = SECBUFFER_DATA; - wrapBufs[1].pvBuffer = inbuf + sizes.cbSecurityTrailer; - - wrapBufs[2].cbBuffer = sizes.cbBlockSize; - wrapBufs[2].BufferType = SECBUFFER_PADDING; - wrapBufs[2].pvBuffer = - inbuf + (sizes.cbSecurityTrailer + plaintextMessageSize); - - status = EncryptMessage ( - &state->ctx, protect ? 0 : SECQOP_WRAP_NO_ENCRYPT, &wrapBufDesc, 0); - if (status != SEC_E_OK) { - free (inbuf); - _mongoc_sspi_set_gsserror (status, "EncryptMessage"); - return MONGOC_SSPI_AUTH_GSS_ERROR; - } - - outbufSize = - wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer + wrapBufs[2].cbBuffer; - outbuf = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * outbufSize); - memcpy_s (outbuf, outbufSize, wrapBufs[0].pvBuffer, wrapBufs[0].cbBuffer); - memcpy_s (outbuf + wrapBufs[0].cbBuffer, - outbufSize - wrapBufs[0].cbBuffer, - wrapBufs[1].pvBuffer, - wrapBufs[1].cbBuffer); - memcpy_s (outbuf + wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer, - outbufSize - wrapBufs[0].cbBuffer - wrapBufs[1].cbBuffer, - wrapBufs[2].pvBuffer, - wrapBufs[2].cbBuffer); - state->response = _mongoc_sspi_base64_encode (outbuf, outbufSize); - if (!state->response) { - status = MONGOC_SSPI_AUTH_GSS_ERROR; - } else { - status = MONGOC_SSPI_AUTH_GSS_COMPLETE; - } - free (inbuf); - free (outbuf); - return status; -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-buffered.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-buffered.c deleted file mode 100644 index 23bcf9e6a4ff9fbed9c7690580297090c61ed390..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-buffered.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright 2013 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 <errno.h> - -#include "mongoc/mongoc-buffer-private.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-stream-buffered.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-trace-private.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream" - - -typedef struct { - mongoc_stream_t stream; - mongoc_stream_t *base_stream; - mongoc_buffer_t buffer; -} mongoc_stream_buffered_t; - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_buffered_destroy -- - * - * Clean up after a mongoc_stream_buffered_t. Free all allocated - * resources and release the base stream. - * - * Returns: - * None. - * - * Side effects: - * Everything. - * - *-------------------------------------------------------------------------- - */ - -static void -mongoc_stream_buffered_destroy (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; - - BSON_ASSERT (stream); - - mongoc_stream_destroy (buffered->base_stream); - buffered->base_stream = NULL; - - _mongoc_buffer_destroy (&buffered->buffer); - - bson_free (stream); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_buffered_failed -- - * - * Called when a stream fails. Useful for streams that differnciate - * between failure and cleanup. - * Calls mongoc_stream_buffered_destroy() on the stream. - * - * Returns: - * None. - * - * Side effects: - * Everything. - * - *-------------------------------------------------------------------------- - */ - -static void -mongoc_stream_buffered_failed (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_buffered_destroy (stream); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_buffered_close -- - * - * Close the underlying stream. The buffered content is still - * valid. - * - * Returns: - * The return value of mongoc_stream_close() on the underlying - * stream. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static int -mongoc_stream_buffered_close (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; - BSON_ASSERT (stream); - return mongoc_stream_close (buffered->base_stream); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_buffered_flush -- - * - * Flushes the underlying stream. - * - * Returns: - * The result of flush on the base stream. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static int -mongoc_stream_buffered_flush (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; - BSON_ASSERT (buffered); - return mongoc_stream_flush (buffered->base_stream); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_buffered_writev -- - * - * Write an iovec to the underlying stream. This write is not - * buffered, it passes through to the base stream directly. - * - * timeout_msec should be the number of milliseconds to wait before - * considering the writev as failed. - * - * Returns: - * The number of bytes written or -1 on failure. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static ssize_t -mongoc_stream_buffered_writev (mongoc_stream_t *stream, /* IN */ - mongoc_iovec_t *iov, /* IN */ - size_t iovcnt, /* IN */ - int32_t timeout_msec) /* IN */ -{ - mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; - ssize_t ret; - - ENTRY; - - BSON_ASSERT (buffered); - - ret = - mongoc_stream_writev (buffered->base_stream, iov, iovcnt, timeout_msec); - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_buffered_readv -- - * - * Read from the underlying stream. The data will be buffered based - * on the buffered streams target buffer size. - * - * When reading from the underlying stream, we read at least the - * requested number of bytes, but try to also fill the stream to - * the size of the underlying buffer. - * - * Note: - * This isn't actually a huge savings since we never have more than - * one reply waiting for us, but perhaps someday that will be - * different. It should help for small replies, however that will - * reduce our read() syscalls by 50%. - * - * Returns: - * The number of bytes read or -1 on failure. - * - * Side effects: - * iov[*]->iov_base buffers are filled. - * - *-------------------------------------------------------------------------- - */ - -static ssize_t -mongoc_stream_buffered_readv (mongoc_stream_t *stream, /* IN */ - mongoc_iovec_t *iov, /* INOUT */ - size_t iovcnt, /* IN */ - size_t min_bytes, /* IN */ - int32_t timeout_msec) /* IN */ -{ - mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; - bson_error_t error = {0}; - size_t total_bytes = 0; - size_t i; - size_t off = 0; - - ENTRY; - - BSON_ASSERT (buffered); - - for (i = 0; i < iovcnt; i++) { - total_bytes += iov[i].iov_len; - } - - if (-1 == _mongoc_buffer_fill (&buffered->buffer, - buffered->base_stream, - total_bytes, - timeout_msec, - &error)) { - MONGOC_WARNING ("%s", error.message); - RETURN (-1); - } - - BSON_ASSERT (buffered->buffer.len >= total_bytes); - - for (i = 0; i < iovcnt; i++) { - memcpy (iov[i].iov_base, buffered->buffer.data + off, iov[i].iov_len); - off += iov[i].iov_len; - buffered->buffer.len -= iov[i].iov_len; - } - - memmove ( - buffered->buffer.data, buffered->buffer.data + off, buffered->buffer.len); - - RETURN (total_bytes); -} - - -static mongoc_stream_t * -_mongoc_stream_buffered_get_base_stream (mongoc_stream_t *stream) /* IN */ -{ - return ((mongoc_stream_buffered_t *) stream)->base_stream; -} - - -static bool -_mongoc_stream_buffered_check_closed (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; - BSON_ASSERT (stream); - return mongoc_stream_check_closed (buffered->base_stream); -} - - -static bool -_mongoc_stream_buffered_timed_out (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; - BSON_ASSERT (stream); - return mongoc_stream_timed_out (buffered->base_stream); -} - - -static bool -_mongoc_stream_buffered_should_retry (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; - BSON_ASSERT (stream); - return mongoc_stream_should_retry (buffered->base_stream); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_buffered_new -- - * - * Creates a new mongoc_stream_buffered_t. - * - * This stream will read from an underlying stream and try to read - * more data than necessary. It can help lower the number of read() - * or recv() syscalls performed. - * - * @base_stream is considered owned by the resulting stream after - * calling this function. - * - * Returns: - * A newly allocated mongoc_stream_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_stream_t * -mongoc_stream_buffered_new (mongoc_stream_t *base_stream, /* IN */ - size_t buffer_size) /* IN */ -{ - mongoc_stream_buffered_t *stream; - - BSON_ASSERT (base_stream); - - stream = (mongoc_stream_buffered_t *) bson_malloc0 (sizeof *stream); - stream->stream.type = MONGOC_STREAM_BUFFERED; - stream->stream.destroy = mongoc_stream_buffered_destroy; - stream->stream.failed = mongoc_stream_buffered_failed; - stream->stream.close = mongoc_stream_buffered_close; - stream->stream.flush = mongoc_stream_buffered_flush; - stream->stream.writev = mongoc_stream_buffered_writev; - stream->stream.readv = mongoc_stream_buffered_readv; - stream->stream.get_base_stream = _mongoc_stream_buffered_get_base_stream; - stream->stream.check_closed = _mongoc_stream_buffered_check_closed; - stream->stream.timed_out = _mongoc_stream_buffered_timed_out; - stream->stream.should_retry = _mongoc_stream_buffered_should_retry; - - stream->base_stream = base_stream; - - _mongoc_buffer_init (&stream->buffer, NULL, buffer_size, NULL, NULL); - - mongoc_counter_streams_active_inc (); - - return (mongoc_stream_t *) stream; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-buffered.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-buffered.h deleted file mode 100644 index 3ffba91d975667f7c232fdb466a432179dd2e88e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-buffered.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_BUFFERED_H -#define MONGOC_STREAM_BUFFERED_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-stream.h" - - -BSON_BEGIN_DECLS - - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_buffered_new (mongoc_stream_t *base_stream, size_t buffer_size); - - -BSON_END_DECLS - - -#endif /* MONGOC_STREAM_BUFFERED_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-file.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-file.c deleted file mode 100644 index 1a948a2605d181279a9f0a5aa130e4c14684760c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-file.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2014 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. - */ - - -#ifdef _WIN32 -#include <io.h> -#include <share.h> -#endif - -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-file.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-counters-private.h" - -/* - * TODO: This does not respect timeouts or set O_NONBLOCK. - * But that should be fine until it isn't :-) - */ - - -struct _mongoc_stream_file_t { - mongoc_stream_t vtable; - int fd; -}; - - -static int -_mongoc_stream_file_close (mongoc_stream_t *stream) -{ - mongoc_stream_file_t *file = (mongoc_stream_file_t *) stream; - int ret; - - ENTRY; - - BSON_ASSERT (file); - - if (file->fd != -1) { -#ifdef _WIN32 - ret = _close (file->fd); -#else - ret = close (file->fd); -#endif - file->fd = -1; - RETURN (ret); - } - - RETURN (0); -} - - -static void -_mongoc_stream_file_destroy (mongoc_stream_t *stream) -{ - mongoc_stream_file_t *file = (mongoc_stream_file_t *) stream; - - ENTRY; - - BSON_ASSERT (file); - - if (file->fd) { - _mongoc_stream_file_close (stream); - } - - bson_free (file); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); - - EXIT; -} - - -static void -_mongoc_stream_file_failed (mongoc_stream_t *stream) -{ - ENTRY; - - _mongoc_stream_file_destroy (stream); - - EXIT; -} - - -static int -_mongoc_stream_file_flush (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_file_t *file = (mongoc_stream_file_t *) stream; - - BSON_ASSERT (file); - - if (file->fd != -1) { -#ifdef _WIN32 - return _commit (file->fd); -#else - return fsync (file->fd); -#endif - } - - return 0; -} - - -static ssize_t -_mongoc_stream_file_readv (mongoc_stream_t *stream, /* IN */ - mongoc_iovec_t *iov, /* IN */ - size_t iovcnt, /* IN */ - size_t min_bytes, /* IN */ - int32_t timeout_msec) /* IN */ -{ - mongoc_stream_file_t *file = (mongoc_stream_file_t *) stream; - ssize_t ret = 0; - -#ifdef _WIN32 - ssize_t nread; - size_t i; - - ENTRY; - - for (i = 0; i < iovcnt; i++) { - nread = _read (file->fd, iov[i].iov_base, iov[i].iov_len); - if (nread < 0) { - ret = ret ? ret : -1; - GOTO (done); - } else if (nread == 0) { - ret = ret ? ret : 0; - GOTO (done); - } else { - ret += nread; - if (nread != iov[i].iov_len) { - ret = ret ? ret : -1; - GOTO (done); - } - } - } - - GOTO (done); -#else - ENTRY; - ret = readv (file->fd, iov, (int) iovcnt); - GOTO (done); -#endif -done: - if (ret > 0) { - mongoc_counter_streams_ingress_add (ret); - } - return ret; -} - - -static ssize_t -_mongoc_stream_file_writev (mongoc_stream_t *stream, /* IN */ - mongoc_iovec_t *iov, /* IN */ - size_t iovcnt, /* IN */ - int32_t timeout_msec) /* IN */ -{ - mongoc_stream_file_t *file = (mongoc_stream_file_t *) stream; - ssize_t ret = 0; - -#ifdef _WIN32 - ssize_t nwrite; - size_t i; - - for (i = 0; i < iovcnt; i++) { - nwrite = _write (file->fd, iov[i].iov_base, iov[i].iov_len); - if (nwrite != iov[i].iov_len) { - ret = ret ? ret : -1; - goto done; - } - ret += nwrite; - } - goto done; -#else - ret = writev (file->fd, iov, (int) iovcnt); - goto done; -#endif -done: - if (ret > 0) { - mongoc_counter_streams_egress_add (ret); - } - return ret; -} - - -static bool -_mongoc_stream_file_check_closed (mongoc_stream_t *stream) /* IN */ -{ - return false; -} - - -mongoc_stream_t * -mongoc_stream_file_new (int fd) /* IN */ -{ - mongoc_stream_file_t *stream; - - BSON_ASSERT (fd != -1); - - stream = (mongoc_stream_file_t *) bson_malloc0 (sizeof *stream); - stream->vtable.type = MONGOC_STREAM_FILE; - stream->vtable.close = _mongoc_stream_file_close; - stream->vtable.destroy = _mongoc_stream_file_destroy; - stream->vtable.failed = _mongoc_stream_file_failed; - stream->vtable.flush = _mongoc_stream_file_flush; - stream->vtable.readv = _mongoc_stream_file_readv; - stream->vtable.writev = _mongoc_stream_file_writev; - stream->vtable.check_closed = _mongoc_stream_file_check_closed; - stream->fd = fd; - - mongoc_counter_streams_active_inc (); - return (mongoc_stream_t *) stream; -} - - -mongoc_stream_t * -mongoc_stream_file_new_for_path (const char *path, /* IN */ - int flags, /* IN */ - int mode) /* IN */ -{ - int fd = -1; - - BSON_ASSERT (path); - -#ifdef _WIN32 - if (_sopen_s (&fd, path, (flags | _O_BINARY), _SH_DENYNO, mode) != 0) { - fd = -1; - } -#else - fd = open (path, flags, mode); -#endif - - if (fd == -1) { - return NULL; - } - - return mongoc_stream_file_new (fd); -} - - -int -mongoc_stream_file_get_fd (mongoc_stream_file_t *stream) -{ - BSON_ASSERT (stream); - - return stream->fd; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-file.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-file.h deleted file mode 100644 index 34420b5fdddb7baffb8514285c5d38e65f373f17..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-file.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_FILE_H -#define MONGOC_STREAM_FILE_H - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-stream.h" - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_stream_file_t mongoc_stream_file_t; - - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_file_new (int fd); -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_file_new_for_path (const char *path, int flags, int mode); -MONGOC_EXPORT (int) -mongoc_stream_file_get_fd (mongoc_stream_file_t *stream); - - -BSON_END_DECLS - - -#endif /* MONGOC_STREAM_FILE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h deleted file mode 100644 index 2e754cfa34171aea2e707b785661e354fcd25103..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_GRIDFS_DOWNLOAD_PRIVATE_H -#define MONGOC_STREAM_GRIDFS_DOWNLOAD_PRIVATE_H - -#include "mongoc-stream.h" -#include "mongoc-gridfs-bucket-file-private.h" - -typedef struct { - mongoc_stream_t stream; - mongoc_gridfs_bucket_file_t *file; -} mongoc_gridfs_download_stream_t; - -mongoc_stream_t * -_mongoc_download_stream_gridfs_new (mongoc_gridfs_bucket_file_t *file); - -#endif /* MONGOC_STREAM_GRIDFS_DOWNLOAD_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c deleted file mode 100644 index 458bac1af852db5a9629b41be832eeaa1d3c9b6c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2018-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 "mongoc-stream-gridfs-download-private.h" -#include "mongoc-gridfs-bucket-file-private.h" -#include "mongoc-counters-private.h" -#include "mongoc-trace-private.h" -#include "mongoc-stream-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-gridfs-download" - -static void -_mongoc_download_stream_gridfs_destroy (mongoc_stream_t *stream) -{ - mongoc_gridfs_download_stream_t *gridfs = - (mongoc_gridfs_download_stream_t *) stream; - - ENTRY; - - BSON_ASSERT (stream); - - mongoc_stream_close (stream); - _mongoc_gridfs_bucket_file_destroy (gridfs->file); - - bson_free (stream); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); - - EXIT; -} - -static void -_mongoc_download_stream_gridfs_failed (mongoc_stream_t *stream) -{ - ENTRY; - - _mongoc_download_stream_gridfs_destroy (stream); - - EXIT; -} - -static int -_mongoc_download_stream_gridfs_close (mongoc_stream_t *stream) -{ - mongoc_gridfs_download_stream_t *gridfs = - (mongoc_gridfs_download_stream_t *) stream; - int ret = 0; - - ENTRY; - - BSON_ASSERT (stream); - - gridfs->file->finished = true; - - RETURN (ret); -} - -static ssize_t -_mongoc_download_stream_gridfs_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - mongoc_gridfs_download_stream_t *gridfs = - (mongoc_gridfs_download_stream_t *) stream; - ssize_t ret = 0; - - ENTRY; - - BSON_ASSERT (stream); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - (void) min_bytes; /* unused. */ - (void) timeout_msec; /* unused. */ - - /* timeout_msec is unused by mongoc_gridfs_bucket_file_readv */ - ret = _mongoc_gridfs_bucket_file_readv (gridfs->file, iov, iovcnt); - - mongoc_counter_streams_ingress_add (ret); - - RETURN (ret); -} - - -static bool -_mongoc_download_stream_gridfs_check_closed (mongoc_stream_t *stream) /* IN */ -{ - mongoc_gridfs_download_stream_t *gridfs = - (mongoc_gridfs_download_stream_t *) stream; - - ENTRY; - - BSON_ASSERT (stream); - - RETURN (gridfs->file->finished); -} - - -mongoc_stream_t * -_mongoc_download_stream_gridfs_new (mongoc_gridfs_bucket_file_t *file) -{ - mongoc_gridfs_download_stream_t *stream; - - ENTRY; - - BSON_ASSERT (file); - - stream = (mongoc_gridfs_download_stream_t *) bson_malloc0 (sizeof *stream); - stream->file = file; - stream->stream.type = MONGOC_STREAM_GRIDFS_DOWNLOAD; - stream->stream.destroy = _mongoc_download_stream_gridfs_destroy; - stream->stream.failed = _mongoc_download_stream_gridfs_failed; - stream->stream.close = _mongoc_download_stream_gridfs_close; - stream->stream.readv = _mongoc_download_stream_gridfs_readv; - stream->stream.check_closed = _mongoc_download_stream_gridfs_check_closed; - - mongoc_counter_streams_active_inc (); - - RETURN ((mongoc_stream_t *) stream); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h deleted file mode 100644 index 88229dbab29fe00d626aa12b0a8765b8228e13db..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_GRIDFS_UPLOAD_PRIVATE_H -#define MONGOC_STREAM_GRIDFS_UPLOAD_PRIVATE_H - -#include "mongoc-gridfs-bucket-file-private.h" -#include "mongoc-stream.h" - -typedef struct { - mongoc_stream_t stream; - mongoc_gridfs_bucket_file_t *file; -} mongoc_gridfs_upload_stream_t; - -mongoc_stream_t * -_mongoc_upload_stream_gridfs_new (mongoc_gridfs_bucket_file_t *file); - -#endif /* MONGOC_STREAM_GRIDFS_UPLOAD_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c deleted file mode 100644 index bf38162528db8669279d07d33dc36d0a66e2bb15..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-gridfs-bucket-file-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-stream-gridfs-upload-private.h" -#include "mongoc/mongoc-stream-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-gridfs-upload" - -static void -_mongoc_upload_stream_gridfs_destroy (mongoc_stream_t *stream) -{ - mongoc_gridfs_upload_stream_t *gridfs = - (mongoc_gridfs_upload_stream_t *) stream; - - ENTRY; - - BSON_ASSERT (stream); - - mongoc_stream_close (stream); - - _mongoc_gridfs_bucket_file_destroy (gridfs->file); - bson_free (stream); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); - - EXIT; -} - -static void -_mongoc_upload_stream_gridfs_failed (mongoc_stream_t *stream) -{ - ENTRY; - - _mongoc_upload_stream_gridfs_destroy (stream); - - EXIT; -} - -static int -_mongoc_upload_stream_gridfs_close (mongoc_stream_t *stream) -{ - mongoc_gridfs_upload_stream_t *gridfs = - (mongoc_gridfs_upload_stream_t *) stream; - int ret = 0; - - ENTRY; - - BSON_ASSERT (stream); - - ret = _mongoc_gridfs_bucket_file_save (gridfs->file); - - RETURN (ret ? 0 : 1); -} - -static ssize_t -_mongoc_upload_stream_gridfs_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - mongoc_gridfs_upload_stream_t *gridfs = - (mongoc_gridfs_upload_stream_t *) stream; - ssize_t ret = 0; - - ENTRY; - - BSON_ASSERT (stream); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - (void) timeout_msec; /* unused. */ - ret = _mongoc_gridfs_bucket_file_writev (gridfs->file, iov, iovcnt); - - if (!ret) { - RETURN (ret); - } - - mongoc_counter_streams_egress_add (ret); - - RETURN (ret); -} - -static bool -_mongoc_upload_stream_gridfs_check_closed (mongoc_stream_t *stream) /* IN */ -{ - mongoc_gridfs_upload_stream_t *gridfs = - (mongoc_gridfs_upload_stream_t *) stream; - - ENTRY; - - BSON_ASSERT (stream); - - RETURN (gridfs->file->saved); -} - -mongoc_stream_t * -_mongoc_upload_stream_gridfs_new (mongoc_gridfs_bucket_file_t *file) -{ - mongoc_gridfs_upload_stream_t *stream; - - ENTRY; - - BSON_ASSERT (file); - - stream = (mongoc_gridfs_upload_stream_t *) bson_malloc0 (sizeof *stream); - stream->file = file; - stream->stream.type = MONGOC_STREAM_GRIDFS_UPLOAD; - stream->stream.destroy = _mongoc_upload_stream_gridfs_destroy; - stream->stream.failed = _mongoc_upload_stream_gridfs_failed; - stream->stream.close = _mongoc_upload_stream_gridfs_close; - stream->stream.writev = _mongoc_upload_stream_gridfs_writev; - stream->stream.check_closed = _mongoc_upload_stream_gridfs_check_closed; - - mongoc_counter_streams_active_inc (); - - RETURN ((mongoc_stream_t *) stream); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs.c deleted file mode 100644 index f5be22447539f07d7c2d4c00b85d40f0df54e076..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2013 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 <limits.h> - -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-gridfs-file-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-stream-gridfs.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-gridfs" - - -typedef struct { - mongoc_stream_t stream; - mongoc_gridfs_file_t *file; -} mongoc_stream_gridfs_t; - - -static void -_mongoc_stream_gridfs_destroy (mongoc_stream_t *stream) -{ - ENTRY; - - BSON_ASSERT (stream); - - mongoc_stream_close (stream); - - bson_free (stream); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); - - EXIT; -} - - -static void -_mongoc_stream_gridfs_failed (mongoc_stream_t *stream) -{ - ENTRY; - - _mongoc_stream_gridfs_destroy (stream); - - EXIT; -} - - -static int -_mongoc_stream_gridfs_close (mongoc_stream_t *stream) -{ - mongoc_stream_gridfs_t *gridfs = (mongoc_stream_gridfs_t *) stream; - int ret = 0; - - ENTRY; - - BSON_ASSERT (stream); - - ret = mongoc_gridfs_file_save (gridfs->file); - - RETURN (ret); -} - -static int -_mongoc_stream_gridfs_flush (mongoc_stream_t *stream) -{ - mongoc_stream_gridfs_t *gridfs = (mongoc_stream_gridfs_t *) stream; - int ret = 0; - - ENTRY; - - BSON_ASSERT (stream); - - ret = mongoc_gridfs_file_save (gridfs->file); - - RETURN (ret); -} - - -static ssize_t -_mongoc_stream_gridfs_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - mongoc_stream_gridfs_t *file = (mongoc_stream_gridfs_t *) stream; - ssize_t ret = 0; - - ENTRY; - - BSON_ASSERT (stream); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - /* timeout_msec is unused by mongoc_gridfs_file_readv */ - ret = mongoc_gridfs_file_readv (file->file, iov, iovcnt, min_bytes, 0); - - mongoc_counter_streams_ingress_add (ret); - - RETURN (ret); -} - - -static ssize_t -_mongoc_stream_gridfs_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - mongoc_stream_gridfs_t *file = (mongoc_stream_gridfs_t *) stream; - ssize_t ret = 0; - - ENTRY; - - BSON_ASSERT (stream); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - /* timeout_msec is unused by mongoc_gridfs_file_writev */ - ret = mongoc_gridfs_file_writev (file->file, iov, iovcnt, 0); - - if (!ret) { - RETURN (ret); - } - - mongoc_counter_streams_egress_add (ret); - - RETURN (ret); -} - - -static bool -_mongoc_stream_gridfs_check_closed (mongoc_stream_t *stream) /* IN */ -{ - return false; -} - - -mongoc_stream_t * -mongoc_stream_gridfs_new (mongoc_gridfs_file_t *file) -{ - mongoc_stream_gridfs_t *stream; - - ENTRY; - - BSON_ASSERT (file); - - stream = (mongoc_stream_gridfs_t *) bson_malloc0 (sizeof *stream); - stream->file = file; - stream->stream.type = MONGOC_STREAM_GRIDFS; - stream->stream.destroy = _mongoc_stream_gridfs_destroy; - stream->stream.failed = _mongoc_stream_gridfs_failed; - stream->stream.close = _mongoc_stream_gridfs_close; - stream->stream.flush = _mongoc_stream_gridfs_flush; - stream->stream.writev = _mongoc_stream_gridfs_writev; - stream->stream.readv = _mongoc_stream_gridfs_readv; - stream->stream.check_closed = _mongoc_stream_gridfs_check_closed; - - mongoc_counter_streams_active_inc (); - - RETURN ((mongoc_stream_t *) stream); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs.h deleted file mode 100644 index 84d6e095defd02694c6f61ac6dabde335d2bbdf2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-gridfs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_GRIDFS_H -#define MONGOC_STREAM_GRIDFS_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-gridfs.h" -#include "mongoc/mongoc-stream.h" - - -BSON_BEGIN_DECLS - - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_gridfs_new (mongoc_gridfs_file_t *file); - - -BSON_END_DECLS - - -#endif /* MONGOC_STREAM_GRIDFS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-private.h deleted file mode 100644 index 7f50fb8c999b00dbbc22c2e929a0ebb1bd484dcf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-private.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_PRIVATE_H -#define MONGOC_STREAM_PRIVATE_H - -#include "mongoc/mongoc-iovec.h" -#include "mongoc/mongoc-stream.h" - - -BSON_BEGIN_DECLS - - -#define MONGOC_STREAM_SOCKET 1 -#define MONGOC_STREAM_FILE 2 -#define MONGOC_STREAM_BUFFERED 3 -#define MONGOC_STREAM_GRIDFS 4 -#define MONGOC_STREAM_TLS 5 -#define MONGOC_STREAM_GRIDFS_UPLOAD 6 -#define MONGOC_STREAM_GRIDFS_DOWNLOAD 7 - -bool -mongoc_stream_wait (mongoc_stream_t *stream, int64_t expire_at); - -bool -_mongoc_stream_writev_full (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec, - bson_error_t *error); - -mongoc_stream_t * -mongoc_stream_get_root_stream (mongoc_stream_t *stream); - -BSON_END_DECLS - - -#endif /* MONGOC_STREAM_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-socket.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-socket.c deleted file mode 100644 index f88b8d0bf5731b52eca30b6758bfdb47c63734cb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-socket.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-socket.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-socket-private.h" -#include "mongoc/mongoc-errno-private.h" -#include "mongoc/mongoc-counters-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream" - - -struct _mongoc_stream_socket_t { - mongoc_stream_t vtable; - mongoc_socket_t *sock; -}; - - -static BSON_INLINE int64_t -get_expiration (int32_t timeout_msec) -{ - if (timeout_msec < 0) { - return -1; - } else if (timeout_msec == 0) { - return 0; - } else { - return (bson_get_monotonic_time () + ((int64_t) timeout_msec * 1000L)); - } -} - - -static int -_mongoc_stream_socket_close (mongoc_stream_t *stream) -{ - mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; - int ret; - - ENTRY; - - BSON_ASSERT (ss); - - if (ss->sock) { - ret = mongoc_socket_close (ss->sock); - RETURN (ret); - } - - RETURN (0); -} - - -static void -_mongoc_stream_socket_destroy (mongoc_stream_t *stream) -{ - mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; - - ENTRY; - - BSON_ASSERT (ss); - - if (ss->sock) { - mongoc_socket_destroy (ss->sock); - ss->sock = NULL; - } - - bson_free (ss); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); - - EXIT; -} - - -static void -_mongoc_stream_socket_failed (mongoc_stream_t *stream) -{ - ENTRY; - - _mongoc_stream_socket_destroy (stream); - - EXIT; -} - - -static int -_mongoc_stream_socket_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen) -{ - mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; - int ret; - - ENTRY; - - BSON_ASSERT (ss); - BSON_ASSERT (ss->sock); - - ret = mongoc_socket_setsockopt (ss->sock, level, optname, optval, optlen); - - RETURN (ret); -} - - -static int -_mongoc_stream_socket_flush (mongoc_stream_t *stream) -{ - ENTRY; - RETURN (0); -} - - -static ssize_t -_mongoc_stream_socket_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; - int64_t expire_at; - ssize_t ret = 0; - ssize_t nread; - size_t cur = 0; - - ENTRY; - - BSON_ASSERT (ss); - BSON_ASSERT (ss->sock); - - expire_at = get_expiration (timeout_msec); - - /* - * This isn't ideal, we should plumb through to recvmsg(), but we - * don't actually use this in any way but to a single buffer - * currently anyway, so should be just fine. - */ - - for (;;) { - nread = mongoc_socket_recv ( - ss->sock, iov[cur].iov_base, iov[cur].iov_len, 0, expire_at); - - if (nread <= 0) { - if (ret >= (ssize_t) min_bytes) { - RETURN (ret); - } - errno = mongoc_socket_errno (ss->sock); - RETURN (-1); - } - - ret += nread; - - while ((cur < iovcnt) && (nread >= (ssize_t) iov[cur].iov_len)) { - nread -= iov[cur++].iov_len; - } - - if (cur == iovcnt) { - break; - } - - if (ret >= (ssize_t) min_bytes) { - RETURN (ret); - } - - iov[cur].iov_base = ((char *) iov[cur].iov_base) + nread; - iov[cur].iov_len -= nread; - - BSON_ASSERT (iovcnt - cur); - BSON_ASSERT (iov[cur].iov_len); - } - - RETURN (ret); -} - - -static ssize_t -_mongoc_stream_socket_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; - int64_t expire_at; - ssize_t ret; - - ENTRY; - - if (ss->sock) { - expire_at = get_expiration (timeout_msec); - ret = mongoc_socket_sendv (ss->sock, iov, iovcnt, expire_at); - errno = mongoc_socket_errno (ss->sock); - RETURN (ret); - } - - RETURN (-1); -} - - -static ssize_t -_mongoc_stream_socket_poll (mongoc_stream_poll_t *streams, - size_t nstreams, - int32_t timeout_msec) - -{ - int i; - ssize_t ret = -1; - mongoc_socket_poll_t *sds; - mongoc_stream_socket_t *ss; - - ENTRY; - - sds = (mongoc_socket_poll_t *) bson_malloc (sizeof (*sds) * nstreams); - - for (i = 0; i < nstreams; i++) { - ss = (mongoc_stream_socket_t *) streams[i].stream; - - if (!ss->sock) { - goto CLEANUP; - } - - sds[i].socket = ss->sock; - sds[i].events = streams[i].events; - } - - ret = mongoc_socket_poll (sds, nstreams, timeout_msec); - - if (ret > 0) { - for (i = 0; i < nstreams; i++) { - streams[i].revents = sds[i].revents; - } - } - -CLEANUP: - bson_free (sds); - - RETURN (ret); -} - - -mongoc_socket_t * -mongoc_stream_socket_get_socket (mongoc_stream_socket_t *stream) /* IN */ -{ - BSON_ASSERT (stream); - - return stream->sock; -} - - -static bool -_mongoc_stream_socket_check_closed (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; - - ENTRY; - - BSON_ASSERT (stream); - - if (ss->sock) { - RETURN (mongoc_socket_check_closed (ss->sock)); - } - - RETURN (true); -} - - -static bool -_mongoc_stream_socket_timed_out (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; - - ENTRY; - - BSON_ASSERT (ss); - BSON_ASSERT (ss->sock); - - RETURN (MONGOC_ERRNO_IS_TIMEDOUT (ss->sock->errno_)); -} - - -static bool -_mongoc_stream_socket_should_retry (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; - - ENTRY; - - BSON_ASSERT (ss); - BSON_ASSERT (ss->sock); - - RETURN (MONGOC_ERRNO_IS_AGAIN (ss->sock->errno_)); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_socket_new -- - * - * Create a new mongoc_stream_t using the mongoc_socket_t for - * read and write underneath. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_stream_t * -mongoc_stream_socket_new (mongoc_socket_t *sock) /* IN */ -{ - mongoc_stream_socket_t *stream; - - BSON_ASSERT (sock); - - stream = (mongoc_stream_socket_t *) bson_malloc0 (sizeof *stream); - stream->vtable.type = MONGOC_STREAM_SOCKET; - stream->vtable.close = _mongoc_stream_socket_close; - stream->vtable.destroy = _mongoc_stream_socket_destroy; - stream->vtable.failed = _mongoc_stream_socket_failed; - stream->vtable.flush = _mongoc_stream_socket_flush; - stream->vtable.readv = _mongoc_stream_socket_readv; - stream->vtable.writev = _mongoc_stream_socket_writev; - stream->vtable.setsockopt = _mongoc_stream_socket_setsockopt; - stream->vtable.check_closed = _mongoc_stream_socket_check_closed; - stream->vtable.timed_out = _mongoc_stream_socket_timed_out; - stream->vtable.should_retry = _mongoc_stream_socket_should_retry; - stream->vtable.poll = _mongoc_stream_socket_poll; - stream->sock = sock; - - mongoc_counter_streams_active_inc (); - return (mongoc_stream_t *) stream; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-socket.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-socket.h deleted file mode 100644 index b0a57a4dfa53b23000b0df0f5cde238a94d2068f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-socket.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_SOCKET_H -#define MONGOC_STREAM_SOCKET_H - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-socket.h" -#include "mongoc/mongoc-stream.h" - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_stream_socket_t mongoc_stream_socket_t; - - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_socket_new (mongoc_socket_t *socket); -MONGOC_EXPORT (mongoc_socket_t *) -mongoc_stream_socket_get_socket (mongoc_stream_socket_t *stream); - - -BSON_END_DECLS - - -#endif /* MONGOC_STREAM_SOCKET_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h deleted file mode 100644 index 5da397bf2ebdba36d1407d3fa98f5e18820bac70..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_LIBRESSL_PRIVATE_H -#define MONGOC_STREAM_TLS_LIBRESSL_PRIVATE_H - -#ifdef MONGOC_ENABLE_SSL_LIBRESSL -#include <bson/bson.h> - -#include <tls.h> - -BSON_BEGIN_DECLS - - -/** - * mongoc_stream_tls_libressl_t: - * - * Private storage for LibreSSL Streams - */ -typedef struct { - struct tls *ctx; - struct tls_config *config; -} mongoc_stream_tls_libressl_t; - - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_LIBRESSL */ -#endif /* MONGOC_STREAM_TLS_LIBRESSL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c deleted file mode 100644 index 879c0d44836af6ef42a6a190b939d84afa673ade..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_LIBRESSL - -#include <bson/bson.h> - -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-tls-libressl-private.h" -#include "mongoc/mongoc-libressl-private.h" -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-stream-socket.h" -#include "mongoc/mongoc-socket-private.h" - -#include <tls.h> - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-tls-libressl" - -static void -_mongoc_stream_tls_libressl_destroy (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (libressl); - - tls_close (libressl->ctx); - tls_free (libressl->ctx); - tls_config_free (libressl->config); - - mongoc_stream_destroy (tls->base_stream); - - bson_free (libressl); - bson_free (stream); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); - EXIT; -} - -static void -_mongoc_stream_tls_libressl_failed (mongoc_stream_t *stream) -{ - ENTRY; - _mongoc_stream_tls_libressl_destroy (stream); - EXIT; -} - -static int -_mongoc_stream_tls_libressl_close (mongoc_stream_t *stream) -{ - int ret = 0; - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (libressl); - - ret = mongoc_stream_close (tls->base_stream); - RETURN (ret); -} - -static int -_mongoc_stream_tls_libressl_flush (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (libressl); - RETURN (0); -} - -static ssize_t -_mongoc_stream_tls_libressl_write (mongoc_stream_t *stream, - char *buf, - size_t buf_len) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - mongoc_stream_poll_t poller; - ssize_t total_write = 0; - ssize_t ret; - int64_t now; - int64_t expire = 0; - - ENTRY; - BSON_ASSERT (libressl); - - if (tls->timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL); - } - - do { - poller.stream = stream; - poller.revents = 0; - poller.events = POLLOUT; - ret = tls_write (libressl->ctx, buf, buf_len); - - if (ret == TLS_WANT_POLLIN) { - poller.events = POLLIN; - mongoc_stream_poll (&poller, 1, tls->timeout_msec); - } else if (ret == TLS_WANT_POLLOUT) { - poller.events = POLLOUT; - mongoc_stream_poll (&poller, 1, tls->timeout_msec); - } else if (ret < 0) { - RETURN (total_write); - } else { - buf += ret; - buf_len -= ret; - total_write += ret; - } - if (expire) { - now = bson_get_monotonic_time (); - - if ((expire - now) < 0) { - if (ret == 0) { - mongoc_counter_streams_timeout_inc (); - break; - } - - tls->timeout_msec = 0; - } else { - tls->timeout_msec = (expire - now) / 1000L; - } - } - } while (buf_len > 0); - - - RETURN (total_write); -} - -/* This is copypasta from _mongoc_stream_tls_openssl_writev */ -#define MONGOC_STREAM_TLS_BUFFER_SIZE 4096 -static ssize_t -_mongoc_stream_tls_libressl_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - char buf[MONGOC_STREAM_TLS_BUFFER_SIZE]; - ssize_t ret = 0; - ssize_t child_ret; - size_t i; - size_t iov_pos = 0; - - /* There's a bit of a dance to coalesce vectorized writes into - * MONGOC_STREAM_TLS_BUFFER_SIZE'd writes to avoid lots of small tls - * packets. - * - * The basic idea is that we want to combine writes in the buffer if they're - * smaller than the buffer, flushing as it gets full. For larger writes, or - * the last write in the iovec array, we want to ignore the buffer and just - * write immediately. We take care of doing buffer writes by re-invoking - * ourself with a single iovec_t, pointing at our stack buffer. - */ - char *buf_head = buf; - char *buf_tail = buf; - char *buf_end = buf + MONGOC_STREAM_TLS_BUFFER_SIZE; - size_t bytes; - - char *to_write = NULL; - size_t to_write_len; - - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - BSON_ASSERT (libressl); - ENTRY; - - tls->timeout_msec = timeout_msec; - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - while (iov_pos < iov[i].iov_len) { - if (buf_head != buf_tail || - ((i + 1 < iovcnt) && - ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { - /* If we have either of: - * - buffered bytes already - * - another iovec to send after this one and we don't have more - * bytes to send than the size of the buffer. - * - * copy into the buffer */ - - bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); - - memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes); - buf_tail += bytes; - iov_pos += bytes; - - if (buf_tail == buf_end) { - /* If we're full, request send */ - - to_write = buf_head; - to_write_len = buf_tail - buf_head; - - buf_tail = buf_head = buf; - } - } else { - /* Didn't buffer, so just write it through */ - - to_write = (char *) iov[i].iov_base + iov_pos; - to_write_len = iov[i].iov_len - iov_pos; - - iov_pos += to_write_len; - } - - if (to_write) { - /* We get here if we buffered some bytes and filled the buffer, or - * if we didn't buffer and have to send out of the iovec */ - - child_ret = _mongoc_stream_tls_libressl_write ( - stream, to_write, to_write_len); - - if (child_ret < 0) { - RETURN (ret); - } - - ret += child_ret; - - if (child_ret < to_write_len) { - /* we timed out, so send back what we could send */ - - RETURN (ret); - } - - to_write = NULL; - } - } - } - - if (buf_head != buf_tail) { - /* If we have any bytes buffered, send */ - - child_ret = _mongoc_stream_tls_libressl_write ( - stream, buf_head, buf_tail - buf_head); - - if (child_ret < 0) { - RETURN (child_ret); - } - - ret += child_ret; - } - - if (ret >= 0) { - mongoc_counter_streams_egress_add (ret); - } - - TRACE ("Returning %d", (int) ret); - RETURN (ret); -} - -/* This function is copypasta of _mongoc_stream_tls_openssl_readv */ -static ssize_t -_mongoc_stream_tls_libressl_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - ssize_t ret = 0; - ssize_t read_ret; - size_t i; - size_t iov_pos = 0; - int64_t now; - int64_t expire = 0; - mongoc_stream_poll_t poller; - - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - BSON_ASSERT (libressl); - ENTRY; - - tls->timeout_msec = timeout_msec; - - if (timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (timeout_msec * 1000UL); - } - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - while (iov_pos < iov[i].iov_len) { - poller.stream = stream; - poller.revents = 0; - poller.events = POLLIN; - read_ret = tls_read (libressl->ctx, - (char *) iov[i].iov_base + iov_pos, - (int) (iov[i].iov_len - iov_pos)); - - if (read_ret == TLS_WANT_POLLIN) { - poller.events = POLLIN; - mongoc_stream_poll (&poller, 1, tls->timeout_msec); - } else if (read_ret == TLS_WANT_POLLOUT) { - poller.events = POLLOUT; - mongoc_stream_poll (&poller, 1, tls->timeout_msec); - } else if (read_ret < 0) { - RETURN (ret); - } else { - iov_pos += read_ret; - ret += read_ret; - } - if (expire) { - now = bson_get_monotonic_time (); - - if ((expire - now) < 0) { - if (read_ret == 0) { - mongoc_counter_streams_timeout_inc (); - errno = ETIMEDOUT; - RETURN (-1); - } - - tls->timeout_msec = 0; - } else { - tls->timeout_msec = (expire - now) / 1000L; - } - } - - - if (ret > 0 && (size_t) ret >= min_bytes) { - mongoc_counter_streams_ingress_add (ret); - RETURN (ret); - } - } - } - - if (ret >= 0) { - mongoc_counter_streams_ingress_add (ret); - } - - RETURN (ret); -} - -static int -_mongoc_stream_tls_libressl_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (libressl); - RETURN (mongoc_stream_setsockopt ( - tls->base_stream, level, optname, optval, optlen)); -} - -static mongoc_stream_t * -_mongoc_stream_tls_libressl_get_base_stream (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (libressl); - RETURN (tls->base_stream); -} - - -static bool -_mongoc_stream_tls_libressl_check_closed (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (libressl); - RETURN (mongoc_stream_check_closed (tls->base_stream)); -} - -bool -mongoc_stream_tls_libressl_handshake (mongoc_stream_t *stream, - const char *host, - int *events, - bson_error_t *error) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_libressl_t *libressl = - (mongoc_stream_tls_libressl_t *) tls->ctx; - int ret; - - ENTRY; - BSON_ASSERT (libressl); - - ret = tls_handshake (libressl->ctx); - - if (ret == TLS_WANT_POLLIN) { - *events = POLLIN; - } else if (ret == TLS_WANT_POLLOUT) { - *events = POLLOUT; - } else if (ret < 0) { - *events = 0; - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "TLS handshake failed: %s", - tls_error (libressl->ctx)); - RETURN (false); - } else { - RETURN (true); - } - RETURN (false); -} - -static bool -_mongoc_stream_tls_libressl_timed_out (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - - ENTRY; - - RETURN (mongoc_stream_timed_out (tls->base_stream)); -} - -static bool -_mongoc_stream_tls_libressl_should_retry (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - - ENTRY; - - RETURN (mongoc_stream_should_retry (tls->base_stream)); -} - -mongoc_stream_t * -mongoc_stream_tls_libressl_new (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client) -{ - mongoc_stream_tls_t *tls; - mongoc_stream_tls_libressl_t *libressl; - - ENTRY; - BSON_ASSERT (base_stream); - BSON_ASSERT (opt); - - - if (opt->crl_file) { - MONGOC_ERROR ( - "Setting mongoc_ssl_opt_t.crl_file has no effect when built " - "against libtls"); - RETURN (false); - } - libressl = (mongoc_stream_tls_libressl_t *) bson_malloc0 (sizeof *libressl); - - tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); - tls->parent.type = MONGOC_STREAM_TLS; - tls->parent.destroy = _mongoc_stream_tls_libressl_destroy; - tls->parent.failed = _mongoc_stream_tls_libressl_failed; - tls->parent.close = _mongoc_stream_tls_libressl_close; - tls->parent.flush = _mongoc_stream_tls_libressl_flush; - tls->parent.writev = _mongoc_stream_tls_libressl_writev; - tls->parent.readv = _mongoc_stream_tls_libressl_readv; - tls->parent.setsockopt = _mongoc_stream_tls_libressl_setsockopt; - tls->parent.get_base_stream = _mongoc_stream_tls_libressl_get_base_stream; - tls->parent.check_closed = _mongoc_stream_tls_libressl_check_closed; - tls->parent.timed_out = _mongoc_stream_tls_libressl_timed_out; - tls->parent.should_retry = _mongoc_stream_tls_libressl_should_retry; - memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); - tls->handshake = mongoc_stream_tls_libressl_handshake; - tls->ctx = (void *) libressl; - tls->timeout_msec = -1; - tls->base_stream = base_stream; - - libressl->ctx = client ? tls_client () : tls_server (); - libressl->config = tls_config_new (); - - if (opt->weak_cert_validation) { - tls_config_insecure_noverifycert (libressl->config); - tls_config_insecure_noverifytime (libressl->config); - } - if (opt->allow_invalid_hostname) { - tls_config_insecure_noverifyname (libressl->config); - } - tls_config_set_ciphers (libressl->config, "compat"); - - mongoc_libressl_setup_certificate (libressl, opt); - mongoc_libressl_setup_ca (libressl, opt); - { - mongoc_stream_t *stream = base_stream; - - do { - if (stream->type == MONGOC_STREAM_SOCKET) { - int socket = mongoc_stream_socket_get_socket ( - (mongoc_stream_socket_t *) stream) - ->sd; - if (tls_configure (libressl->ctx, libressl->config) == -1) { - MONGOC_ERROR ("%s", tls_config_error (libressl->config)); - RETURN (false); - } - if (tls_connect_socket (libressl->ctx, socket, host) == -1) { - MONGOC_ERROR ("%s", tls_error (libressl->ctx)); - RETURN (false); - } - break; - } - } while ((stream = mongoc_stream_get_base_stream (stream))); - } - - mongoc_counter_streams_active_inc (); - RETURN ((mongoc_stream_t *) tls); -} -#endif /* MONGOC_ENABLE_SSL_LIBRESSL */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h deleted file mode 100644 index d2b5b3501bd990c6783485a5eadcb82eea345606..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_LIBRESSL_H -#define MONGOC_STREAM_TLS_LIBRESSL_H - -#ifdef MONGOC_ENABLE_SSL_LIBRESSL - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_tls_libressl_new (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client); - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_LIBRESSL */ -#endif /* MONGOC_STREAM_TLS_LIBRESSL_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h deleted file mode 100644 index 21d5aaceb0e55e5f6ecd8a338866f4be1957a0b2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_OPENSSL_BIO_PRIVATE_H -#define MONGOC_STREAM_TLS_OPENSSL_BIO_PRIVATE_H - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -#include <bson/bson.h> - -#include <openssl/bio.h> -#include <openssl/ssl.h> -#include <openssl/err.h> - -BSON_BEGIN_DECLS - -BIO_METHOD * -mongoc_stream_tls_openssl_bio_meth_new (); - -void -mongoc_stream_tls_openssl_bio_set_data (BIO *b, void *ptr); - -int -mongoc_stream_tls_openssl_bio_create (BIO *b); - -int -mongoc_stream_tls_openssl_bio_destroy (BIO *b); - -int -mongoc_stream_tls_openssl_bio_read (BIO *b, char *buf, int len); - -int -mongoc_stream_tls_openssl_bio_write (BIO *b, const char *buf, int len); - -long -mongoc_stream_tls_openssl_bio_ctrl (BIO *b, int cmd, long num, void *ptr); - -int -mongoc_stream_tls_openssl_bio_gets (BIO *b, char *buf, int len); - -int -mongoc_stream_tls_openssl_bio_puts (BIO *b, const char *str); - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_OPENSSL */ -#endif /* MONGOC_STREAM_TLS_OPENSSL_BIO_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c deleted file mode 100644 index 8bd567676832393056985c5a3f9f8bdbaefb17e5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_OPENSSL - -#include <bson/bson.h> - -#include <errno.h> -#include <string.h> - -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-errno-private.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-stream-tls-openssl-bio-private.h" -#include "mongoc/mongoc-stream-tls-openssl-private.h" -#include "mongoc/mongoc-openssl-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-log.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-tls-openssl-bio" - - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) - -/* Magic vtable to make our BIO shim */ -static BIO_METHOD gMongocStreamTlsOpenSslRawMethods = { - BIO_TYPE_FILTER, - "mongoc-stream-tls-glue", - mongoc_stream_tls_openssl_bio_write, - mongoc_stream_tls_openssl_bio_read, - mongoc_stream_tls_openssl_bio_puts, - mongoc_stream_tls_openssl_bio_gets, - mongoc_stream_tls_openssl_bio_ctrl, - mongoc_stream_tls_openssl_bio_create, - mongoc_stream_tls_openssl_bio_destroy, - NULL}; - -static void -BIO_set_data (BIO *b, void *ptr) -{ - b->ptr = ptr; -} - -static void * -BIO_get_data (BIO *b) -{ - return b->ptr; -} - -static void -BIO_set_init (BIO *b, int init) -{ - b->init = init; -} - -BIO_METHOD * -mongoc_stream_tls_openssl_bio_meth_new () -{ - BIO_METHOD *meth = NULL; - - meth = &gMongocStreamTlsOpenSslRawMethods; - return meth; -} - -#else - -BIO_METHOD * -mongoc_stream_tls_openssl_bio_meth_new () -{ - BIO_METHOD *meth = NULL; - - meth = BIO_meth_new (BIO_TYPE_FILTER, "mongoc-stream-tls-glue"); - if (meth) { - BIO_meth_set_write (meth, mongoc_stream_tls_openssl_bio_write); - BIO_meth_set_read (meth, mongoc_stream_tls_openssl_bio_read); - BIO_meth_set_puts (meth, mongoc_stream_tls_openssl_bio_puts); - BIO_meth_set_gets (meth, mongoc_stream_tls_openssl_bio_gets); - BIO_meth_set_ctrl (meth, mongoc_stream_tls_openssl_bio_ctrl); - BIO_meth_set_create (meth, mongoc_stream_tls_openssl_bio_create); - BIO_meth_set_destroy (meth, mongoc_stream_tls_openssl_bio_destroy); - } - - return meth; -} - -#endif - -void -mongoc_stream_tls_openssl_bio_set_data (BIO *b, void *ptr) -{ - BIO_set_data (b, ptr); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_openssl_bio_create -- - * - * BIO callback to create a new BIO instance. - * - * Returns: - * 1 if successful. - * - * Side effects: - * @b is initialized. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_stream_tls_openssl_bio_create (BIO *b) -{ - BSON_ASSERT (b); - - BIO_set_init (b, 1); - BIO_set_data (b, NULL); - BIO_set_flags (b, 0); - - return 1; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_openssl_bio_destroy -- - * - * Release resources associated with BIO. - * - * Returns: - * 1 if successful. - * - * Side effects: - * @b is destroyed. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_stream_tls_openssl_bio_destroy (BIO *b) -{ - mongoc_stream_tls_t *tls; - - BSON_ASSERT (b); - - tls = (mongoc_stream_tls_t *) BIO_get_data (b); - - if (!tls) { - return -1; - } - - BIO_set_data (b, NULL); - BIO_set_init (b, 0); - BIO_set_flags (b, 0); - - ((mongoc_stream_tls_openssl_t *) tls->ctx)->bio = NULL; - - return 1; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_openssl_bio_read -- - * - * Read from the underlying stream to BIO. - * - * Returns: - * -1 on failure; otherwise the number of bytes read. - * - * Side effects: - * @buf is filled with data read from underlying stream. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_stream_tls_openssl_bio_read (BIO *b, char *buf, int len) -{ - mongoc_stream_tls_t *tls; - mongoc_stream_tls_openssl_t *openssl; - int ret; - - BSON_ASSERT (b); - BSON_ASSERT (buf); - ENTRY; - - tls = (mongoc_stream_tls_t *) BIO_get_data (b); - - if (!tls) { - RETURN (-1); - } - - openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; - - errno = 0; - ret = (int) mongoc_stream_read ( - tls->base_stream, buf, len, 0, tls->timeout_msec); - BIO_clear_retry_flags (b); - - if ((ret <= 0) && MONGOC_ERRNO_IS_AGAIN (errno)) { - /* this BIO is not the same as "b", which openssl passed in to this func. - * set its retry flag, which we check with BIO_should_retry in - * mongoc-stream-tls-openssl.c - */ - BIO_set_retry_read (openssl->bio); - } - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_openssl_bio_write -- - * - * Write to the underlying stream on behalf of BIO. - * - * Returns: - * -1 on failure; otherwise the number of bytes written. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_stream_tls_openssl_bio_write (BIO *b, const char *buf, int len) -{ - mongoc_stream_tls_t *tls; - mongoc_stream_tls_openssl_t *openssl; - mongoc_iovec_t iov; - int ret; - ENTRY; - - BSON_ASSERT (b); - BSON_ASSERT (buf); - - tls = (mongoc_stream_tls_t *) BIO_get_data (b); - - if (!tls) { - RETURN (-1); - } - - openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; - - iov.iov_base = (void *) buf; - iov.iov_len = len; - - errno = 0; - TRACE ("mongoc_stream_writev is expected to write: %d", len); - ret = - (int) mongoc_stream_writev (tls->base_stream, &iov, 1, tls->timeout_msec); - BIO_clear_retry_flags (b); - - if (len > ret) { - TRACE ("Returned short write: %d of %d", ret, len); - } else { - TRACE ("Completed the %d", ret); - } - if (ret <= 0 && MONGOC_ERRNO_IS_AGAIN (errno)) { - /* this BIO is not the same as "b", which openssl passed in to this func. - * set its retry flag, which we check with BIO_should_retry in - * mongoc-stream-tls-openssl.c - */ - TRACE ("%s", "Requesting a retry"); - BIO_set_retry_write (openssl->bio); - } - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_openssl_bio_ctrl -- - * - * Handle ctrl callback for BIO. - * - * Returns: - * ioctl dependent. - * - * Side effects: - * ioctl dependent. - * - *-------------------------------------------------------------------------- - */ - -long -mongoc_stream_tls_openssl_bio_ctrl (BIO *b, int cmd, long num, void *ptr) -{ - switch (cmd) { - case BIO_CTRL_FLUSH: - return 1; - default: - return 0; - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_openssl_bio_gets -- - * - * BIO callback for gets(). Not supported. - * - * Returns: - * -1 always. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_stream_tls_openssl_bio_gets (BIO *b, char *buf, int len) -{ - return -1; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_openssl_bio_puts -- - * - * BIO callback to perform puts(). Just calls the actual write - * callback. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -int -mongoc_stream_tls_openssl_bio_puts (BIO *b, const char *str) -{ - return mongoc_stream_tls_openssl_bio_write (b, str, (int) strlen (str)); -} - - -#endif /* MONGOC_ENABLE_SSL_OPENSSL */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h deleted file mode 100644 index 219c2853ae3daf799c5c1f5d4f243fb00ceaea28..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_OPENSSL_PRIVATE_H -#define MONGOC_STREAM_TLS_OPENSSL_PRIVATE_H - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -#include <bson/bson.h> - -BSON_BEGIN_DECLS - - -/** - * mongoc_stream_tls_openssl_t: - * - * Private storage for handling callbacks from mongoc_stream and BIO_* - */ -typedef struct { - BIO *bio; - BIO_METHOD *meth; - SSL_CTX *ctx; -} mongoc_stream_tls_openssl_t; - - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_OPENSSL */ -#endif /* MONGOC_STREAM_TLS_OPENSSL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c deleted file mode 100644 index 5839068a9b74a01d974a500fe2c7b5c1ccf6b769..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c +++ /dev/null @@ -1,779 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_OPENSSL - -#include <bson/bson.h> - -#include <errno.h> -#include <string.h> -#include <openssl/bio.h> -#include <openssl/ssl.h> -#include <openssl/err.h> -#include <openssl/x509v3.h> - -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-errno-private.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-stream-tls-openssl-bio-private.h" -#include "mongoc/mongoc-stream-tls-openssl-private.h" -#include "mongoc/mongoc-openssl-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-error.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-tls-openssl" - -#define MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE 4096 - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) -static void -BIO_meth_free (BIO_METHOD *meth) -{ - /* Nothing to free pre OpenSSL 1.1.0 */ -} -#endif - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_stream_tls_openssl_destroy -- - * - * Cleanup after usage of a mongoc_stream_tls_openssl_t. Free all - *allocated - * resources and ensure connections are closed. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static void -_mongoc_stream_tls_openssl_destroy (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_openssl_t *openssl = - (mongoc_stream_tls_openssl_t *) tls->ctx; - - BSON_ASSERT (tls); - - BIO_free_all (openssl->bio); - openssl->bio = NULL; - - BIO_meth_free (openssl->meth); - openssl->meth = NULL; - - mongoc_stream_destroy (tls->base_stream); - tls->base_stream = NULL; - - SSL_CTX_free (openssl->ctx); - openssl->ctx = NULL; - - bson_free (openssl); - bson_free (stream); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_stream_tls_openssl_failed -- - * - * Called on stream failure. Same as _mongoc_stream_tls_openssl_destroy() - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static void -_mongoc_stream_tls_openssl_failed (mongoc_stream_t *stream) -{ - _mongoc_stream_tls_openssl_destroy (stream); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_stream_tls_openssl_close -- - * - * Close the underlying socket. - * - * Linus dictates that you should not check the result of close() - * since there is a race condition with EAGAIN and a new file - * descriptor being opened. - * - * Returns: - * 0 on success; otherwise -1. - * - * Side effects: - * The BIO fd is closed. - * - *-------------------------------------------------------------------------- - */ - -static int -_mongoc_stream_tls_openssl_close (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - int ret = 0; - ENTRY; - - BSON_ASSERT (tls); - - ret = mongoc_stream_close (tls->base_stream); - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_stream_tls_openssl_flush -- - * - * Flush the underlying stream. - * - * Returns: - * 0 if successful; otherwise -1. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static int -_mongoc_stream_tls_openssl_flush (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_openssl_t *openssl = - (mongoc_stream_tls_openssl_t *) tls->ctx; - - BSON_ASSERT (openssl); - - return BIO_flush (openssl->bio); -} - - -static ssize_t -_mongoc_stream_tls_openssl_write (mongoc_stream_tls_t *tls, - char *buf, - size_t buf_len) -{ - mongoc_stream_tls_openssl_t *openssl = - (mongoc_stream_tls_openssl_t *) tls->ctx; - ssize_t ret; - int64_t now; - int64_t expire = 0; - ENTRY; - - BSON_ASSERT (tls); - BSON_ASSERT (buf); - BSON_ASSERT (buf_len); - - if (tls->timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL); - } - - ret = BIO_write (openssl->bio, buf, buf_len); - - if (ret <= 0) { - return ret; - } - - if (expire) { - now = bson_get_monotonic_time (); - - if ((expire - now) < 0) { - if (ret < buf_len) { - mongoc_counter_streams_timeout_inc (); - } - - tls->timeout_msec = 0; - } else { - tls->timeout_msec = (expire - now) / 1000L; - } - } - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_stream_tls_openssl_writev -- - * - * Write the iovec to the stream. This function will try to write - * all of the bytes or fail. If the number of bytes is not equal - * to the number requested, a failure or EOF has occurred. - * - * Returns: - * -1 on failure, otherwise the number of bytes written. - * - * Side effects: - * None. - * - * This function is copied as _mongoc_stream_tls_secure_transport_writev - *-------------------------------------------------------------------------- - */ - -static ssize_t -_mongoc_stream_tls_openssl_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - char buf[MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE]; - ssize_t ret = 0; - ssize_t child_ret; - size_t i; - size_t iov_pos = 0; - - /* There's a bit of a dance to coalesce vectorized writes into - * MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE'd writes to avoid lots of small tls - * packets. - * - * The basic idea is that we want to combine writes in the buffer if they're - * smaller than the buffer, flushing as it gets full. For larger writes, or - * the last write in the iovec array, we want to ignore the buffer and just - * write immediately. We take care of doing buffer writes by re-invoking - * ourself with a single iovec_t, pointing at our stack buffer. - */ - char *buf_head = buf; - char *buf_tail = buf; - char *buf_end = buf + MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE; - size_t bytes; - - char *to_write = NULL; - size_t to_write_len; - - BSON_ASSERT (tls); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - ENTRY; - - tls->timeout_msec = timeout_msec; - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - while (iov_pos < iov[i].iov_len) { - if (buf_head != buf_tail || - ((i + 1 < iovcnt) && - ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { - /* If we have either of: - * - buffered bytes already - * - another iovec to send after this one and we don't have more - * bytes to send than the size of the buffer. - * - * copy into the buffer */ - - bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); - - memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes); - buf_tail += bytes; - iov_pos += bytes; - - if (buf_tail == buf_end) { - /* If we're full, request send */ - - to_write = buf_head; - to_write_len = buf_tail - buf_head; - - buf_tail = buf_head = buf; - } - } else { - /* Didn't buffer, so just write it through */ - - to_write = (char *) iov[i].iov_base + iov_pos; - to_write_len = iov[i].iov_len - iov_pos; - - iov_pos += to_write_len; - } - - if (to_write) { - /* We get here if we buffered some bytes and filled the buffer, or - * if we didn't buffer and have to send out of the iovec */ - - child_ret = - _mongoc_stream_tls_openssl_write (tls, to_write, to_write_len); - if (child_ret != to_write_len) { - TRACE ("Got child_ret: %ld while to_write_len is: %ld", - child_ret, - to_write_len); - } - - if (child_ret < 0) { - TRACE ("Returning what I had (%ld) as apposed to the error " - "(%ld, errno:%d)", - ret, - child_ret, - errno); - RETURN (ret); - } - - ret += child_ret; - - if (child_ret < to_write_len) { - /* we timed out, so send back what we could send */ - - RETURN (ret); - } - - to_write = NULL; - } - } - } - - if (buf_head != buf_tail) { - /* If we have any bytes buffered, send */ - - child_ret = - _mongoc_stream_tls_openssl_write (tls, buf_head, buf_tail - buf_head); - - if (child_ret < 0) { - RETURN (child_ret); - } - - ret += child_ret; - } - - if (ret >= 0) { - mongoc_counter_streams_egress_add (ret); - } - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_stream_tls_openssl_readv -- - * - * Read from the stream into iov. This function will try to read - * all of the bytes or fail. If the number of bytes is not equal - * to the number requested, a failure or EOF has occurred. - * - * Returns: - * -1 on failure, 0 on EOF, otherwise the number of bytes read. - * - * Side effects: - * iov buffers will be written to. - * - * This function is copied as _mongoc_stream_tls_secure_transport_readv - * - *-------------------------------------------------------------------------- - */ - -static ssize_t -_mongoc_stream_tls_openssl_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_openssl_t *openssl = - (mongoc_stream_tls_openssl_t *) tls->ctx; - ssize_t ret = 0; - size_t i; - int read_ret; - size_t iov_pos = 0; - int64_t now; - int64_t expire = 0; - ENTRY; - - BSON_ASSERT (tls); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - tls->timeout_msec = timeout_msec; - - if (timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (timeout_msec * 1000UL); - } - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - while (iov_pos < iov[i].iov_len) { - read_ret = BIO_read (openssl->bio, - (char *) iov[i].iov_base + iov_pos, - (int) (iov[i].iov_len - iov_pos)); - - /* https://www.openssl.org/docs/crypto/BIO_should_retry.html: - * - * If BIO_should_retry() returns false then the precise "error - * condition" depends on the BIO type that caused it and the return - * code of the BIO operation. For example if a call to BIO_read() on a - * socket BIO returns 0 and BIO_should_retry() is false then the cause - * will be that the connection closed. - */ - if (read_ret < 0 || - (read_ret == 0 && !BIO_should_retry (openssl->bio))) { - return -1; - } - - if (expire) { - now = bson_get_monotonic_time (); - - if ((expire - now) < 0) { - if (read_ret == 0) { - mongoc_counter_streams_timeout_inc (); -#ifdef _WIN32 - errno = WSAETIMEDOUT; -#else - errno = ETIMEDOUT; -#endif - RETURN (-1); - } - - tls->timeout_msec = 0; - } else { - tls->timeout_msec = (expire - now) / 1000L; - } - } - - ret += read_ret; - - if ((size_t) ret >= min_bytes) { - mongoc_counter_streams_ingress_add (ret); - RETURN (ret); - } - - iov_pos += read_ret; - } - } - - if (ret >= 0) { - mongoc_counter_streams_ingress_add (ret); - } - - RETURN (ret); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_stream_tls_openssl_setsockopt -- - * - * Perform a setsockopt on the underlying stream. - * - * Returns: - * -1 on failure, otherwise opt specific value. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static int -_mongoc_stream_tls_openssl_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - - BSON_ASSERT (tls); - - return mongoc_stream_setsockopt ( - tls->base_stream, level, optname, optval, optlen); -} - - -static mongoc_stream_t * -_mongoc_stream_tls_openssl_get_base_stream (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - return tls->base_stream; -} - - -static bool -_mongoc_stream_tls_openssl_check_closed (mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - BSON_ASSERT (stream); - return mongoc_stream_check_closed (tls->base_stream); -} - - -/** - * mongoc_stream_tls_openssl_handshake: - */ -bool -mongoc_stream_tls_openssl_handshake (mongoc_stream_t *stream, - const char *host, - int *events, - bson_error_t *error) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_openssl_t *openssl = - (mongoc_stream_tls_openssl_t *) tls->ctx; - SSL *ssl; - - BSON_ASSERT (tls); - BSON_ASSERT (host); - ENTRY; - - BIO_get_ssl (openssl->bio, &ssl); - - if (BIO_do_handshake (openssl->bio) == 1) { - if (_mongoc_openssl_check_cert ( - ssl, host, tls->ssl_opts.allow_invalid_hostname)) { - RETURN (true); - } - - *events = 0; - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "TLS handshake failed: Failed certificate verification"); - - RETURN (false); - } - - if (BIO_should_retry (openssl->bio)) { - *events = BIO_should_read (openssl->bio) ? POLLIN : POLLOUT; - RETURN (false); - } - - if (!errno) { -#ifdef _WIN32 - errno = WSAETIMEDOUT; -#else - errno = ETIMEDOUT; -#endif - } - - - *events = 0; - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "TLS handshake failed: %s", - ERR_error_string (ERR_get_error (), NULL)); - - RETURN (false); -} - -/* Callback to get the client provided SNI, if any - * It is only called in SSL "server mode" (e.g. when using the Mock Server), - * and we don't actually use the hostname for anything, just debug print it - */ -static int -_mongoc_stream_tls_openssl_sni (SSL *ssl, int *ad, void *arg) -{ - const char *hostname; - - if (ssl == NULL) { - TRACE ("%s", "No SNI hostname provided"); - return SSL_TLSEXT_ERR_NOACK; - } - - hostname = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name); - /* This is intentionally debug since its only used by the mock test server */ - MONGOC_DEBUG ("Got SNI: '%s'", hostname); - - return SSL_TLSEXT_ERR_OK; -} - -static bool -_mongoc_stream_tls_openssl_timed_out (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - - ENTRY; - - RETURN (mongoc_stream_timed_out (tls->base_stream)); -} - -static bool -_mongoc_stream_tls_openssl_should_retry (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_openssl_t *openssl = - (mongoc_stream_tls_openssl_t *) tls->ctx; - - ENTRY; - - if (BIO_should_retry (openssl->bio)) { - RETURN (true); - } - - RETURN (mongoc_stream_should_retry (tls->base_stream)); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_openssl_new -- - * - * Creates a new mongoc_stream_tls_openssl_t to communicate with a remote - * server using a TLS stream. - * - * @base_stream should be a stream that will become owned by the - * resulting tls stream. It will be used for raw I/O. - * - * @trust_store_dir should be a path to the SSL cert db to use for - * verifying trust of the remote server. - * - * Returns: - * NULL on failure, otherwise a mongoc_stream_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_stream_t * -mongoc_stream_tls_openssl_new (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client) -{ - mongoc_stream_tls_t *tls; - mongoc_stream_tls_openssl_t *openssl; - SSL_CTX *ssl_ctx = NULL; - BIO *bio_ssl = NULL; - BIO *bio_mongoc_shim = NULL; - BIO_METHOD *meth; - - BSON_ASSERT (base_stream); - BSON_ASSERT (opt); - ENTRY; - - ssl_ctx = _mongoc_openssl_ctx_new (opt); - - if (!ssl_ctx) { - RETURN (NULL); - } - -#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) - if (!opt->allow_invalid_hostname) { - struct in_addr addr; - X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new (); - - X509_VERIFY_PARAM_set_hostflags (param, - X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); - if (inet_pton (AF_INET, host, &addr) || - inet_pton (AF_INET6, host, &addr)) { - X509_VERIFY_PARAM_set1_ip_asc (param, host); - } else { - X509_VERIFY_PARAM_set1_host (param, host, 0); - } - SSL_CTX_set1_param (ssl_ctx, param); - X509_VERIFY_PARAM_free (param); - } -#endif - - if (!client) { - /* Only used by the Mock Server. - * Set a callback to get the SNI, if provided */ - SSL_CTX_set_tlsext_servername_callback (ssl_ctx, - _mongoc_stream_tls_openssl_sni); - } - - if (opt->weak_cert_validation) { - SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL); - } else { - SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER, NULL); - } - - bio_ssl = BIO_new_ssl (ssl_ctx, client); - if (!bio_ssl) { - SSL_CTX_free (ssl_ctx); - RETURN (NULL); - } - meth = mongoc_stream_tls_openssl_bio_meth_new (); - bio_mongoc_shim = BIO_new (meth); - if (!bio_mongoc_shim) { - BIO_free_all (bio_ssl); - BIO_meth_free (meth); - RETURN (NULL); - } - -/* Added in OpenSSL 0.9.8f, as a build time option */ -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - if (client) { - SSL *ssl; - /* Set the SNI hostname we are expecting certificate for */ - BIO_get_ssl (bio_ssl, &ssl); - SSL_set_tlsext_host_name (ssl, host); -#endif - } - - - BIO_push (bio_ssl, bio_mongoc_shim); - - openssl = (mongoc_stream_tls_openssl_t *) bson_malloc0 (sizeof *openssl); - openssl->bio = bio_ssl; - openssl->meth = meth; - openssl->ctx = ssl_ctx; - - tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); - tls->parent.type = MONGOC_STREAM_TLS; - tls->parent.destroy = _mongoc_stream_tls_openssl_destroy; - tls->parent.failed = _mongoc_stream_tls_openssl_failed; - tls->parent.close = _mongoc_stream_tls_openssl_close; - tls->parent.flush = _mongoc_stream_tls_openssl_flush; - tls->parent.writev = _mongoc_stream_tls_openssl_writev; - tls->parent.readv = _mongoc_stream_tls_openssl_readv; - tls->parent.setsockopt = _mongoc_stream_tls_openssl_setsockopt; - tls->parent.get_base_stream = _mongoc_stream_tls_openssl_get_base_stream; - tls->parent.check_closed = _mongoc_stream_tls_openssl_check_closed; - tls->parent.timed_out = _mongoc_stream_tls_openssl_timed_out; - tls->parent.should_retry = _mongoc_stream_tls_openssl_should_retry; - memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); - tls->handshake = mongoc_stream_tls_openssl_handshake; - tls->ctx = (void *) openssl; - tls->timeout_msec = -1; - tls->base_stream = base_stream; - mongoc_stream_tls_openssl_bio_set_data (bio_mongoc_shim, tls); - - mongoc_counter_streams_active_inc (); - - RETURN ((mongoc_stream_t *) tls); -} - -#endif /* MONGOC_ENABLE_SSL_OPENSSL */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h deleted file mode 100644 index 92d0fae1288afe06ee43830db34e348afab2371c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_OPENSSL_H -#define MONGOC_STREAM_TLS_OPENSSL_H - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_tls_openssl_new (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client); - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_OPENSSL */ -#endif /* MONGOC_STREAM_TLS_OPENSSL_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-private.h deleted file mode 100644 index bb78d81af083a0a86b31716bafc7e3793e7f5072..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_PRIVATE_H -#define MONGOC_STREAM_TLS_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-stream.h" - -BSON_BEGIN_DECLS - -/** - * mongoc_stream_tls_t: - * - * Overloaded mongoc_stream_t with additional TLS handshake and verification - * callbacks. - * - */ -struct _mongoc_stream_tls_t { - mongoc_stream_t parent; /* The TLS stream wrapper */ - mongoc_stream_t *base_stream; /* The underlying actual stream */ - void *ctx; /* TLS lib specific configuration or wrappers */ - int32_t timeout_msec; - mongoc_ssl_opt_t ssl_opts; - bool (*handshake) (mongoc_stream_t *stream, - const char *host, - int *events /* OUT*/, - bson_error_t *error); -}; - - -BSON_END_DECLS - -#endif /* MONGOC_STREAM_TLS_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h deleted file mode 100644 index ad83da67825e4477b05731796e0551c34d288445..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_SECURE_CHANNEL_PRIVATE_H -#define MONGOC_STREAM_TLS_SECURE_CHANNEL_PRIVATE_H - -#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL -#include <bson/bson.h> - -/* Its mandatory to indicate to Windows who is compiling the code */ -#define SECURITY_WIN32 -#include <security.h> - - -BSON_BEGIN_DECLS - - -/* enum for the nonblocking SSL connection state machine */ -typedef enum { - ssl_connect_1, - ssl_connect_2, - ssl_connect_2_reading, - ssl_connect_2_writing, - ssl_connect_3, - ssl_connect_done -} ssl_connect_state; - -/* Structs to store Schannel handles */ -typedef struct { - CredHandle cred_handle; - TimeStamp time_stamp; -} mongoc_secure_channel_cred; - -typedef struct { - CtxtHandle ctxt_handle; - TimeStamp time_stamp; -} mongoc_secure_channel_ctxt; - -/** - * mongoc_stream_tls_secure_channel_t: - * - * Private storage for Secure Channel Streams - */ -typedef struct { - ssl_connect_state connecting_state; - mongoc_secure_channel_cred *cred; - mongoc_secure_channel_ctxt *ctxt; - SecPkgContext_StreamSizes stream_sizes; - size_t encdata_length, decdata_length; - size_t encdata_offset, decdata_offset; - unsigned char *encdata_buffer, *decdata_buffer; - unsigned long req_flags, ret_flags; - int recv_unrecoverable_err; /* _mongoc_stream_tls_secure_channel_read had an - unrecoverable err */ - bool recv_sspi_close_notify; /* true if connection closed by close_notify */ - bool recv_connection_closed; /* true if connection closed, regardless how */ -} mongoc_stream_tls_secure_channel_t; - - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_SECURE_CHANNEL */ -#endif /* MONGOC_STREAM_TLS_SECURE_CHANNEL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c deleted file mode 100644 index fb6a32749edb935ff1e830675d3e8a8443363f58..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c +++ /dev/null @@ -1,1060 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/** - * Significant portion of this file, such as - * _mongoc_stream_tls_secure_channel_write & - *_mongoc_stream_tls_secure_channel_read - * comes straight from one of my favorite projects, cURL! - * Thank you so much for having gone through the Secure Channel pain for me. - * - * - * Copyright (C) 2012 - 2015, Marc Hoersken, <info@marc-hoersken.de> - * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> - * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Based upon the PolarSSL implementation in polarssl.c and polarssl.h: - * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com> - * - * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * Thanks for code and inspiration! - */ - -#include "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL - -#include <bson/bson.h> - -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-tls-secure-channel-private.h" -#include "mongoc/mongoc-secure-channel-private.h" -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-errno-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-tls-secure-channel" - - -#define SECURITY_WIN32 -#include <security.h> -#include <schnlsp.h> -#include <schannel.h> - -/* mingw doesn't define these */ -#ifndef SP_PROT_TLS1_1_CLIENT -#define SP_PROT_TLS1_1_CLIENT 0x00000200 -#endif - -#ifndef SP_PROT_TLS1_2_CLIENT -#define SP_PROT_TLS1_2_CLIENT 0x00000800 -#endif - -size_t -mongoc_secure_channel_write (mongoc_stream_tls_t *tls, - const void *data, - size_t data_length); - - -static void -_mongoc_stream_tls_secure_channel_destroy (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_channel); - - - /* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx - * Shutting Down an Schannel Connection - */ - - TRACE ("shutting down SSL/TLS connection"); - - if (secure_channel->cred && secure_channel->ctxt) { - SecBufferDesc BuffDesc; - SecBuffer Buffer; - SECURITY_STATUS sspi_status; - SecBuffer outbuf; - SecBufferDesc outbuf_desc; - DWORD dwshut = SCHANNEL_SHUTDOWN; - - _mongoc_secure_channel_init_sec_buffer ( - &Buffer, SECBUFFER_TOKEN, &dwshut, sizeof (dwshut)); - _mongoc_secure_channel_init_sec_buffer_desc (&BuffDesc, &Buffer, 1); - - sspi_status = - ApplyControlToken (&secure_channel->ctxt->ctxt_handle, &BuffDesc); - - if (sspi_status != SEC_E_OK) { - MONGOC_ERROR ("ApplyControlToken failure: %d", sspi_status); - } - - /* setup output buffer */ - _mongoc_secure_channel_init_sec_buffer ( - &outbuf, SECBUFFER_EMPTY, NULL, 0); - _mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, &outbuf, 1); - - sspi_status = - InitializeSecurityContext (&secure_channel->cred->cred_handle, - &secure_channel->ctxt->ctxt_handle, - /*tls->hostname*/ NULL, - secure_channel->req_flags, - 0, - 0, - NULL, - 0, - &secure_channel->ctxt->ctxt_handle, - &outbuf_desc, - &secure_channel->ret_flags, - &secure_channel->ctxt->time_stamp); - - if ((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { - /* send close message which is in output buffer */ - ssize_t written = - mongoc_secure_channel_write (tls, outbuf.pvBuffer, outbuf.cbBuffer); - - FreeContextBuffer (outbuf.pvBuffer); - - if (outbuf.cbBuffer != (size_t) written) { - TRACE ("failed to send close msg (wrote %zd out of %zd)", - written, - outbuf.cbBuffer); - } - } - } - - /* free SSPI Schannel API security context handle */ - if (secure_channel->ctxt) { - TRACE ("clear security context handle"); - DeleteSecurityContext (&secure_channel->ctxt->ctxt_handle); - bson_free (secure_channel->ctxt); - } - - /* free SSPI Schannel API credential handle */ - if (secure_channel->cred) { - /* decrement the reference counter of the credential/session handle */ - /* if the handle was not cached and the refcount is zero */ - TRACE ("clear credential handle"); - FreeCredentialsHandle (&secure_channel->cred->cred_handle); - bson_free (secure_channel->cred); - } - - /* free internal buffer for received encrypted data */ - if (secure_channel->encdata_buffer != NULL) { - bson_free (secure_channel->encdata_buffer); - secure_channel->encdata_length = 0; - secure_channel->encdata_offset = 0; - } - - /* free internal buffer for received decrypted data */ - if (secure_channel->decdata_buffer != NULL) { - bson_free (secure_channel->decdata_buffer); - secure_channel->decdata_length = 0; - secure_channel->decdata_offset = 0; - } - - mongoc_stream_destroy (tls->base_stream); - - bson_free (secure_channel); - bson_free (stream); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); - EXIT; -} - -static void -_mongoc_stream_tls_secure_channel_failed (mongoc_stream_t *stream) -{ - ENTRY; - _mongoc_stream_tls_secure_channel_destroy (stream); - EXIT; -} - -static int -_mongoc_stream_tls_secure_channel_close (mongoc_stream_t *stream) -{ - int ret = 0; - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_channel); - - ret = mongoc_stream_close (tls->base_stream); - RETURN (ret); -} - -static int -_mongoc_stream_tls_secure_channel_flush (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_channel); - RETURN (0); -} - -static ssize_t -_mongoc_stream_tls_secure_channel_write (mongoc_stream_t *stream, - char *buf, - size_t buf_len) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - ssize_t written = -1; - size_t data_len = 0; - unsigned char *data = NULL; - SecBuffer outbuf[4]; - SecBufferDesc outbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - - ENTRY; - - BSON_ASSERT (secure_channel); - TRACE ("The entire buffer is: %d", buf_len); - - /* check if the maximum stream sizes were queried */ - if (secure_channel->stream_sizes.cbMaximumMessage == 0) { - sspi_status = QueryContextAttributes (&secure_channel->ctxt->ctxt_handle, - SECPKG_ATTR_STREAM_SIZES, - &secure_channel->stream_sizes); - - if (sspi_status != SEC_E_OK) { - TRACE ("failing here: %d", __LINE__); - return -1; - } - } - - /* check if the buffer is longer than the maximum message length */ - if (buf_len > secure_channel->stream_sizes.cbMaximumMessage) { - TRACE ("SHRINKING buf_len from %lu to %lu", - buf_len, - secure_channel->stream_sizes.cbMaximumMessage); - buf_len = secure_channel->stream_sizes.cbMaximumMessage; - } - - /* calculate the complete message length and allocate a buffer for it */ - data_len = secure_channel->stream_sizes.cbHeader + buf_len + - secure_channel->stream_sizes.cbTrailer; - data = (unsigned char *) bson_malloc (data_len); - - /* setup output buffers (header, data, trailer, empty) */ - _mongoc_secure_channel_init_sec_buffer ( - &outbuf[0], - SECBUFFER_STREAM_HEADER, - data, - secure_channel->stream_sizes.cbHeader); - _mongoc_secure_channel_init_sec_buffer ( - &outbuf[1], - SECBUFFER_DATA, - data + secure_channel->stream_sizes.cbHeader, - (unsigned long) (buf_len & (size_t) 0xFFFFFFFFUL)); - _mongoc_secure_channel_init_sec_buffer ( - &outbuf[2], - SECBUFFER_STREAM_TRAILER, - data + secure_channel->stream_sizes.cbHeader + buf_len, - secure_channel->stream_sizes.cbTrailer); - _mongoc_secure_channel_init_sec_buffer ( - &outbuf[3], SECBUFFER_EMPTY, NULL, 0); - _mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, outbuf, 4); - - /* copy data into output buffer */ - memcpy (outbuf[1].pvBuffer, buf, buf_len); - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */ - sspi_status = - EncryptMessage (&secure_channel->ctxt->ctxt_handle, 0, &outbuf_desc, 0); - - /* check if the message was encrypted */ - if (sspi_status == SEC_E_OK) { - written = 0; - - /* send the encrypted message including header, data and trailer */ - buf_len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer; - written = mongoc_secure_channel_write (tls, data, buf_len); - } else { - written = -1; - } - - bson_free (data); - - if (buf_len == (size_t) written) { - /* Encrypted message including header, data and trailer entirely sent. - * The return value is the number of unencrypted bytes that were sent. */ - written = outbuf[1].cbBuffer; - } - - return written; -} - -/* This is copypasta from _mongoc_stream_tls_openssl_writev */ -#define MONGOC_STREAM_TLS_BUFFER_SIZE 4096 -static ssize_t -_mongoc_stream_tls_secure_channel_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - char buf[MONGOC_STREAM_TLS_BUFFER_SIZE]; - ssize_t ret = 0; - ssize_t child_ret; - size_t i; - size_t iov_pos = 0; - - /* There's a bit of a dance to coalesce vectorized writes into - * MONGOC_STREAM_TLS_BUFFER_SIZE'd writes to avoid lots of small tls - * packets. - * - * The basic idea is that we want to combine writes in the buffer if they're - * smaller than the buffer, flushing as it gets full. For larger writes, or - * the last write in the iovec array, we want to ignore the buffer and just - * write immediately. We take care of doing buffer writes by re-invoking - * ourself with a single iovec_t, pointing at our stack buffer. - */ - char *buf_head = buf; - char *buf_tail = buf; - char *buf_end = buf + MONGOC_STREAM_TLS_BUFFER_SIZE; - size_t bytes; - - char *to_write = NULL; - size_t to_write_len; - - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - BSON_ASSERT (secure_channel); - ENTRY; - - TRACE ("Trying to write to the server"); - tls->timeout_msec = timeout_msec; - - TRACE ("count: %d, 0th: %lu", iovcnt, iov[0].iov_len); - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - TRACE ("iov %d size: %lu", i, iov[i].iov_len); - while (iov_pos < iov[i].iov_len) { - if (buf_head != buf_tail || - ((i + 1 < iovcnt) && - ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { - /* If we have either of: - * - buffered bytes already - * - another iovec to send after this one and we don't have more - * bytes to send than the size of the buffer. - * - * copy into the buffer */ - - bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); - - memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes); - buf_tail += bytes; - iov_pos += bytes; - - if (buf_tail == buf_end) { - /* If we're full, request send */ - - to_write = buf_head; - to_write_len = buf_tail - buf_head; - - buf_tail = buf_head = buf; - } - } else { - /* Didn't buffer, so just write it through */ - - to_write = (char *) iov[i].iov_base + iov_pos; - to_write_len = iov[i].iov_len - iov_pos; - - iov_pos += to_write_len; - } - - if (to_write) { - /* We get here if we buffered some bytes and filled the buffer, or - * if we didn't buffer and have to send out of the iovec */ - - child_ret = _mongoc_stream_tls_secure_channel_write ( - stream, to_write, to_write_len); - TRACE ("Child0wrote: %d, was supposed to write: %d", - child_ret, - to_write_len); - - if (child_ret < 0) { - RETURN (ret); - } - - ret += child_ret; - - iov_pos -= to_write_len - child_ret; - - to_write = NULL; - } - } - } - - if (buf_head != buf_tail) { - /* If we have any bytes buffered, send */ - - child_ret = _mongoc_stream_tls_secure_channel_write ( - stream, buf_head, buf_tail - buf_head); - TRACE ("Child1wrote: %d, was supposed to write: %d", - child_ret, - buf_tail - buf_head); - - if (child_ret < 0) { - RETURN (child_ret); - } - - ret += child_ret; - } - - if (ret >= 0) { - mongoc_counter_streams_egress_add (ret); - } - - TRACE ("Returning %d", (int) ret); - RETURN (ret); -} - - -/* move up to "len" decrypted bytes to buf, return number of bytes */ -static ssize_t -_mongoc_stream_tls_secure_channel_debuf ( - mongoc_stream_tls_secure_channel_t *secure_channel, char *buf, size_t size) -{ - size_t s = BSON_MIN (size, secure_channel->decdata_offset); - memcpy (buf, secure_channel->decdata_buffer, s); - memmove (secure_channel->decdata_buffer, - secure_channel->decdata_buffer + s, - secure_channel->decdata_offset - s); - - secure_channel->decdata_offset -= s; - - TRACE ("decrypted data returned %d", (int) s); - TRACE ("decrypted data buffer: offset %d length %d", - (int) secure_channel->decdata_offset, - (int) secure_channel->decdata_length); - - return (ssize_t) s; -} - - -/* decrypt as many received bytes as possible to secure_channel.decdata_buf */ -static void -_mongoc_stream_tls_secure_channel_decrypt ( - mongoc_stream_tls_secure_channel_t *secure_channel) -{ - size_t size = 0; - size_t remaining; - ssize_t nread = -1; - bool done = false; - SecBuffer inbuf[4]; - SecBufferDesc inbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - - TRACE ("encrypted data buffer: offset %d length %d", - (int) secure_channel->encdata_offset, - (int) secure_channel->encdata_length); - - /* decrypt loop */ - while (secure_channel->encdata_offset > 0 && sspi_status == SEC_E_OK) { - /* prepare data buffer for DecryptMessage call */ - _mongoc_secure_channel_init_sec_buffer ( - &inbuf[0], - SECBUFFER_DATA, - secure_channel->encdata_buffer, - (unsigned long) (secure_channel->encdata_offset & - (size_t) 0xFFFFFFFFUL)); - - /* we need 3 more empty input buffers for possible output */ - _mongoc_secure_channel_init_sec_buffer ( - &inbuf[1], SECBUFFER_EMPTY, NULL, 0); - _mongoc_secure_channel_init_sec_buffer ( - &inbuf[2], SECBUFFER_EMPTY, NULL, 0); - _mongoc_secure_channel_init_sec_buffer ( - &inbuf[3], SECBUFFER_EMPTY, NULL, 0); - _mongoc_secure_channel_init_sec_buffer_desc (&inbuf_desc, inbuf, 4); - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx - */ - sspi_status = DecryptMessage ( - &secure_channel->ctxt->ctxt_handle, &inbuf_desc, 0, NULL); - - /* check if everything went fine (server may want to renegotiate - * or shutdown the connection context) */ - if (sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE || - sspi_status == SEC_I_CONTEXT_EXPIRED) { - /* check for successfully decrypted data, even before actual - * renegotiation or shutdown of the connection context */ - if (inbuf[1].BufferType == SECBUFFER_DATA) { - TRACE ("decrypted data length: %lu", inbuf[1].cbBuffer); - - size = inbuf[1].cbBuffer; - remaining = - secure_channel->decdata_length - secure_channel->decdata_offset; - - if (remaining < size) { - mongoc_secure_channel_realloc_buf ( - &secure_channel->decdata_length, - &secure_channel->decdata_buffer, - size); - } - - /* copy decrypted data to internal buffer */ - if (size) { - memcpy (secure_channel->decdata_buffer + - secure_channel->decdata_offset, - inbuf[1].pvBuffer, - size); - secure_channel->decdata_offset += size; - } - - TRACE ("decrypted data added: %d", (int) size); - TRACE ("decrypted data cached: offset %d length %d", - (int) secure_channel->decdata_offset, - (int) secure_channel->decdata_length); - } - - /* check for remaining encrypted data */ - if (inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) { - TRACE ("encrypted data length: %lu", inbuf[3].cbBuffer); - - /* check if the remaining data is less than the total amount - * and therefore begins after the already processed data - */ - if (secure_channel->encdata_offset > inbuf[3].cbBuffer) { - /* move remaining encrypted data forward to the beginning of - * buffer */ - memmove (secure_channel->encdata_buffer, - (secure_channel->encdata_buffer + - secure_channel->encdata_offset) - - inbuf[3].cbBuffer, - inbuf[3].cbBuffer); - secure_channel->encdata_offset = inbuf[3].cbBuffer; - } - - TRACE ("encrypted data cached: offset %d length %d", - (int) secure_channel->encdata_offset, - (int) secure_channel->encdata_length); - } else { - /* reset encrypted buffer offset, because there is no data remaining - */ - secure_channel->encdata_offset = 0; - } - - /* check if server wants to renegotiate the connection context */ - if (sspi_status == SEC_I_RENEGOTIATE) { - TRACE ("remote party requests renegotiation"); - } - /* check if the server closed the connection */ - else if (sspi_status == SEC_I_CONTEXT_EXPIRED) { - /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not - * returned so we have to work around that in cleanup. */ - secure_channel->recv_sspi_close_notify = true; - - if (!secure_channel->recv_connection_closed) { - secure_channel->recv_connection_closed = true; - TRACE ("server closed the connection"); - } - } - } else if (sspi_status == SEC_E_INCOMPLETE_MESSAGE) { - TRACE ("failed to decrypt data, need more data"); - } else { - TRACE ("failed to read data from server: %d", sspi_status); - secure_channel->recv_unrecoverable_err = true; - } - } - - TRACE ("encrypted data buffer: offset %d length %d", - (int) secure_channel->encdata_offset, - (int) secure_channel->encdata_length); - - TRACE ("decrypted data buffer: offset %d length %d", - (int) secure_channel->decdata_offset, - (int) secure_channel->decdata_length); -} - - -static ssize_t -_mongoc_stream_tls_secure_channel_read (mongoc_stream_t *stream, - char *buf, - size_t len) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - ssize_t size = 0; - ssize_t nread; - - TRACE ("client wants to read %d bytes", (int) len); - BSON_ASSERT (len > 0); - - /* - * Our priority is to always return as much decrypted data to the caller as - * possible, even if an error occurs. The state of the decrypted buffer must - * always be valid. - */ - - if (secure_channel->decdata_offset) { - TRACE ("decrypted data is already available"); - return _mongoc_stream_tls_secure_channel_debuf (secure_channel, buf, len); - } - - /* is a complete encrypted block left from last network read? */ - if (secure_channel->encdata_offset) { - _mongoc_stream_tls_secure_channel_decrypt (secure_channel); - if (secure_channel->decdata_offset) { - return _mongoc_stream_tls_secure_channel_debuf ( - secure_channel, buf, len); - } - } - - /* keep these checks separated, for more detailed tracing */ - if (secure_channel->recv_unrecoverable_err) { - TRACE ("an unrecoverable error occurred in a prior call"); - return -1; - } - - if (secure_channel->recv_sspi_close_notify) { - TRACE ("server indicated shutdown in a prior call"); - return -1; - } - - if (secure_channel->recv_connection_closed) { - TRACE ("connection closed"); - return -1; - } - - size = secure_channel->encdata_length - secure_channel->encdata_offset; - - /* read encrypted data from socket. returns 0 on shutdown or error */ - nread = - mongoc_secure_channel_read (tls, - (char *) (secure_channel->encdata_buffer + - secure_channel->encdata_offset), - (size_t) size); - - if (!nread) { - if (MONGOC_ERRNO_IS_AGAIN (errno)) { - TRACE ("Try again"); - return 0; - } else { - secure_channel->recv_connection_closed = true; - TRACE ("reading failed: %d", errno); - return -1; - } - } - - secure_channel->encdata_offset += (size_t) nread; - TRACE ("encrypted data got %zd", nread); - - _mongoc_stream_tls_secure_channel_decrypt (secure_channel); - return _mongoc_stream_tls_secure_channel_debuf (secure_channel, buf, len); -} - - -/* This function is copypasta of _mongoc_stream_tls_openssl_readv */ -static ssize_t -_mongoc_stream_tls_secure_channel_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - ssize_t ret = 0; - size_t i; - size_t iov_pos = 0; - int64_t now; - int64_t expire = 0; - - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - BSON_ASSERT (secure_channel); - ENTRY; - - tls->timeout_msec = timeout_msec; - - if (timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (timeout_msec * 1000UL); - } - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - while (iov_pos < iov[i].iov_len) { - ssize_t read_ret = _mongoc_stream_tls_secure_channel_read ( - stream, - (char *) iov[i].iov_base + iov_pos, - (int) (iov[i].iov_len - iov_pos)); - - if (read_ret < 0) { - RETURN (-1); - } - - if (expire) { - now = bson_get_monotonic_time (); - - if ((expire - now) < 0) { - if (read_ret == 0) { - mongoc_counter_streams_timeout_inc (); - errno = ETIMEDOUT; - RETURN (-1); - } - - tls->timeout_msec = 0; - } else { - tls->timeout_msec = (expire - now) / 1000L; - } - } - - ret += read_ret; - - if ((size_t) ret >= min_bytes) { - mongoc_counter_streams_ingress_add (ret); - RETURN (ret); - } - - iov_pos += read_ret; - } - } - - if (ret >= 0) { - mongoc_counter_streams_ingress_add (ret); - } - - RETURN (ret); -} - -static int -_mongoc_stream_tls_secure_channel_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_channel); - RETURN (mongoc_stream_setsockopt ( - tls->base_stream, level, optname, optval, optlen)); -} - -static mongoc_stream_t * -_mongoc_stream_tls_secure_channel_get_base_stream (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_channel); - RETURN (tls->base_stream); -} - - -static bool -_mongoc_stream_tls_secure_channel_check_closed ( - mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_channel); - RETURN (mongoc_stream_check_closed (tls->base_stream)); -} - -bool -mongoc_stream_tls_secure_channel_handshake (mongoc_stream_t *stream, - const char *host, - int *events, - bson_error_t *error) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_channel_t *secure_channel = - (mongoc_stream_tls_secure_channel_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_channel); - - TRACE ("Getting ready for state: %d, timeout is %d", - secure_channel->connecting_state + 1, - tls->timeout_msec); - - switch (secure_channel->connecting_state) { - case ssl_connect_1: - - - if (mongoc_secure_channel_handshake_step_1 (tls, (char *) host)) { - TRACE ("Step#1 Worked!\n\n"); - *events = POLLIN; - RETURN (false); - } else { - TRACE ("Step#1 FAILED!"); - } - - break; - - case ssl_connect_2: - case ssl_connect_2_reading: - case ssl_connect_2_writing: - - if (mongoc_secure_channel_handshake_step_2 (tls, (char *) host)) { - if (secure_channel->connecting_state == ssl_connect_2_reading) { - *events = POLLIN; - } else { - *events = POLLOUT; - } - RETURN (false); - } else { - TRACE ("Step#2 FAILED!"); - } - - break; - - case ssl_connect_3: - - if (mongoc_secure_channel_handshake_step_3 (tls, (char *) host)) { - TRACE ("Step#3 Worked!\n\n"); - *events = POLLIN | POLLOUT; - RETURN (false); - } else { - TRACE ("Step#3 FAILED!"); - } - - break; - - case ssl_connect_done: - TRACE ("Connect DONE!"); - /* reset our connection state machine */ - secure_channel->connecting_state = ssl_connect_1; - RETURN (true); - break; - } - - - *events = 0; - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "TLS handshake failed"); - - RETURN (false); -} - -static bool -_mongoc_stream_tls_secure_channel_timed_out (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - - ENTRY; - - RETURN (mongoc_stream_timed_out (tls->base_stream)); -} - -static bool -_mongoc_stream_tls_secure_channel_should_retry (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - - ENTRY; - - RETURN (mongoc_stream_should_retry (tls->base_stream)); -} - -mongoc_stream_t * -mongoc_stream_tls_secure_channel_new (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client) -{ - SECURITY_STATUS sspi_status = SEC_E_OK; - SCHANNEL_CRED schannel_cred; - mongoc_stream_tls_t *tls; - mongoc_stream_tls_secure_channel_t *secure_channel; - PCCERT_CONTEXT cert = NULL; - - ENTRY; - BSON_ASSERT (base_stream); - BSON_ASSERT (opt); - - - secure_channel = (mongoc_stream_tls_secure_channel_t *) bson_malloc0 ( - sizeof *secure_channel); - - secure_channel->decdata_buffer = - bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE); - secure_channel->decdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE; - secure_channel->encdata_buffer = - bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE); - secure_channel->encdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE; - - tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); - tls->parent.type = MONGOC_STREAM_TLS; - tls->parent.destroy = _mongoc_stream_tls_secure_channel_destroy; - tls->parent.failed = _mongoc_stream_tls_secure_channel_failed; - tls->parent.close = _mongoc_stream_tls_secure_channel_close; - tls->parent.flush = _mongoc_stream_tls_secure_channel_flush; - tls->parent.writev = _mongoc_stream_tls_secure_channel_writev; - tls->parent.readv = _mongoc_stream_tls_secure_channel_readv; - tls->parent.setsockopt = _mongoc_stream_tls_secure_channel_setsockopt; - tls->parent.get_base_stream = - _mongoc_stream_tls_secure_channel_get_base_stream; - tls->parent.check_closed = _mongoc_stream_tls_secure_channel_check_closed; - tls->parent.timed_out = _mongoc_stream_tls_secure_channel_timed_out; - tls->parent.should_retry = _mongoc_stream_tls_secure_channel_should_retry; - memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); - tls->handshake = mongoc_stream_tls_secure_channel_handshake; - tls->ctx = (void *) secure_channel; - tls->timeout_msec = -1; - tls->base_stream = base_stream; - - TRACE ("SSL/TLS connection with endpoint AcquireCredentialsHandle"); - - /* setup Schannel API options */ - memset (&schannel_cred, 0, sizeof (schannel_cred)); - schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; - -/* SCHANNEL_CRED: - * SCH_USE_STRONG_CRYPTO is not available in VS2010 - * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379810.aspx */ -#ifdef SCH_USE_STRONG_CRYPTO - schannel_cred.dwFlags = SCH_USE_STRONG_CRYPTO; -#endif - if (opt->weak_cert_validation) { - schannel_cred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION | - SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; - TRACE ("disabled server certificate checks"); - } else { - schannel_cred.dwFlags |= - SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_REVOCATION_CHECK_CHAIN; - TRACE ("enabled server certificate checks"); - } - - if (opt->allow_invalid_hostname) { - schannel_cred.dwFlags |= - SCH_CRED_NO_SERVERNAME_CHECK | SCH_CRED_IGNORE_NO_REVOCATION_CHECK; - } - - if (opt->ca_file) { - mongoc_secure_channel_setup_ca (secure_channel, opt); - } - - if (opt->crl_file) { - mongoc_secure_channel_setup_crl (secure_channel, opt); - } - - if (opt->pem_file) { - cert = mongoc_secure_channel_setup_certificate (secure_channel, opt); - - if (cert) { - schannel_cred.cCreds = 1; - schannel_cred.paCred = &cert; - } - } - - - schannel_cred.grbitEnabledProtocols = - SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT; - - secure_channel->cred = (mongoc_secure_channel_cred *) bson_malloc0 ( - sizeof (mongoc_secure_channel_cred)); - - /* Example: - * https://msdn.microsoft.com/en-us/library/windows/desktop/aa375454%28v=vs.85%29.aspx - * AcquireCredentialsHandle: - * https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx - */ - sspi_status = AcquireCredentialsHandle ( - NULL, /* principal */ - UNISP_NAME, /* security package */ - SECPKG_CRED_OUTBOUND, /* we are preparing outbound connection */ - NULL, /* Optional logon */ - &schannel_cred, /* TLS "configuration", "auth data" */ - NULL, /* unused */ - NULL, /* unused */ - &secure_channel->cred->cred_handle, /* credential OUT param */ - &secure_channel->cred->time_stamp); /* certificate expiration time */ - - if (sspi_status != SEC_E_OK) { - LPTSTR msg = NULL; - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ARGUMENT_ARRAY, - NULL, - GetLastError (), - LANG_NEUTRAL, - (LPTSTR) &msg, - 0, - NULL); - MONGOC_ERROR ( - "Failed to initialize security context, error code: 0x%04X%04X: '%s'", - (sspi_status >> 16) & 0xffff, - sspi_status & 0xffff, - msg); - LocalFree (msg); - RETURN (NULL); - } - - if (opt->ca_dir) { - MONGOC_ERROR ("Setting mongoc_ssl_opt_t.ca_dir has no effect when built " - "against Secure Channel"); - } - - - mongoc_counter_streams_active_inc (); - RETURN ((mongoc_stream_t *) tls); -} -#endif /* MONGOC_ENABLE_SSL_SECURE_CHANNEL */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h deleted file mode 100644 index f5c0e5442fea4e1ee400d6d254514d32565c7b00..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_SECURE_CHANNEL_H -#define MONGOC_STREAM_TLS_SECURE_CHANNEL_H - -#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_tls_secure_channel_new (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client); - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_SECURE_CHANNEL */ -#endif /* MONGOC_STREAM_TLS_SECURE_CHANNEL_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h deleted file mode 100644 index 5faf5f6b0a84b2cd124da289cc9debdbc83798c5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_SECURE_TRANSPORT_PRIVATE_H -#define MONGOC_STREAM_TLS_SECURE_TRANSPORT_PRIVATE_H - -#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT -#include <bson/bson.h> - -#include <Security/Security.h> - -BSON_BEGIN_DECLS - - -/** - * mongoc_stream_tls_secure_transport_t: - * - * Private storage for Secure Transport Streams - */ -typedef struct { - SSLContextRef ssl_ctx_ref; - CFArrayRef anchors; - CFMutableArrayRef my_cert; -} mongoc_stream_tls_secure_transport_t; - - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_SECURE_TRANSPORT */ -#endif /* MONGOC_STREAM_TLS_SECURE_TRANSPORT_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c deleted file mode 100644 index 206540c2ed5db90768707348cd0a9377d9bd96a0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT - -#include <Security/Security.h> -#include <Security/SecureTransport.h> -#include <CoreFoundation/CoreFoundation.h> - - -#include <bson/bson.h> - -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-secure-transport-private.h" -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-tls-secure-transport-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-tls-secure_transport" - -static void -_mongoc_stream_tls_secure_transport_destroy (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_transport); - - SSLClose (secure_transport->ssl_ctx_ref); - CFRelease (secure_transport->ssl_ctx_ref); - secure_transport->ssl_ctx_ref = NULL; - - /* SSLClose will do IO so destroy must come after */ - mongoc_stream_destroy (tls->base_stream); - - if (secure_transport->anchors) { - CFRelease (secure_transport->anchors); - } - if (secure_transport->my_cert) { - CFRelease (secure_transport->my_cert); - } - bson_free (secure_transport); - bson_free (stream); - - mongoc_counter_streams_active_dec (); - mongoc_counter_streams_disposed_inc (); - EXIT; -} - -static void -_mongoc_stream_tls_secure_transport_failed (mongoc_stream_t *stream) -{ - ENTRY; - _mongoc_stream_tls_secure_transport_destroy (stream); - EXIT; -} - -static int -_mongoc_stream_tls_secure_transport_close (mongoc_stream_t *stream) -{ - int ret = 0; - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_transport); - - ret = mongoc_stream_close (tls->base_stream); - RETURN (ret); -} - -static int -_mongoc_stream_tls_secure_transport_flush (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_transport); - RETURN (0); -} - -static ssize_t -_mongoc_stream_tls_secure_transport_write (mongoc_stream_t *stream, - char *buf, - size_t buf_len) -{ - OSStatus status; - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - ssize_t write_ret; - int64_t now; - int64_t expire = 0; - - ENTRY; - BSON_ASSERT (secure_transport); - - if (tls->timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL); - } - - status = SSLWrite ( - secure_transport->ssl_ctx_ref, buf, buf_len, (size_t *) &write_ret); - - switch (status) { - case errSSLWouldBlock: - case noErr: - break; - - case errSSLClosedAbort: - errno = ECONNRESET; - - default: - RETURN (-1); - } - - if (expire) { - now = bson_get_monotonic_time (); - - if ((expire - now) < 0) { - if (write_ret < buf_len) { - mongoc_counter_streams_timeout_inc (); - } - - tls->timeout_msec = 0; - } else { - tls->timeout_msec = (expire - now) / 1000L; - } - } - - RETURN (write_ret); -} - -/* This is copypasta from _mongoc_stream_tls_openssl_writev */ -#define MONGOC_STREAM_TLS_BUFFER_SIZE 4096 -static ssize_t -_mongoc_stream_tls_secure_transport_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - char buf[MONGOC_STREAM_TLS_BUFFER_SIZE]; - ssize_t ret = 0; - ssize_t child_ret; - size_t i; - size_t iov_pos = 0; - - /* There's a bit of a dance to coalesce vectorized writes into - * MONGOC_STREAM_TLS_BUFFER_SIZE'd writes to avoid lots of small tls - * packets. - * - * The basic idea is that we want to combine writes in the buffer if they're - * smaller than the buffer, flushing as it gets full. For larger writes, or - * the last write in the iovec array, we want to ignore the buffer and just - * write immediately. We take care of doing buffer writes by re-invoking - * ourself with a single iovec_t, pointing at our stack buffer. - */ - char *buf_head = buf; - char *buf_tail = buf; - char *buf_end = buf + MONGOC_STREAM_TLS_BUFFER_SIZE; - size_t bytes; - - char *to_write = NULL; - size_t to_write_len; - - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - BSON_ASSERT (secure_transport); - ENTRY; - - tls->timeout_msec = timeout_msec; - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - while (iov_pos < iov[i].iov_len) { - if (buf_head != buf_tail || - ((i + 1 < iovcnt) && - ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { - /* If we have either of: - * - buffered bytes already - * - another iovec to send after this one and we don't have more - * bytes to send than the size of the buffer. - * - * copy into the buffer */ - - bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); - - memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes); - buf_tail += bytes; - iov_pos += bytes; - - if (buf_tail == buf_end) { - /* If we're full, request send */ - - to_write = buf_head; - to_write_len = buf_tail - buf_head; - - buf_tail = buf_head = buf; - } - } else { - /* Didn't buffer, so just write it through */ - - to_write = (char *) iov[i].iov_base + iov_pos; - to_write_len = iov[i].iov_len - iov_pos; - - iov_pos += to_write_len; - } - - if (to_write) { - /* We get here if we buffered some bytes and filled the buffer, or - * if we didn't buffer and have to send out of the iovec */ - - child_ret = _mongoc_stream_tls_secure_transport_write ( - stream, to_write, to_write_len); - - if (child_ret < 0) { - RETURN (ret); - } - - ret += child_ret; - - if (child_ret < to_write_len) { - /* we timed out, so send back what we could send */ - - RETURN (ret); - } - - to_write = NULL; - } - } - } - - if (buf_head != buf_tail) { - /* If we have any bytes buffered, send */ - - child_ret = _mongoc_stream_tls_secure_transport_write ( - stream, buf_head, buf_tail - buf_head); - - if (child_ret < 0) { - RETURN (child_ret); - } - - ret += child_ret; - } - - if (ret >= 0) { - mongoc_counter_streams_egress_add (ret); - } - - TRACE ("Returning %d", (int) ret); - RETURN (ret); -} - -/* This function is copypasta of _mongoc_stream_tls_openssl_readv */ -static ssize_t -_mongoc_stream_tls_secure_transport_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - ssize_t ret = 0; - size_t i; - size_t read_ret; - size_t iov_pos = 0; - int64_t now; - int64_t expire = 0; - size_t to_read; - size_t remaining_buf_size; - size_t remaining_to_read; - - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - BSON_ASSERT (secure_transport); - ENTRY; - - tls->timeout_msec = timeout_msec; - - if (timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (timeout_msec * 1000UL); - } - - for (i = 0; i < iovcnt; i++) { - iov_pos = 0; - - while (iov_pos < iov[i].iov_len) { - - remaining_buf_size = iov[i].iov_len - iov_pos; - remaining_to_read = min_bytes - ret; - - /* The third argument passed to SSLRead is an all-or-nothing - dataLength, which it will attempt to read until it succeeds or - times out. If our buffer is larger than the message we expect - to read, choose the smaller number of the two. */ - if (remaining_to_read > 0 && remaining_to_read < remaining_buf_size) { - to_read = remaining_to_read; - } else { - to_read = remaining_buf_size; - } - - OSStatus status = SSLRead (secure_transport->ssl_ctx_ref, - (char *) iov[i].iov_base + iov_pos, - to_read, - &read_ret); - - if (status != noErr) { - RETURN (-1); - } - - if (expire) { - now = bson_get_monotonic_time (); - - if ((expire - now) < 0) { - if (read_ret == 0) { - mongoc_counter_streams_timeout_inc (); - errno = ETIMEDOUT; - RETURN (-1); - } - - tls->timeout_msec = 0; - } else { - tls->timeout_msec = (expire - now) / 1000L; - } - } - - ret += read_ret; - - if ((size_t) ret >= min_bytes) { - mongoc_counter_streams_ingress_add (ret); - RETURN (ret); - } - - iov_pos += read_ret; - } - } - - if (ret >= 0) { - mongoc_counter_streams_ingress_add (ret); - } - - RETURN (ret); -} - -static int -_mongoc_stream_tls_secure_transport_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_transport); - RETURN (mongoc_stream_setsockopt ( - tls->base_stream, level, optname, optval, optlen)); -} - -static mongoc_stream_t * -_mongoc_stream_tls_secure_transport_get_base_stream (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_transport); - RETURN (tls->base_stream); -} - - -static bool -_mongoc_stream_tls_secure_transport_check_closed ( - mongoc_stream_t *stream) /* IN */ -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_transport); - RETURN (mongoc_stream_check_closed (tls->base_stream)); -} - -bool -mongoc_stream_tls_secure_transport_handshake (mongoc_stream_t *stream, - const char *host, - int *events, - bson_error_t *error) -{ - OSStatus ret = 0; - CFStringRef err; - char *err_str; - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - mongoc_stream_tls_secure_transport_t *secure_transport = - (mongoc_stream_tls_secure_transport_t *) tls->ctx; - - ENTRY; - BSON_ASSERT (secure_transport); - - ret = SSLHandshake (secure_transport->ssl_ctx_ref); - /* Weak certificate validation requested, eg: none */ - - if (ret == errSSLServerAuthCompleted) { - ret = errSSLWouldBlock; - } - - if (ret == noErr) { - RETURN (true); - } - - if (ret == errSSLWouldBlock) { - *events = POLLIN | POLLOUT; - } else { - *events = 0; - err = SecCopyErrorMessageString (ret, NULL); - err_str = _mongoc_cfstringref_to_cstring (err); - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "TLS handshake failed: %s (%d)", - err_str, - ret); - - bson_free (err_str); - CFRelease (err); - } - - RETURN (false); -} - -static bool -_mongoc_stream_tls_secure_channel_timed_out (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - - ENTRY; - - RETURN (mongoc_stream_timed_out (tls->base_stream)); -} - -static bool -_mongoc_stream_tls_secure_channel_should_retry (mongoc_stream_t *stream) -{ - mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; - - ENTRY; - - RETURN (mongoc_stream_should_retry (tls->base_stream)); -} - -mongoc_stream_t * -mongoc_stream_tls_secure_transport_new (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client) -{ - mongoc_stream_tls_t *tls; - mongoc_stream_tls_secure_transport_t *secure_transport; - - ENTRY; - BSON_ASSERT (base_stream); - BSON_ASSERT (opt); - - if (opt->ca_dir) { - MONGOC_ERROR ("Setting mongoc_ssl_opt_t.ca_dir has no effect when built " - "against Secure Transport"); - RETURN (NULL); - } - if (opt->crl_file) { - MONGOC_ERROR ( - "Setting mongoc_ssl_opt_t.crl_file has no effect when built " - "against Secure Transport"); - RETURN (NULL); - } - - secure_transport = (mongoc_stream_tls_secure_transport_t *) bson_malloc0 ( - sizeof *secure_transport); - - tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); - tls->parent.type = MONGOC_STREAM_TLS; - tls->parent.destroy = _mongoc_stream_tls_secure_transport_destroy; - tls->parent.failed = _mongoc_stream_tls_secure_transport_failed; - tls->parent.close = _mongoc_stream_tls_secure_transport_close; - tls->parent.flush = _mongoc_stream_tls_secure_transport_flush; - tls->parent.writev = _mongoc_stream_tls_secure_transport_writev; - tls->parent.readv = _mongoc_stream_tls_secure_transport_readv; - tls->parent.setsockopt = _mongoc_stream_tls_secure_transport_setsockopt; - tls->parent.get_base_stream = - _mongoc_stream_tls_secure_transport_get_base_stream; - tls->parent.check_closed = _mongoc_stream_tls_secure_transport_check_closed; - tls->parent.timed_out = _mongoc_stream_tls_secure_channel_timed_out; - tls->parent.should_retry = _mongoc_stream_tls_secure_channel_should_retry; - memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); - tls->handshake = mongoc_stream_tls_secure_transport_handshake; - tls->ctx = (void *) secure_transport; - tls->timeout_msec = -1; - - secure_transport->ssl_ctx_ref = - SSLCreateContext (kCFAllocatorDefault, - client ? kSSLClientSide : kSSLServerSide, - kSSLStreamType); - - SSLSetIOFuncs (secure_transport->ssl_ctx_ref, - mongoc_secure_transport_read, - mongoc_secure_transport_write); - SSLSetProtocolVersionMin (secure_transport->ssl_ctx_ref, kTLSProtocol1); - - if (opt->pem_file && - !mongoc_secure_transport_setup_certificate (secure_transport, opt)) { - mongoc_stream_destroy ((mongoc_stream_t *) tls); - RETURN (NULL); - } - - if (opt->ca_file && - !mongoc_secure_transport_setup_ca (secure_transport, opt)) { - mongoc_stream_destroy ((mongoc_stream_t *) tls); - RETURN (NULL); - } - - /* don't link base_stream to tls until we're sure we won't destroy tls */ - tls->base_stream = base_stream; - - if (client) { - SSLSetSessionOption (secure_transport->ssl_ctx_ref, - kSSLSessionOptionBreakOnServerAuth, - opt->weak_cert_validation); - } else if (!opt->allow_invalid_hostname) { - /* used only in mock_server_t tests */ - SSLSetClientSideAuthenticate (secure_transport->ssl_ctx_ref, - kAlwaysAuthenticate); - } - - if (!opt->allow_invalid_hostname) { - SSLSetPeerDomainName (secure_transport->ssl_ctx_ref, host, strlen (host)); - } - SSLSetConnection (secure_transport->ssl_ctx_ref, tls); - - - mongoc_counter_streams_active_inc (); - RETURN ((mongoc_stream_t *) tls); -} -#endif /* MONGOC_ENABLE_SSL_SECURE_TRANSPORT */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h deleted file mode 100644 index 7dac2650b9b8547e5c42b263d7b3583bd1b12722..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_SECURE_TRANSPORT_H -#define MONGOC_STREAM_TLS_SECURE_TRANSPORT_H - -#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_tls_secure_transport_new (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client); - -BSON_END_DECLS - -#endif /* MONGOC_ENABLE_SSL_SECURE_TRANSPORT */ -#endif /* MONGOC_STREAM_TLS_SECURE_TRANSPORT_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls.c deleted file mode 100644 index a95cd115491b79ee063df93f12fff3f28faa892e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-config.h" - -#ifdef MONGOC_ENABLE_SSL - -#include <errno.h> -#include <string.h> -#include <bson/bson.h> - -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-error.h" - -#include "mongoc/mongoc-stream-tls-private.h" -#include "mongoc/mongoc-stream-private.h" -#if defined(MONGOC_ENABLE_SSL_OPENSSL) -#include "mongoc/mongoc-stream-tls-openssl.h" -#include "mongoc/mongoc-openssl-private.h" -#elif defined(MONGOC_ENABLE_SSL_LIBRESSL) -#include "mongoc/mongoc-libressl-private.h" -#include "mongoc/mongoc-stream-tls-libressl.h" -#elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) -#include "mongoc/mongoc-secure-transport-private.h" -#include "mongoc/mongoc-stream-tls-secure-transport.h" -#elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) -#include "mongoc/mongoc-secure-channel-private.h" -#include "mongoc/mongoc-stream-tls-secure-channel.h" -#endif -#include "mongoc/mongoc-stream-tls.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream-tls" - - -/** - * mongoc_stream_tls_handshake: - * - * Performs TLS handshake dance - */ -bool -mongoc_stream_tls_handshake (mongoc_stream_t *stream, - const char *host, - int32_t timeout_msec, - int *events, - bson_error_t *error) -{ - mongoc_stream_tls_t *stream_tls = - (mongoc_stream_tls_t *) mongoc_stream_get_tls_stream (stream); - - BSON_ASSERT (stream_tls); - BSON_ASSERT (stream_tls->handshake); - - stream_tls->timeout_msec = timeout_msec; - - return stream_tls->handshake (stream, host, events, error); -} - -bool -mongoc_stream_tls_handshake_block (mongoc_stream_t *stream, - const char *host, - int32_t timeout_msec, - bson_error_t *error) -{ - int events; - ssize_t ret = 0; - mongoc_stream_poll_t poller; - int64_t now; - int64_t expire = 0; - - if (timeout_msec >= 0) { - expire = bson_get_monotonic_time () + (timeout_msec * 1000UL); - } - - /* - * error variables get re-used a lot. To prevent cross-contamination of error - * messages, and still be able to provide a generic failure message when - * mongoc_stream_tls_handshake fails without a specific reason, we need to - * init - * the error code to 0. - */ - if (error) { - error->code = 0; - } - do { - events = 0; - - if (mongoc_stream_tls_handshake ( - stream, host, timeout_msec, &events, error)) { - return true; - } - - if (events) { - poller.stream = stream; - poller.events = events; - poller.revents = 0; - - if (expire) { - now = bson_get_monotonic_time (); - if ((expire - now) < 0) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "TLS handshake timed out."); - return false; - } else { - timeout_msec = (expire - now) / 1000L; - } - } - ret = mongoc_stream_poll (&poller, 1, timeout_msec); - } - } while (events && ret > 0); - - if (error && !error->code) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "TLS handshake failed."); - } - return false; -} -/** - * Deprecated. Was never supposed to be part of the public API. - * See mongoc_stream_tls_handshake. - */ -bool -mongoc_stream_tls_do_handshake (mongoc_stream_t *stream, int32_t timeout_msec) -{ - mongoc_stream_tls_t *stream_tls = - (mongoc_stream_tls_t *) mongoc_stream_get_tls_stream (stream); - - BSON_ASSERT (stream_tls); - - MONGOC_ERROR ("This function doesn't do anything. Please call " - "mongoc_stream_tls_handshake()"); - return false; -} - - -/** - * Deprecated. Was never supposed to be part of the public API. - * See mongoc_stream_tls_handshake. - */ -bool -mongoc_stream_tls_check_cert (mongoc_stream_t *stream, const char *host) -{ - mongoc_stream_tls_t *stream_tls = - (mongoc_stream_tls_t *) mongoc_stream_get_tls_stream (stream); - - BSON_ASSERT (stream_tls); - - MONGOC_ERROR ("This function doesn't do anything. Please call " - "mongoc_stream_tls_handshake()"); - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_stream_tls_new_with_hostname -- - * - * Creates a new mongoc_stream_tls_t to communicate with a remote - * server using a TLS stream. - * - * @host the hostname we are connected to and to verify the - * server certificate against - * - * @base_stream should be a stream that will become owned by the - * resulting tls stream. It will be used for raw I/O. - * - * @trust_store_dir should be a path to the SSL cert db to use for - * verifying trust of the remote server. - * - * Returns: - * NULL on failure, otherwise a mongoc_stream_t. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mongoc_stream_t * -mongoc_stream_tls_new_with_hostname (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client) -{ - BSON_ASSERT (base_stream); - - /* !client is only used for testing, - * when the streams are pretending to be the server */ - if (!client || opt->weak_cert_validation) { - opt->allow_invalid_hostname = true; - } - -#ifndef _WIN32 - /* Silly check for Unix Domain Sockets */ - if (!host || (host[0] == '/' && !access (host, F_OK))) { - opt->allow_invalid_hostname = true; - } -#endif - -#if defined(MONGOC_ENABLE_SSL_OPENSSL) - return mongoc_stream_tls_openssl_new (base_stream, host, opt, client); -#elif defined(MONGOC_ENABLE_SSL_LIBRESSL) - return mongoc_stream_tls_libressl_new (base_stream, host, opt, client); -#elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) - return mongoc_stream_tls_secure_transport_new ( - base_stream, host, opt, client); -#elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) - return mongoc_stream_tls_secure_channel_new (base_stream, host, opt, client); -#else -#error "Don't know how to create TLS stream" -#endif -} - -mongoc_stream_t * -mongoc_stream_tls_new (mongoc_stream_t *base_stream, - mongoc_ssl_opt_t *opt, - int client) -{ - return mongoc_stream_tls_new_with_hostname (base_stream, NULL, opt, client); -} - -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls.h deleted file mode 100644 index 3605c0388f6630e0338999eb086c2071fb90ac74..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream-tls.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_TLS_H -#define MONGOC_STREAM_TLS_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-ssl.h" -#include "mongoc/mongoc-stream.h" - - -BSON_BEGIN_DECLS - -typedef struct _mongoc_stream_tls_t mongoc_stream_tls_t; - -MONGOC_EXPORT (bool) -mongoc_stream_tls_handshake (mongoc_stream_t *stream, - const char *host, - int32_t timeout_msec, - int *events, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_stream_tls_handshake_block (mongoc_stream_t *stream, - const char *host, - int32_t timeout_msec, - bson_error_t *error); -MONGOC_EXPORT (bool) -mongoc_stream_tls_do_handshake (mongoc_stream_t *stream, int32_t timeout_msec) - BSON_GNUC_DEPRECATED_FOR (mongoc_stream_tls_handshake); -MONGOC_EXPORT (bool) -mongoc_stream_tls_check_cert (mongoc_stream_t *stream, const char *host) - BSON_GNUC_DEPRECATED_FOR (mongoc_stream_tls_handshake); -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_tls_new_with_hostname (mongoc_stream_t *base_stream, - const char *host, - mongoc_ssl_opt_t *opt, - int client); -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_tls_new (mongoc_stream_t *base_stream, - mongoc_ssl_opt_t *opt, - int client) - BSON_GNUC_DEPRECATED_FOR (mongoc_stream_tls_new_with_hostname); - - -BSON_END_DECLS - - -#endif /* MONGOC_STREAM_TLS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream.c deleted file mode 100644 index 10fc783114495afa53a79871e04071efcb88094e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright 2013 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 <bson/bson.h> - -#include "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-buffer-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-errno-private.h" -#include "mongoc/mongoc-flags.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-opcode.h" -#include "mongoc/mongoc-rpc-private.h" -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "stream" - -#ifndef MONGOC_DEFAULT_TIMEOUT_MSEC -#define MONGOC_DEFAULT_TIMEOUT_MSEC (60L * 60L * 1000L) -#endif - - -/** - * mongoc_stream_close: - * @stream: A mongoc_stream_t. - * - * Closes the underlying file-descriptor used by @stream. - * - * Returns: 0 on success, -1 on failure. - */ -int -mongoc_stream_close (mongoc_stream_t *stream) -{ - int ret; - - ENTRY; - - BSON_ASSERT (stream); - - BSON_ASSERT (stream->close); - - ret = stream->close (stream); - - RETURN (ret); -} - - -/** - * mongoc_stream_failed: - * @stream: A mongoc_stream_t. - * - * Frees any resources referenced by @stream, including the memory allocation - * for @stream. - * This handler is called upon stream failure, such as network errors, invalid - * replies - * or replicaset reconfigures deleting the stream - */ -void -mongoc_stream_failed (mongoc_stream_t *stream) -{ - ENTRY; - - BSON_ASSERT (stream); - - if (stream->failed) { - stream->failed (stream); - } else { - stream->destroy (stream); - } - - EXIT; -} - - -/** - * mongoc_stream_destroy: - * @stream: A mongoc_stream_t. - * - * Frees any resources referenced by @stream, including the memory allocation - * for @stream. - */ -void -mongoc_stream_destroy (mongoc_stream_t *stream) -{ - ENTRY; - - if (!stream) { - EXIT; - } - - BSON_ASSERT (stream->destroy); - - stream->destroy (stream); - - EXIT; -} - - -/** - * mongoc_stream_flush: - * @stream: A mongoc_stream_t. - * - * Flushes the data in the underlying stream to the transport. - * - * Returns: 0 on success, -1 on failure. - */ -int -mongoc_stream_flush (mongoc_stream_t *stream) -{ - BSON_ASSERT (stream); - return stream->flush (stream); -} - - -/** - * mongoc_stream_writev: - * @stream: A mongoc_stream_t. - * @iov: An array of iovec to write to the stream. - * @iovcnt: The number of elements in @iov. - * - * Writes an array of iovec buffers to the underlying stream. - * - * Returns: the number of bytes written, or -1 upon failure. - */ -ssize_t -mongoc_stream_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - ssize_t ret; - - ENTRY; - - BSON_ASSERT (stream); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - BSON_ASSERT (stream->writev); - - if (timeout_msec < 0) { - timeout_msec = MONGOC_DEFAULT_TIMEOUT_MSEC; - } - - DUMP_IOVEC (writev, iov, iovcnt); - ret = stream->writev (stream, iov, iovcnt, timeout_msec); - - RETURN (ret); -} - -/** - * mongoc_stream_write: - * @stream: A mongoc_stream_t. - * @buf: A buffer to write. - * @count: The number of bytes to write into @buf. - * - * Simplified access to mongoc_stream_writev(). Creates a single iovec - * with the buffer provided. - * - * Returns: -1 on failure, otherwise the number of bytes written. - */ -ssize_t -mongoc_stream_write (mongoc_stream_t *stream, - void *buf, - size_t count, - int32_t timeout_msec) -{ - mongoc_iovec_t iov; - ssize_t ret; - - ENTRY; - - BSON_ASSERT (stream); - BSON_ASSERT (buf); - - iov.iov_base = buf; - iov.iov_len = count; - - BSON_ASSERT (stream->writev); - - ret = mongoc_stream_writev (stream, &iov, 1, timeout_msec); - - RETURN (ret); -} - -/** - * mongoc_stream_readv: - * @stream: A mongoc_stream_t. - * @iov: An array of iovec containing the location and sizes to read. - * @iovcnt: the number of elements in @iov. - * @min_bytes: the minimum number of bytes to return, or -1. - * - * Reads into the various buffers pointed to by @iov and associated - * buffer lengths. - * - * If @min_bytes is specified, then at least min_bytes will be returned unless - * eof is encountered. This may result in ETIMEDOUT - * - * Returns: the number of bytes read or -1 on failure. - */ -ssize_t -mongoc_stream_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - ssize_t ret; - - ENTRY; - - BSON_ASSERT (stream); - BSON_ASSERT (iov); - BSON_ASSERT (iovcnt); - - BSON_ASSERT (stream->readv); - - ret = stream->readv (stream, iov, iovcnt, min_bytes, timeout_msec); - if (ret >= 0) { - DUMP_IOVEC (readv, iov, iovcnt); - } - - RETURN (ret); -} - - -/** - * mongoc_stream_read: - * @stream: A mongoc_stream_t. - * @buf: A buffer to write into. - * @count: The number of bytes to write into @buf. - * @min_bytes: The minimum number of bytes to receive - * - * Simplified access to mongoc_stream_readv(). Creates a single iovec - * with the buffer provided. - * - * If @min_bytes is specified, then at least min_bytes will be returned unless - * eof is encountered. This may result in ETIMEDOUT - * - * Returns: -1 on failure, otherwise the number of bytes read. - */ -ssize_t -mongoc_stream_read (mongoc_stream_t *stream, - void *buf, - size_t count, - size_t min_bytes, - int32_t timeout_msec) -{ - mongoc_iovec_t iov; - ssize_t ret; - - ENTRY; - - BSON_ASSERT (stream); - BSON_ASSERT (buf); - - iov.iov_base = buf; - iov.iov_len = count; - - BSON_ASSERT (stream->readv); - - ret = mongoc_stream_readv (stream, &iov, 1, min_bytes, timeout_msec); - - RETURN (ret); -} - - -int -mongoc_stream_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen) -{ - BSON_ASSERT (stream); - - if (stream->setsockopt) { - return stream->setsockopt (stream, level, optname, optval, optlen); - } - - return 0; -} - - -mongoc_stream_t * -mongoc_stream_get_base_stream (mongoc_stream_t *stream) /* IN */ -{ - BSON_ASSERT (stream); - - if (stream->get_base_stream) { - return stream->get_base_stream (stream); - } - - return stream; -} - - -mongoc_stream_t * -mongoc_stream_get_root_stream (mongoc_stream_t *stream) -{ - BSON_ASSERT (stream); - - while (stream->get_base_stream) { - stream = stream->get_base_stream (stream); - } - - return stream; -} - -mongoc_stream_t * -mongoc_stream_get_tls_stream (mongoc_stream_t *stream) /* IN */ -{ - BSON_ASSERT (stream); - - for (; stream && stream->type != MONGOC_STREAM_TLS; - stream = stream->get_base_stream (stream)) - ; - - return stream; -} - -ssize_t -mongoc_stream_poll (mongoc_stream_poll_t *streams, - size_t nstreams, - int32_t timeout) -{ - mongoc_stream_poll_t *poller = - (mongoc_stream_poll_t *) bson_malloc (sizeof (*poller) * nstreams); - - int i; - int last_type = 0; - ssize_t rval = -1; - - errno = 0; - - for (i = 0; i < nstreams; i++) { - poller[i].stream = mongoc_stream_get_root_stream (streams[i].stream); - poller[i].events = streams[i].events; - poller[i].revents = 0; - - if (i == 0) { - last_type = poller[i].stream->type; - } else if (last_type != poller[i].stream->type) { - errno = EINVAL; - goto CLEANUP; - } - } - - if (!poller[0].stream->poll) { - errno = EINVAL; - goto CLEANUP; - } - - rval = poller[0].stream->poll (poller, nstreams, timeout); - - if (rval > 0) { - for (i = 0; i < nstreams; i++) { - streams[i].revents = poller[i].revents; - } - } - -CLEANUP: - bson_free (poller); - - return rval; -} - -bool -mongoc_stream_check_closed (mongoc_stream_t *stream) -{ - int ret; - - ENTRY; - - if (!stream) { - return true; - } - - ret = stream->check_closed (stream); - - RETURN (ret); -} - -bool -mongoc_stream_timed_out (mongoc_stream_t *stream) -{ - ENTRY; - - BSON_ASSERT (stream); - - /* for e.g. a file stream there is no timed_out function */ - RETURN (stream->timed_out && stream->timed_out (stream)); -} - -bool -mongoc_stream_should_retry (mongoc_stream_t *stream) -{ - ENTRY; - - BSON_ASSERT (stream); - - /* for e.g. a file stream there is no should_retry function */ - RETURN (stream->should_retry && stream->should_retry (stream)); -} - -bool -_mongoc_stream_writev_full (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec, - bson_error_t *error) -{ - size_t total_bytes = 0; - int i; - ssize_t r; - ENTRY; - - for (i = 0; i < iovcnt; i++) { - total_bytes += iov[i].iov_len; - } - - r = mongoc_stream_writev (stream, iov, iovcnt, timeout_msec); - TRACE ("writev returned: %ld", r); - - if (r < 0) { - if (error) { - char buf[128]; - char *errstr; - - errstr = bson_strerror_r (errno, buf, sizeof (buf)); - - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failure during socket delivery: %s (%d)", - errstr, - errno); - } - - RETURN (false); - } - - if (r != total_bytes) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failure to send all requested bytes (only sent: %" PRIu64 - "/%" PRId64 " in %dms) during socket delivery", - (uint64_t) r, - (int64_t) total_bytes, - timeout_msec); - - RETURN (false); - } - - RETURN (true); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-stream.h deleted file mode 100644 index f138b12beb39ef33fe1cfb5a55fb8b9409fdfb8b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-stream.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2013-2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_STREAM_H -#define MONGOC_STREAM_H - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-iovec.h" -#include "mongoc/mongoc-socket.h" - - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_stream_t mongoc_stream_t; - -typedef struct _mongoc_stream_poll_t { - mongoc_stream_t *stream; - int events; - int revents; -} mongoc_stream_poll_t; - -struct _mongoc_stream_t { - int type; - void (*destroy) (mongoc_stream_t *stream); - int (*close) (mongoc_stream_t *stream); - int (*flush) (mongoc_stream_t *stream); - ssize_t (*writev) (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec); - ssize_t (*readv) (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec); - int (*setsockopt) (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen); - mongoc_stream_t *(*get_base_stream) (mongoc_stream_t *stream); - bool (*check_closed) (mongoc_stream_t *stream); - ssize_t (*poll) (mongoc_stream_poll_t *streams, - size_t nstreams, - int32_t timeout); - void (*failed) (mongoc_stream_t *stream); - bool (*timed_out) (mongoc_stream_t *stream); - bool (*should_retry) (mongoc_stream_t *stream); - void *padding[3]; -}; - - -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_get_base_stream (mongoc_stream_t *stream); -MONGOC_EXPORT (mongoc_stream_t *) -mongoc_stream_get_tls_stream (mongoc_stream_t *stream); -MONGOC_EXPORT (int) -mongoc_stream_close (mongoc_stream_t *stream); -MONGOC_EXPORT (void) -mongoc_stream_destroy (mongoc_stream_t *stream); -MONGOC_EXPORT (void) -mongoc_stream_failed (mongoc_stream_t *stream); -MONGOC_EXPORT (int) -mongoc_stream_flush (mongoc_stream_t *stream); -MONGOC_EXPORT (ssize_t) -mongoc_stream_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec); -MONGOC_EXPORT (ssize_t) -mongoc_stream_write (mongoc_stream_t *stream, - void *buf, - size_t count, - int32_t timeout_msec); -MONGOC_EXPORT (ssize_t) -mongoc_stream_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec); -MONGOC_EXPORT (ssize_t) -mongoc_stream_read (mongoc_stream_t *stream, - void *buf, - size_t count, - size_t min_bytes, - int32_t timeout_msec); -MONGOC_EXPORT (int) -mongoc_stream_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen); -MONGOC_EXPORT (bool) -mongoc_stream_check_closed (mongoc_stream_t *stream); -MONGOC_EXPORT (bool) -mongoc_stream_timed_out (mongoc_stream_t *stream); -MONGOC_EXPORT (bool) -mongoc_stream_should_retry (mongoc_stream_t *stream); -MONGOC_EXPORT (ssize_t) -mongoc_stream_poll (mongoc_stream_poll_t *streams, - size_t nstreams, - int32_t timeout); - - -BSON_END_DECLS - - -#endif /* MONGOC_STREAM_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-thread-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-thread-private.h deleted file mode 100644 index 03530f6a279bca858420e33628addd20e2f90f45..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-thread-private.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2013-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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_THREAD_PRIVATE_H -#define MONGOC_THREAD_PRIVATE_H - -#include <bson/bson.h> - -#include "common-thread-private.h" -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-log.h" - -#if defined(BSON_OS_UNIX) -#define mongoc_cond_t pthread_cond_t -#define mongoc_cond_broadcast pthread_cond_broadcast -#define mongoc_cond_init(_n) pthread_cond_init ((_n), NULL) -#define mongoc_cond_wait pthread_cond_wait -#define mongoc_cond_signal pthread_cond_signal -static BSON_INLINE int -mongoc_cond_timedwait (pthread_cond_t *cond, - pthread_mutex_t *mutex, - int64_t timeout_msec) -{ - struct timespec to; - struct timeval tv; - int64_t msec; - - bson_gettimeofday (&tv); - - msec = ((int64_t) tv.tv_sec * 1000) + (tv.tv_usec / 1000) + timeout_msec; - - to.tv_sec = msec / 1000; - to.tv_nsec = (msec % 1000) * 1000 * 1000; - - return pthread_cond_timedwait (cond, mutex, &to); -} -#define mongoc_cond_destroy pthread_cond_destroy -#else -#define mongoc_cond_t CONDITION_VARIABLE -#define mongoc_cond_init InitializeConditionVariable -#define mongoc_cond_wait(_c, _m) mongoc_cond_timedwait ((_c), (_m), INFINITE) -static BSON_INLINE int -mongoc_cond_timedwait (mongoc_cond_t *cond, - bson_mutex_t *mutex, - int64_t timeout_msec) -{ - int r; - - if (SleepConditionVariableCS (cond, mutex, (DWORD) timeout_msec)) { - return 0; - } else { - r = GetLastError (); - - if (r == WAIT_TIMEOUT || r == ERROR_TIMEOUT) { - return WSAETIMEDOUT; - } else { - return EINVAL; - } - } -} -#define mongoc_cond_signal WakeConditionVariable -#define mongoc_cond_broadcast WakeAllConditionVariable -static BSON_INLINE int -mongoc_cond_destroy (mongoc_cond_t *_ignored) -{ - return 0; -} -#endif - - -#endif /* MONGOC_THREAD_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h deleted file mode 100644 index 5c033771771a890f1e02cf2189d428c3727c7db3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_TOPOLOGY_DESCRIPTION_APM_PRIVATE_H -#define MONGOC_TOPOLOGY_DESCRIPTION_APM_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-topology-description-private.h" - -/* Application Performance Monitoring for topology events, complies with the - * SDAM Monitoring Spec: - -https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst - - */ - -void -_mongoc_topology_description_monitor_server_opening ( - const mongoc_topology_description_t *td, mongoc_server_description_t *sd); - -void -_mongoc_topology_description_monitor_server_changed ( - const mongoc_topology_description_t *td, - const mongoc_server_description_t *prev_sd, - const mongoc_server_description_t *new_sd); - -void -_mongoc_topology_description_monitor_server_closed ( - const mongoc_topology_description_t *td, - const mongoc_server_description_t *sd); - -/* td is not const: we set its "opened" field here */ -void -_mongoc_topology_description_monitor_opening ( - mongoc_topology_description_t *td); - -void -_mongoc_topology_description_monitor_changed ( - const mongoc_topology_description_t *prev_td, - const mongoc_topology_description_t *new_td); - -void -_mongoc_topology_description_monitor_closed ( - const mongoc_topology_description_t *td); - -#endif /* MONGOC_TOPOLOGY_DESCRIPTION_APM_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-apm.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-apm.c deleted file mode 100644 index 0ae897a2066f2bc73f24a802f98f09f4228b925f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-apm.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-topology-description-apm-private.h" -#include "mongoc/mongoc-server-description-private.h" - -/* Application Performance Monitoring for topology events, complies with the - * SDAM Monitoring Spec: - -https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst - - */ - -/* ServerOpeningEvent */ -void -_mongoc_topology_description_monitor_server_opening ( - const mongoc_topology_description_t *td, - mongoc_server_description_t *sd) -{ - if (td->apm_callbacks.server_opening && !sd->opened) { - mongoc_apm_server_opening_t event; - - bson_oid_copy (&td->topology_id, &event.topology_id); - event.host = &sd->host; - event.context = td->apm_context; - sd->opened = true; - td->apm_callbacks.server_opening (&event); - } -} - -/* ServerDescriptionChangedEvent */ -void -_mongoc_topology_description_monitor_server_changed ( - const mongoc_topology_description_t *td, - const mongoc_server_description_t *prev_sd, - const mongoc_server_description_t *new_sd) -{ - if (td->apm_callbacks.server_changed) { - mongoc_apm_server_changed_t event; - - /* address is same in previous and new sd */ - bson_oid_copy (&td->topology_id, &event.topology_id); - event.host = &new_sd->host; - event.previous_description = prev_sd; - event.new_description = new_sd; - event.context = td->apm_context; - td->apm_callbacks.server_changed (&event); - } -} - -/* ServerClosedEvent */ -void -_mongoc_topology_description_monitor_server_closed ( - const mongoc_topology_description_t *td, - const mongoc_server_description_t *sd) -{ - if (td->apm_callbacks.server_closed) { - mongoc_apm_server_closed_t event; - - bson_oid_copy (&td->topology_id, &event.topology_id); - event.host = &sd->host; - event.context = td->apm_context; - td->apm_callbacks.server_closed (&event); - } -} - - -/* Send TopologyOpeningEvent when first called on this topology description. - * td is not const: we set its "opened" field here */ -void -_mongoc_topology_description_monitor_opening (mongoc_topology_description_t *td) -{ - mongoc_topology_description_t *prev_td = NULL; - size_t i; - mongoc_server_description_t *sd; - - if (td->opened) { - return; - } - - if (td->apm_callbacks.topology_changed) { - /* prepare to call monitor_changed */ - prev_td = bson_malloc0 (sizeof (mongoc_topology_description_t)); - mongoc_topology_description_init (prev_td, td->heartbeat_msec); - } - - td->opened = true; - - if (td->apm_callbacks.topology_opening) { - mongoc_apm_topology_opening_t event; - - bson_oid_copy (&td->topology_id, &event.topology_id); - event.context = td->apm_context; - td->apm_callbacks.topology_opening (&event); - } - - if (td->apm_callbacks.topology_changed) { - /* send initial description-changed event */ - _mongoc_topology_description_monitor_changed (prev_td, td); - } - - for (i = 0; i < td->servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, - (int) i); - - _mongoc_topology_description_monitor_server_opening (td, sd); - } - - if (prev_td) { - mongoc_topology_description_destroy (prev_td); - bson_free (prev_td); - } -} - -/* TopologyDescriptionChangedEvent */ -void -_mongoc_topology_description_monitor_changed ( - const mongoc_topology_description_t *prev_td, - const mongoc_topology_description_t *new_td) -{ - if (new_td->apm_callbacks.topology_changed) { - mongoc_apm_topology_changed_t event; - - /* callbacks, context, and id are the same in previous and new td */ - bson_oid_copy (&new_td->topology_id, &event.topology_id); - event.context = new_td->apm_context; - event.previous_description = prev_td; - event.new_description = new_td; - - new_td->apm_callbacks.topology_changed (&event); - } -} - -/* TopologyClosedEvent */ -void -_mongoc_topology_description_monitor_closed ( - const mongoc_topology_description_t *td) -{ - if (td->apm_callbacks.topology_closed) { - mongoc_apm_topology_closed_t event; - - bson_oid_copy (&td->topology_id, &event.topology_id); - event.context = td->apm_context; - td->apm_callbacks.topology_closed (&event); - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-private.h deleted file mode 100644 index f31c15fc03c4567d3d62ccb9407f9d56a02a99b4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description-private.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H -#define MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H - -#include "mongoc/mongoc-set-private.h" -#include "mongoc/mongoc-server-description.h" -#include "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-topology-description.h" -#include "mongoc/mongoc-apm-private.h" - - -typedef enum { - MONGOC_TOPOLOGY_UNKNOWN, - MONGOC_TOPOLOGY_SHARDED, - MONGOC_TOPOLOGY_RS_NO_PRIMARY, - MONGOC_TOPOLOGY_RS_WITH_PRIMARY, - MONGOC_TOPOLOGY_SINGLE, - MONGOC_TOPOLOGY_DESCRIPTION_TYPES -} mongoc_topology_description_type_t; - -struct _mongoc_topology_description_t { - bson_oid_t topology_id; - bool opened; - mongoc_topology_description_type_t type; - int64_t heartbeat_msec; - mongoc_set_t *servers; - char *set_name; - int64_t max_set_version; - bson_oid_t max_election_id; - bson_error_t compatibility_error; - uint32_t max_server_id; - bool stale; - unsigned int rand_seed; - - /* the greatest seen cluster time, for a MongoDB 3.6+ sharded cluster. - * see Driver Sessions Spec. */ - bson_t cluster_time; - - /* smallest seen logicalSessionTimeoutMinutes, or -1 if any server has no - * logicalSessionTimeoutMinutes. see Server Discovery and Monitoring Spec */ - int64_t session_timeout_minutes; - - mongoc_apm_callbacks_t apm_callbacks; - void *apm_context; -}; - -typedef enum { MONGOC_SS_READ, MONGOC_SS_WRITE } mongoc_ss_optype_t; - -void -mongoc_topology_description_init (mongoc_topology_description_t *description, - int64_t heartbeat_msec); - -void -_mongoc_topology_description_copy_to (const mongoc_topology_description_t *src, - mongoc_topology_description_t *dst); - -void -mongoc_topology_description_destroy ( - mongoc_topology_description_t *description); - -void -mongoc_topology_description_handle_ismaster ( - mongoc_topology_description_t *topology, - uint32_t server_id, - const bson_t *reply, - int64_t rtt_msec, - const bson_error_t *error /* IN */); - -mongoc_server_description_t * -mongoc_topology_description_select (mongoc_topology_description_t *description, - mongoc_ss_optype_t optype, - const mongoc_read_prefs_t *read_pref, - int64_t local_threshold_ms); - -mongoc_server_description_t * -mongoc_topology_description_server_by_id ( - mongoc_topology_description_t *description, - uint32_t id, - bson_error_t *error); - -int32_t -mongoc_topology_description_lowest_max_wire_version ( - const mongoc_topology_description_t *td); - -bool -mongoc_topology_description_all_sds_have_write_date ( - const mongoc_topology_description_t *td); - -bool -_mongoc_topology_description_validate_max_staleness ( - const mongoc_topology_description_t *td, - int64_t max_staleness_seconds, - bson_error_t *error); - -void -mongoc_topology_description_suitable_servers ( - mongoc_array_t *set, /* OUT */ - mongoc_ss_optype_t optype, - mongoc_topology_description_t *topology, - const mongoc_read_prefs_t *read_pref, - size_t local_threshold_ms); - -bool -mongoc_topology_description_has_data_node (mongoc_topology_description_t *td); - -void -mongoc_topology_description_invalidate_server ( - mongoc_topology_description_t *topology, - uint32_t id, - const bson_error_t *error /* IN */); - -bool -mongoc_topology_description_add_server (mongoc_topology_description_t *topology, - const char *server, - uint32_t *id /* OUT */); - -void -mongoc_topology_description_update_cluster_time ( - mongoc_topology_description_t *td, const bson_t *reply); - -#endif /* MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description.c deleted file mode 100644 index 51cdc82f78c4f491d932a7a3bf7ce602c8ef6c31..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description.c +++ /dev/null @@ -1,2121 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-server-description-private.h" -#include "mongoc/mongoc-topology-description-apm-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-set-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-thread-private.h" - - -static bool -_is_data_node (mongoc_server_description_t *sd) -{ - switch (sd->type) { - case MONGOC_SERVER_MONGOS: - case MONGOC_SERVER_STANDALONE: - case MONGOC_SERVER_RS_SECONDARY: - case MONGOC_SERVER_RS_PRIMARY: - return true; - case MONGOC_SERVER_RS_OTHER: - case MONGOC_SERVER_RS_ARBITER: - case MONGOC_SERVER_UNKNOWN: - case MONGOC_SERVER_POSSIBLE_PRIMARY: - case MONGOC_SERVER_RS_GHOST: - case MONGOC_SERVER_DESCRIPTION_TYPES: - default: - return false; - } -} - - -static void -_mongoc_topology_server_dtor (void *server_, void *ctx_) -{ - mongoc_server_description_destroy ((mongoc_server_description_t *) server_); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_init -- - * - * Initialize the given topology description - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_topology_description_init (mongoc_topology_description_t *description, - int64_t heartbeat_msec) -{ - ENTRY; - - BSON_ASSERT (description); - - memset (description, 0, sizeof (*description)); - - bson_oid_init (&description->topology_id, NULL); - description->opened = false; - description->type = MONGOC_TOPOLOGY_UNKNOWN; - description->heartbeat_msec = heartbeat_msec; - description->servers = - mongoc_set_new (8, _mongoc_topology_server_dtor, NULL); - description->set_name = NULL; - description->max_set_version = MONGOC_NO_SET_VERSION; - description->stale = true; - description->rand_seed = (unsigned int) bson_get_monotonic_time (); - bson_init (&description->cluster_time); - description->session_timeout_minutes = MONGOC_NO_SESSIONS; - - EXIT; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_copy_to -- - * - * Deep-copy @src to an uninitialized topology description @dst. - * @dst must not already point to any allocated resources. Clean - * up with mongoc_topology_description_destroy. - * - * WARNING: @dst's rand_seed is not initialized. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -_mongoc_topology_description_copy_to (const mongoc_topology_description_t *src, - mongoc_topology_description_t *dst) -{ - size_t nitems; - size_t i; - mongoc_server_description_t *sd; - uint32_t id; - - ENTRY; - - BSON_ASSERT (src); - BSON_ASSERT (dst); - - bson_oid_copy (&src->topology_id, &dst->topology_id); - dst->opened = src->opened; - dst->type = src->type; - dst->heartbeat_msec = src->heartbeat_msec; - - nitems = bson_next_power_of_two (src->servers->items_len); - dst->servers = mongoc_set_new (nitems, _mongoc_topology_server_dtor, NULL); - for (i = 0; i < src->servers->items_len; i++) { - sd = mongoc_set_get_item_and_id (src->servers, (int) i, &id); - mongoc_set_add ( - dst->servers, id, mongoc_server_description_new_copy (sd)); - } - - dst->set_name = bson_strdup (src->set_name); - dst->max_set_version = src->max_set_version; - memcpy (&dst->compatibility_error, - &src->compatibility_error, - sizeof (bson_error_t)); - dst->max_server_id = src->max_server_id; - dst->stale = src->stale; - memcpy (&dst->apm_callbacks, - &src->apm_callbacks, - sizeof (mongoc_apm_callbacks_t)); - - dst->apm_context = src->apm_context; - - bson_copy_to (&src->cluster_time, &dst->cluster_time); - - dst->session_timeout_minutes = src->session_timeout_minutes; - - EXIT; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_destroy -- - * - * Destroy allocated resources within @description - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_topology_description_destroy (mongoc_topology_description_t *description) -{ - ENTRY; - - BSON_ASSERT (description); - - if (description->servers) { - mongoc_set_destroy (description->servers); - } - - if (description->set_name) { - bson_free (description->set_name); - } - - bson_destroy (&description->cluster_time); - - EXIT; -} - -/* find the primary, then stop iterating */ -static bool -_mongoc_topology_description_has_primary_cb (void *item, void *ctx /* OUT */) -{ - mongoc_server_description_t *server = (mongoc_server_description_t *) item; - mongoc_server_description_t **primary = (mongoc_server_description_t **) ctx; - - /* TODO should this include MONGOS? */ - if (server->type == MONGOC_SERVER_RS_PRIMARY || - server->type == MONGOC_SERVER_STANDALONE) { - *primary = (mongoc_server_description_t *) item; - return false; - } - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_has_primary -- - * - * If topology has a primary, return it. - * - * Returns: - * A pointer to the primary, or NULL. - * - * Side effects: - * None - * - *-------------------------------------------------------------------------- - */ -static mongoc_server_description_t * -_mongoc_topology_description_has_primary ( - mongoc_topology_description_t *description) -{ - mongoc_server_description_t *primary = NULL; - - mongoc_set_for_each (description->servers, - _mongoc_topology_description_has_primary_cb, - &primary); - - return primary; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_later_election -- - * - * Check if we've seen a more recent election in the replica set - * than this server has. - * - * Returns: - * True if the topology description's max replica set version plus - * election id is later than the server description's. - * - * Side effects: - * None - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_topology_description_later_election (mongoc_topology_description_t *td, - mongoc_server_description_t *sd) -{ - /* initially max_set_version is -1 and max_election_id is zeroed */ - return td->max_set_version > sd->set_version || - (td->max_set_version == sd->set_version && - bson_oid_compare (&td->max_election_id, &sd->election_id) > 0); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_set_max_set_version -- - * - * Remember that we've seen a new replica set version. Unconditionally - * sets td->set_version to sd->set_version. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_set_max_set_version ( - mongoc_topology_description_t *td, mongoc_server_description_t *sd) -{ - td->max_set_version = sd->set_version; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_set_max_election_id -- - * - * Remember that we've seen a new election id. Unconditionally sets - * td->max_election_id to sd->election_id. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_set_max_election_id ( - mongoc_topology_description_t *td, mongoc_server_description_t *sd) -{ - bson_oid_copy (&sd->election_id, &td->max_election_id); -} - -static bool -_mongoc_topology_description_server_is_candidate ( - mongoc_server_description_type_t desc_type, - mongoc_read_mode_t read_mode, - mongoc_topology_description_type_t topology_type) -{ - switch ((int) topology_type) { - case MONGOC_TOPOLOGY_SINGLE: - switch ((int) desc_type) { - case MONGOC_SERVER_STANDALONE: - return true; - default: - return false; - } - - case MONGOC_TOPOLOGY_RS_NO_PRIMARY: - case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: - switch ((int) read_mode) { - case MONGOC_READ_PRIMARY: - switch ((int) desc_type) { - case MONGOC_SERVER_RS_PRIMARY: - return true; - default: - return false; - } - case MONGOC_READ_SECONDARY: - switch ((int) desc_type) { - case MONGOC_SERVER_RS_SECONDARY: - return true; - default: - return false; - } - default: - switch ((int) desc_type) { - case MONGOC_SERVER_RS_PRIMARY: - case MONGOC_SERVER_RS_SECONDARY: - return true; - default: - return false; - } - } - - case MONGOC_TOPOLOGY_SHARDED: - switch ((int) desc_type) { - case MONGOC_SERVER_MONGOS: - return true; - default: - return false; - } - default: - return false; - } -} - -typedef struct _mongoc_suitable_data_t { - mongoc_read_mode_t read_mode; - mongoc_topology_description_type_t topology_type; - mongoc_server_description_t *primary; /* OUT */ - mongoc_server_description_t **candidates; /* OUT */ - size_t candidates_len; /* OUT */ - bool has_secondary; /* OUT */ -} mongoc_suitable_data_t; - -static bool -_mongoc_replica_set_read_suitable_cb (void *item, void *ctx) -{ - mongoc_server_description_t *server = (mongoc_server_description_t *) item; - mongoc_suitable_data_t *data = (mongoc_suitable_data_t *) ctx; - - /* primary's used in staleness calculation, even with mode SECONDARY */ - if (server->type == MONGOC_SERVER_RS_PRIMARY) { - data->primary = server; - } - - if (_mongoc_topology_description_server_is_candidate ( - server->type, data->read_mode, data->topology_type)) { - if (server->type == MONGOC_SERVER_RS_PRIMARY) { - if (data->read_mode == MONGOC_READ_PRIMARY || - data->read_mode == MONGOC_READ_PRIMARY_PREFERRED) { - /* we want a primary and we have one, done! */ - return false; - } - } - - if (server->type == MONGOC_SERVER_RS_SECONDARY) { - data->has_secondary = true; - } - - /* add to our candidates */ - data->candidates[data->candidates_len++] = server; - } else { - TRACE ("Rejected [%s] [%s] for mode [%s]", - mongoc_server_description_type (server), - server->host.host_and_port, - _mongoc_read_mode_as_str (data->read_mode)); - } - - return true; -} - - -/* if any mongos are candidates, add them to the candidates array */ -static void -_mongoc_try_mode_secondary (mongoc_array_t *set, /* OUT */ - mongoc_topology_description_t *topology, - const mongoc_read_prefs_t *read_pref, - size_t local_threshold_ms) -{ - mongoc_read_prefs_t *secondary; - - secondary = mongoc_read_prefs_copy (read_pref); - mongoc_read_prefs_set_mode (secondary, MONGOC_READ_SECONDARY); - - mongoc_topology_description_suitable_servers ( - set, MONGOC_SS_READ, topology, secondary, local_threshold_ms); - - mongoc_read_prefs_destroy (secondary); -} - - -/* if any mongos are candidates, add them to the candidates array */ -static bool -_mongoc_find_suitable_mongos_cb (void *item, void *ctx) -{ - mongoc_server_description_t *server = (mongoc_server_description_t *) item; - mongoc_suitable_data_t *data = (mongoc_suitable_data_t *) ctx; - - if (_mongoc_topology_description_server_is_candidate ( - server->type, data->read_mode, data->topology_type)) { - data->candidates[data->candidates_len++] = server; - } - return true; -} - - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_description_lowest_max_wire_version -- - * - * The topology's max wire version. - * - * NOTE: this method should only be called while holding the mutex on - * the owning topology object. - * - * Returns: - * The minimum of all known servers' max wire versions, or INT32_MAX - * if there are no known servers. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ -int32_t -mongoc_topology_description_lowest_max_wire_version ( - const mongoc_topology_description_t *td) -{ - int i; - int32_t ret = INT32_MAX; - mongoc_server_description_t *sd; - - for (i = 0; (size_t) i < td->servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i); - - if (sd->type != MONGOC_SERVER_UNKNOWN && sd->max_wire_version < ret) { - ret = sd->max_wire_version; - } - } - - return ret; -} - - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_description_all_sds_have_write_date -- - * - * Whether the primary and all secondaries' server descriptions have - * last_write_date_ms. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ -bool -mongoc_topology_description_all_sds_have_write_date ( - const mongoc_topology_description_t *td) -{ - int i; - mongoc_server_description_t *sd; - - for (i = 0; (size_t) i < td->servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i); - - if (sd->last_write_date_ms <= 0 && - (sd->type == MONGOC_SERVER_RS_PRIMARY || - sd->type == MONGOC_SERVER_RS_SECONDARY)) { - return false; - } - } - - return true; -} - -/* - *------------------------------------------------------------------------- - * - * _mongoc_topology_description_validate_max_staleness -- - * - * If the provided "maxStalenessSeconds" component of the read - * preference is not valid for this topology, fill out @error and - * return false. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ -bool -_mongoc_topology_description_validate_max_staleness ( - const mongoc_topology_description_t *td, - int64_t max_staleness_seconds, - bson_error_t *error) -{ - mongoc_topology_description_type_t td_type; - - /* Server Selection Spec: A driver MUST raise an error if the TopologyType - * is ReplicaSetWithPrimary or ReplicaSetNoPrimary and either of these - * conditions is false: - * - * maxStalenessSeconds * 1000 >= heartbeatFrequencyMS + idleWritePeriodMS - * maxStalenessSeconds >= smallestMaxStalenessSeconds - */ - - td_type = td->type; - - if (td_type != MONGOC_TOPOLOGY_RS_WITH_PRIMARY && - td_type != MONGOC_TOPOLOGY_RS_NO_PRIMARY) { - return true; - } - - if (max_staleness_seconds * 1000 < - td->heartbeat_msec + MONGOC_IDLE_WRITE_PERIOD_MS) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "maxStalenessSeconds is set to %" PRId64 - ", it must be at least heartbeatFrequencyMS (%" PRId64 - ") + server's idle write period (%d seconds)", - max_staleness_seconds, - td->heartbeat_msec, - MONGOC_IDLE_WRITE_PERIOD_MS / 1000); - return false; - } - - if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "maxStalenessSeconds is set to %" PRId64 - ", it must be at least %d seconds", - max_staleness_seconds, - MONGOC_SMALLEST_MAX_STALENESS_SECONDS); - return false; - } - - return true; -} - - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_description_suitable_servers -- - * - * Fill out an array of servers matching the read preference and - * localThresholdMS. - * - * NOTE: this method should only be called while holding the mutex on - * the owning topology object. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -void -mongoc_topology_description_suitable_servers ( - mongoc_array_t *set, /* OUT */ - mongoc_ss_optype_t optype, - mongoc_topology_description_t *topology, - const mongoc_read_prefs_t *read_pref, - size_t local_threshold_ms) -{ - mongoc_suitable_data_t data; - mongoc_server_description_t **candidates; - mongoc_server_description_t *server; - int64_t nearest = -1; - int i; - mongoc_read_mode_t read_mode = mongoc_read_prefs_get_mode (read_pref); - - candidates = (mongoc_server_description_t **) bson_malloc0 ( - sizeof (*candidates) * topology->servers->items_len); - - data.read_mode = read_mode; - data.topology_type = topology->type; - data.primary = NULL; - data.candidates = candidates; - data.candidates_len = 0; - data.has_secondary = false; - - /* Single server -- - * Either it is suitable or it isn't */ - if (topology->type == MONGOC_TOPOLOGY_SINGLE) { - server = (mongoc_server_description_t *) mongoc_set_get_item ( - topology->servers, 0); - if (_mongoc_topology_description_server_is_candidate ( - server->type, read_mode, topology->type)) { - _mongoc_array_append_val (set, server); - } else { - TRACE ( - "Rejected [%s] [%s] for read mode [%s] with topology type Single", - mongoc_server_description_type (server), - server->host.host_and_port, - _mongoc_read_mode_as_str (read_mode)); - } - goto DONE; - } - - /* Replica sets -- - * Find suitable servers based on read mode */ - if (topology->type == MONGOC_TOPOLOGY_RS_NO_PRIMARY || - topology->type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY) { - if (optype == MONGOC_SS_READ) { - mongoc_set_for_each ( - topology->servers, _mongoc_replica_set_read_suitable_cb, &data); - - if (read_mode == MONGOC_READ_PRIMARY) { - if (data.primary) { - _mongoc_array_append_val (set, data.primary); - } - - goto DONE; - } - - if (read_mode == MONGOC_READ_PRIMARY_PREFERRED && data.primary) { - _mongoc_array_append_val (set, data.primary); - goto DONE; - } - - if (read_mode == MONGOC_READ_SECONDARY_PREFERRED) { - /* try read_mode SECONDARY */ - _mongoc_try_mode_secondary ( - set, topology, read_pref, local_threshold_ms); - - /* otherwise fall back to primary */ - if (!set->len && data.primary) { - _mongoc_array_append_val (set, data.primary); - } - - goto DONE; - } - - if (read_mode == MONGOC_READ_SECONDARY) { - for (i = 0; i < data.candidates_len; i++) { - if (candidates[i] && - candidates[i]->type != MONGOC_SERVER_RS_SECONDARY) { - TRACE ("Rejected [%s] [%s] for mode [%s] with RS topology", - mongoc_server_description_type (candidates[i]), - candidates[i]->host.host_and_port, - _mongoc_read_mode_as_str (read_mode)); - candidates[i] = NULL; - } - } - } - - /* mode is SECONDARY or NEAREST, filter by staleness and tags */ - mongoc_server_description_filter_stale (data.candidates, - data.candidates_len, - data.primary, - topology->heartbeat_msec, - read_pref); - - mongoc_server_description_filter_tags ( - data.candidates, data.candidates_len, read_pref); - } else if (topology->type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY) { - /* includes optype == MONGOC_SS_WRITE as the exclusion of the above if - */ - mongoc_set_for_each (topology->servers, - _mongoc_topology_description_has_primary_cb, - &data.primary); - if (data.primary) { - _mongoc_array_append_val (set, data.primary); - goto DONE; - } - } - } - - /* Sharded clusters -- - * All candidates in the latency window are suitable */ - if (topology->type == MONGOC_TOPOLOGY_SHARDED) { - mongoc_set_for_each ( - topology->servers, _mongoc_find_suitable_mongos_cb, &data); - } - - /* Ways to get here: - * - secondary read - * - secondary preferred read - * - primary_preferred and no primary read - * - sharded anything - * Find the nearest, then select within the window */ - - for (i = 0; i < data.candidates_len; i++) { - if (candidates[i] && - (nearest == -1 || nearest > candidates[i]->round_trip_time_msec)) { - nearest = candidates[i]->round_trip_time_msec; - } - } - - for (i = 0; i < data.candidates_len; i++) { - if (candidates[i] && (candidates[i]->round_trip_time_msec <= - nearest + local_threshold_ms)) { - _mongoc_array_append_val (set, candidates[i]); - } - } - -DONE: - - bson_free (candidates); - - return; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_has_data_node -- - * - * Internal method: are any servers not Arbiter, Ghost, or Unknown? - * - *-------------------------------------------------------------------------- - */ -bool -mongoc_topology_description_has_data_node (mongoc_topology_description_t *td) -{ - int i; - mongoc_server_description_t *sd; - - for (i = 0; i < (int) td->servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i); - if (_is_data_node (sd)) { - return true; - } - } - - return false; -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_description_select -- - * - * Return a server description of a node that is appropriate for - * the given read preference and operation type. - * - * NOTE: this method simply attempts to select a server from the - * current topology, it does not retry or trigger topology checks. - * - * NOTE: this method should only be called while holding the mutex on - * the owning topology object. - * - * Returns: - * Selected server description, or NULL upon failure. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -mongoc_server_description_t * -mongoc_topology_description_select (mongoc_topology_description_t *topology, - mongoc_ss_optype_t optype, - const mongoc_read_prefs_t *read_pref, - int64_t local_threshold_ms) -{ - mongoc_array_t suitable_servers; - mongoc_server_description_t *sd = NULL; - int rand_n; - - ENTRY; - - if (topology->type == MONGOC_TOPOLOGY_SINGLE) { - sd = (mongoc_server_description_t *) mongoc_set_get_item ( - topology->servers, 0); - - if (sd->has_is_master) { - RETURN (sd); - } else { - TRACE ("Topology type single, [%s] is down", sd->host.host_and_port); - RETURN (NULL); - } - } - - _mongoc_array_init (&suitable_servers, - sizeof (mongoc_server_description_t *)); - - mongoc_topology_description_suitable_servers ( - &suitable_servers, optype, topology, read_pref, local_threshold_ms); - if (suitable_servers.len != 0) { - rand_n = _mongoc_rand_simple (&topology->rand_seed); - sd = _mongoc_array_index (&suitable_servers, - mongoc_server_description_t *, - rand_n % suitable_servers.len); - } - - _mongoc_array_destroy (&suitable_servers); - - if (sd) { - TRACE ("Topology type [%s], selected [%s] [%s]", - mongoc_topology_description_type (topology), - mongoc_server_description_type (sd), - sd->host.host_and_port); - } - - RETURN (sd); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_server_by_id -- - * - * Get the server description for @id, if that server is present - * in @description. Otherwise, return NULL and fill out optional - * @error. - * - * NOTE: In most cases, caller should create a duplicate of the - * returned server description. Caller should hold the mutex on the - * owning topology object while calling this method and while using - * the returned reference. - * - * Returns: - * A mongoc_server_description_t *, or NULL. - * - * Side effects: - * Fills out optional @error if server not found. - * - *-------------------------------------------------------------------------- - */ - -mongoc_server_description_t * -mongoc_topology_description_server_by_id ( - mongoc_topology_description_t *description, uint32_t id, bson_error_t *error) -{ - mongoc_server_description_t *sd; - - BSON_ASSERT (description); - - sd = - (mongoc_server_description_t *) mongoc_set_get (description->servers, id); - if (!sd) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NOT_ESTABLISHED, - "Could not find description for node %u", - id); - } - - return sd; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_remove_server -- - * - * If present, remove this server from this topology description. - * - * Returns: - * None. - * - * Side effects: - * Removes the server description from topology and destroys it. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_remove_server ( - mongoc_topology_description_t *description, - mongoc_server_description_t *server) -{ - BSON_ASSERT (description); - BSON_ASSERT (server); - - _mongoc_topology_description_monitor_server_closed (description, server); - mongoc_set_rm (description->servers, server->id); - - /* Check if removing server resulted in an empty set of servers */ - if (description->servers->items_len == 0) { - MONGOC_WARNING ("Last server removed from topology"); - } -} - -typedef struct _mongoc_address_and_id_t { - const char *address; /* IN */ - bool found; /* OUT */ - uint32_t id; /* OUT */ -} mongoc_address_and_id_t; - -/* find the given server and stop iterating */ -static bool -_mongoc_topology_description_has_server_cb (void *item, - void *ctx /* IN - OUT */) -{ - mongoc_server_description_t *server = (mongoc_server_description_t *) item; - mongoc_address_and_id_t *data = (mongoc_address_and_id_t *) ctx; - - if (strcasecmp (data->address, server->connection_address) == 0) { - data->found = true; - data->id = server->id; - return false; - } - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_has_set_version -- - * - * Whether @topology's max replica set version has been set. - * - * Returns: - * True if the max setVersion was ever set. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_topology_description_has_set_version (mongoc_topology_description_t *td) -{ - return td->max_set_version != MONGOC_NO_SET_VERSION; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_topology_has_server -- - * - * Return true if @server is in @topology. If so, place its id in - * @id if given. - * - * Returns: - * True if server is in topology, false otherwise. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_topology_description_has_server ( - mongoc_topology_description_t *description, - const char *address, - uint32_t *id /* OUT */) -{ - mongoc_address_and_id_t data; - - BSON_ASSERT (description); - BSON_ASSERT (address); - - data.address = address; - data.found = false; - mongoc_set_for_each ( - description->servers, _mongoc_topology_description_has_server_cb, &data); - - if (data.found && id) { - *id = data.id; - } - - return data.found; -} - -typedef struct _mongoc_address_and_type_t { - const char *address; - mongoc_server_description_type_t type; -} mongoc_address_and_type_t; - -static bool -_mongoc_label_unknown_member_cb (void *item, void *ctx) -{ - mongoc_server_description_t *server = (mongoc_server_description_t *) item; - mongoc_address_and_type_t *data = (mongoc_address_and_type_t *) ctx; - - if (strcasecmp (server->connection_address, data->address) == 0 && - server->type == MONGOC_SERVER_UNKNOWN) { - mongoc_server_description_set_state (server, data->type); - return false; - } - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_label_unknown_member -- - * - * Find the server description with the given @address and if its - * type is UNKNOWN, set its type to @type. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_label_unknown_member ( - mongoc_topology_description_t *description, - const char *address, - mongoc_server_description_type_t type) -{ - mongoc_address_and_type_t data; - - BSON_ASSERT (description); - BSON_ASSERT (address); - - data.type = type; - data.address = address; - - mongoc_set_for_each ( - description->servers, _mongoc_label_unknown_member_cb, &data); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_set_state -- - * - * Change the state of this cluster and unblock things waiting - * on a change of topology type. - * - * Returns: - * None. - * - * Side effects: - * Unblocks anything waiting on this description to change states. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_set_state ( - mongoc_topology_description_t *description, - mongoc_topology_description_type_t type) -{ - description->type = type; -} - - -static void -_update_rs_type (mongoc_topology_description_t *topology) -{ - if (_mongoc_topology_description_has_primary (topology)) { - _mongoc_topology_description_set_state (topology, - MONGOC_TOPOLOGY_RS_WITH_PRIMARY); - } else { - _mongoc_topology_description_set_state (topology, - MONGOC_TOPOLOGY_RS_NO_PRIMARY); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_check_if_has_primary -- - * - * If there is a primary in topology, set topology - * type to RS_WITH_PRIMARY, otherwise set it to - * RS_NO_PRIMARY. - * - * Returns: - * None. - * - * Side effects: - * Changes the topology type. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_check_if_has_primary ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - _update_rs_type (topology); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_invalidate_server -- - * - * Invalidate a server if a network error occurred while using it in - * another part of the client. Server description is set to type - * UNKNOWN, the error is recorded, and other parameters are reset to - * defaults. Pass in the reason for invalidation in @error. - * - * NOTE: this method should only be called while holding the mutex on - * the owning topology object. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_topology_description_invalidate_server ( - mongoc_topology_description_t *topology, - uint32_t id, - const bson_error_t *error /* IN */) -{ - BSON_ASSERT (error); - - /* send NULL ismaster reply */ - mongoc_topology_description_handle_ismaster (topology, id, NULL, 0, error); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_add_server -- - * - * Add the specified server to the cluster topology if it is not - * already a member. If @id, place its id in @id. - * - * NOTE: this method should only be called while holding the mutex on - * the owning topology object. - * - * Return: - * True if the server was added or already existed in the topology, - * false if an error occurred. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -bool -mongoc_topology_description_add_server (mongoc_topology_description_t *topology, - const char *server, - uint32_t *id /* OUT */) -{ - uint32_t server_id; - mongoc_server_description_t *description; - - BSON_ASSERT (topology); - BSON_ASSERT (server); - - if (!_mongoc_topology_description_has_server ( - topology, server, &server_id)) { - /* TODO this might not be an accurate count in all cases */ - server_id = ++topology->max_server_id; - - description = - (mongoc_server_description_t *) bson_malloc0 (sizeof *description); - mongoc_server_description_init (description, server, server_id); - - mongoc_set_add (topology->servers, server_id, description); - - /* if we're in topology_new then no callbacks are registered and this is - * a no-op. later, if we discover a new RS member this sends an event. */ - _mongoc_topology_description_monitor_server_opening (topology, - description); - } - - if (id) { - *id = server_id; - } - - return true; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_update_cluster_time -- - * - * Drivers Session Spec: Drivers MUST examine responses to server commands to - * see if they contain a top level field named $clusterTime formatted as - * follows: - * - * { - * ... - * $clusterTime : { - * clusterTime : <BsonTimestamp>, - * signature : { - * hash : <BsonBinaryData>, - * keyId : <BsonInt64> - * } - * }, - * ... - * } - * - * Whenever a driver receives a clusterTime from a server it MUST compare it - * to the current highest seen clusterTime for the cluster. If the new - * clusterTime is higher than the highest seen clusterTime it MUST become - * the new highest seen clusterTime. Two clusterTimes are compared using - * only the BsonTimestamp value of the clusterTime embedded field (be sure to - * include both the timestamp and the increment of the BsonTimestamp in the - * comparison). The signature field does not participate in the comparison. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_topology_description_update_cluster_time ( - mongoc_topology_description_t *td, const bson_t *reply) -{ - bson_iter_t iter; - bson_iter_t child; - const uint8_t *data; - uint32_t size; - bson_t cluster_time; - - if (!reply || !bson_iter_init_find (&iter, reply, "$clusterTime")) { - return; - } - - if (!BSON_ITER_HOLDS_DOCUMENT (&iter) || - !bson_iter_recurse (&iter, &child)) { - MONGOC_ERROR ("Can't parse $clusterTime"); - return; - } - - bson_iter_document (&iter, &size, &data); - BSON_ASSERT (bson_init_static (&cluster_time, data, (size_t) size)); - - if (bson_empty (&td->cluster_time) || - _mongoc_cluster_time_greater (&cluster_time, &td->cluster_time)) { - bson_destroy (&td->cluster_time); - bson_copy_to (&cluster_time, &td->cluster_time); - } -} - - -static void -_mongoc_topology_description_add_new_servers ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - bson_iter_t member_iter; - const bson_t *rs_members[3]; - int i; - - rs_members[0] = &server->hosts; - rs_members[1] = &server->arbiters; - rs_members[2] = &server->passives; - - for (i = 0; i < 3; i++) { - BSON_ASSERT (bson_iter_init (&member_iter, rs_members[i])); - - while (bson_iter_next (&member_iter)) { - mongoc_topology_description_add_server ( - topology, bson_iter_utf8 (&member_iter, NULL), NULL); - } - } -} - -typedef struct _mongoc_primary_and_topology_t { - mongoc_topology_description_t *topology; - mongoc_server_description_t *primary; -} mongoc_primary_and_topology_t; - -/* invalidate old primaries */ -static bool -_mongoc_topology_description_invalidate_primaries_cb (void *item, void *ctx) -{ - mongoc_server_description_t *server = (mongoc_server_description_t *) item; - mongoc_primary_and_topology_t *data = (mongoc_primary_and_topology_t *) ctx; - - if (server->id != data->primary->id && - server->type == MONGOC_SERVER_RS_PRIMARY) { - mongoc_server_description_set_state (server, MONGOC_SERVER_UNKNOWN); - mongoc_server_description_set_set_version (server, MONGOC_NO_SET_VERSION); - mongoc_server_description_set_election_id (server, NULL); - } - return true; -} - - -/* Remove and destroy all replica set members not in primary's hosts lists */ -static void -_mongoc_topology_description_remove_unreported_servers ( - mongoc_topology_description_t *topology, - mongoc_server_description_t *primary) -{ - mongoc_array_t to_remove; - int i; - mongoc_server_description_t *member; - const char *address; - - _mongoc_array_init (&to_remove, sizeof (mongoc_server_description_t *)); - - /* Accumulate servers to be removed - do this before calling - * _mongoc_topology_description_remove_server, which could call - * mongoc_server_description_cleanup on the primary itself if it - * doesn't report its own connection_address in its hosts list. - * See hosts_differ_from_seeds.json */ - for (i = 0; i < topology->servers->items_len; i++) { - member = (mongoc_server_description_t *) mongoc_set_get_item ( - topology->servers, i); - address = member->connection_address; - if (!mongoc_server_description_has_rs_member (primary, address)) { - _mongoc_array_append_val (&to_remove, member); - } - } - - /* now it's safe to call _mongoc_topology_description_remove_server, - * even on the primary */ - for (i = 0; i < to_remove.len; i++) { - member = - _mongoc_array_index (&to_remove, mongoc_server_description_t *, i); - - _mongoc_topology_description_remove_server (topology, member); - } - - _mongoc_array_destroy (&to_remove); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_matches_me -- - * - * Server Discovery And Monitoring Spec: "Removal from the topology of - * seed list members where the "me" property does not match the address - * used to connect prevents clients from being able to select a server, - * only to fail to re-select that server once the primary has responded. - * - * Returns: - * True if "me" matches "connection_address". - * - * Side Effects: - * None. - * - *-------------------------------------------------------------------------- - */ -static bool -_mongoc_topology_description_matches_me (mongoc_server_description_t *server) -{ - BSON_ASSERT (server->connection_address); - - if (!server->me) { - /* "me" is unknown: consider it a match */ - return true; - } - - return strcasecmp (server->connection_address, server->me) == 0; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_update_rs_from_primary -- - * - * First, determine that this is really the primary: - * -If this node isn't in the cluster, do nothing. - * -If the cluster's set name is null, set it to node's set name. - * Otherwise if the cluster's set name is different from node's, - * we found a rogue primary, so remove it from the cluster and - * check the cluster for a primary, then return. - * -If any of the members of cluster reports an address different - * from node's, node cannot be the primary. - * Now that we know this is the primary: - * -If any hosts, passives, or arbiters in node's description aren't - * in the cluster, add them as UNKNOWN servers. - * -If the cluster has any servers that aren't in node's description, - * remove and destroy them. - * Finally, check the cluster for the new primary. - * - * Returns: - * None. - * - * Side effects: - * Changes to the cluster, possible removal of cluster nodes. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_update_rs_from_primary ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - mongoc_primary_and_topology_t data; - bson_error_t error; - - BSON_ASSERT (topology); - BSON_ASSERT (server); - - if (!_mongoc_topology_description_has_server ( - topology, server->connection_address, NULL)) - return; - - /* If server->set_name was null this function wouldn't be called from - * mongoc_server_description_handle_ismaster(). static code analyzers however - * don't know that so we check for it explicitly. */ - if (server->set_name) { - /* 'Server' can only be the primary if it has the right rs name */ - - if (!topology->set_name) { - topology->set_name = bson_strdup (server->set_name); - } else if (strcmp (topology->set_name, server->set_name) != 0) { - _mongoc_topology_description_remove_server (topology, server); - _update_rs_type (topology); - return; - } - } - - if (mongoc_server_description_has_set_version (server) && - mongoc_server_description_has_election_id (server)) { - /* Server Discovery And Monitoring Spec: "The client remembers the - * greatest electionId reported by a primary, and distrusts primaries - * with lesser electionIds. This prevents the client from oscillating - * between the old and new primary during a split-brain period." - */ - if (_mongoc_topology_description_later_election (topology, server)) { - bson_set_error (&error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "member's setVersion or electionId is stale"); - mongoc_topology_description_invalidate_server ( - topology, server->id, &error); - _update_rs_type (topology); - return; - } - - /* server's electionId >= topology's max electionId */ - _mongoc_topology_description_set_max_election_id (topology, server); - } - - if (mongoc_server_description_has_set_version (server) && - (!_mongoc_topology_description_has_set_version (topology) || - server->set_version > topology->max_set_version)) { - _mongoc_topology_description_set_max_set_version (topology, server); - } - - /* 'Server' is the primary! Invalidate other primaries if found */ - data.primary = server; - data.topology = topology; - mongoc_set_for_each (topology->servers, - _mongoc_topology_description_invalidate_primaries_cb, - &data); - - /* Add to topology description any new servers primary knows about */ - _mongoc_topology_description_add_new_servers (topology, server); - - /* Remove from topology description any servers primary doesn't know about */ - _mongoc_topology_description_remove_unreported_servers (topology, server); - - /* Finally, set topology type */ - _update_rs_type (topology); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_update_rs_without_primary -- - * - * Update cluster's information when there is no primary. - * - * Returns: - * None. - * - * Side Effects: - * Alters cluster state, may remove node from cluster. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_update_rs_without_primary ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - BSON_ASSERT (topology); - BSON_ASSERT (server); - - if (!_mongoc_topology_description_has_server ( - topology, server->connection_address, NULL)) { - return; - } - - /* make sure we're talking about the same replica set */ - if (server->set_name) { - if (!topology->set_name) { - topology->set_name = bson_strdup (server->set_name); - } else if (strcmp (topology->set_name, server->set_name) != 0) { - _mongoc_topology_description_remove_server (topology, server); - return; - } - } - - /* Add new servers that this replica set member knows about */ - _mongoc_topology_description_add_new_servers (topology, server); - - /* If this server thinks there is a primary, label it POSSIBLE_PRIMARY */ - if (server->current_primary) { - _mongoc_topology_description_label_unknown_member ( - topology, server->current_primary, MONGOC_SERVER_POSSIBLE_PRIMARY); - } - - if (!_mongoc_topology_description_matches_me (server)) { - _mongoc_topology_description_remove_server (topology, server); - return; - } -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_update_rs_with_primary_from_member -- - * - * Update cluster's information when there is a primary, but the - * update is coming from another replica set member. - * - * Returns: - * None. - * - * Side Effects: - * Alters cluster state. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_update_rs_with_primary_from_member ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - BSON_ASSERT (topology); - BSON_ASSERT (server); - - if (!_mongoc_topology_description_has_server ( - topology, server->connection_address, NULL)) { - return; - } - - /* set_name should never be null here */ - if (strcmp (topology->set_name, server->set_name) != 0) { - _mongoc_topology_description_remove_server (topology, server); - _update_rs_type (topology); - return; - } - - if (!_mongoc_topology_description_matches_me (server)) { - _mongoc_topology_description_remove_server (topology, server); - return; - } - - /* If there is no primary, label server's current_primary as the - * POSSIBLE_PRIMARY */ - if (!_mongoc_topology_description_has_primary (topology) && - server->current_primary) { - _mongoc_topology_description_set_state (topology, - MONGOC_TOPOLOGY_RS_NO_PRIMARY); - _mongoc_topology_description_label_unknown_member ( - topology, server->current_primary, MONGOC_SERVER_POSSIBLE_PRIMARY); - } -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_set_topology_type_to_sharded -- - * - * Sets topology's type to SHARDED. - * - * Returns: - * None - * - * Side effects: - * Alter's topology's type - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_set_topology_type_to_sharded ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - _mongoc_topology_description_set_state (topology, MONGOC_TOPOLOGY_SHARDED); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_transition_unknown_to_rs_no_primary -- - * - * Encapsulates transition from cluster state UNKNOWN to - * RS_NO_PRIMARY. Sets the type to RS_NO_PRIMARY, - * then updates the replica set accordingly. - * - * Returns: - * None. - * - * Side effects: - * Changes topology state. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_transition_unknown_to_rs_no_primary ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - _mongoc_topology_description_set_state (topology, - MONGOC_TOPOLOGY_RS_NO_PRIMARY); - _mongoc_topology_description_update_rs_without_primary (topology, server); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_remove_and_check_primary -- - * - * Remove the server and check if the topology still has a primary. - * - * Returns: - * None. - * - * Side effects: - * Removes server from topology and destroys it. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_remove_and_check_primary ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - _mongoc_topology_description_remove_server (topology, server); - _update_rs_type (topology); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_update_unknown_with_standalone -- - * - * If the cluster doesn't contain this server, do nothing. - * Otherwise, if the topology only has one seed, change its - * type to SINGLE. If the topology has multiple seeds, it does not - * include us, so remove this server and destroy it. - * - * Returns: - * None. - * - * Side effects: - * Changes the topology type, might remove server from topology. - * - *-------------------------------------------------------------------------- - */ -static void -_mongoc_topology_description_update_unknown_with_standalone ( - mongoc_topology_description_t *topology, mongoc_server_description_t *server) -{ - BSON_ASSERT (topology); - BSON_ASSERT (server); - - if (!_mongoc_topology_description_has_server ( - topology, server->connection_address, NULL)) - return; - - if (topology->servers->items_len > 1) { - /* This cluster contains other servers, it cannot be a standalone. */ - _mongoc_topology_description_remove_server (topology, server); - } else { - _mongoc_topology_description_set_state (topology, MONGOC_TOPOLOGY_SINGLE); - } -} - -/* - *-------------------------------------------------------------------------- - * - * This table implements the 'ToplogyType' table outlined in the Server - * Discovery and Monitoring spec. Each row represents a server type, - * and each column represents the topology type. Given a current topology - * type T and a newly-observed server type S, use the function at - * state_transions[S][T] to transition to a new state. - * - * Rows should be read like so: - * { server type for this row - * UNKNOWN, - * SHARDED, - * RS_NO_PRIMARY, - * RS_WITH_PRIMARY - * } - * - *-------------------------------------------------------------------------- - */ - -typedef void (*transition_t) (mongoc_topology_description_t *topology, - mongoc_server_description_t *server); - -transition_t gSDAMTransitionTable - [MONGOC_SERVER_DESCRIPTION_TYPES][MONGOC_TOPOLOGY_DESCRIPTION_TYPES] = { - { - /* UNKNOWN */ - NULL, /* MONGOC_TOPOLOGY_UNKNOWN */ - NULL, /* MONGOC_TOPOLOGY_SHARDED */ - NULL, /* MONGOC_TOPOLOGY_RS_NO_PRIMARY */ - _mongoc_topology_description_check_if_has_primary /* MONGOC_TOPOLOGY_RS_WITH_PRIMARY - */ - }, - {/* STANDALONE */ - _mongoc_topology_description_update_unknown_with_standalone, - _mongoc_topology_description_remove_server, - _mongoc_topology_description_remove_server, - _mongoc_topology_description_remove_and_check_primary}, - {/* MONGOS */ - _mongoc_topology_description_set_topology_type_to_sharded, - NULL, - _mongoc_topology_description_remove_server, - _mongoc_topology_description_remove_and_check_primary}, - {/* POSSIBLE_PRIMARY */ - NULL, - NULL, - NULL, - NULL}, - {/* PRIMARY */ - _mongoc_topology_description_update_rs_from_primary, - _mongoc_topology_description_remove_server, - _mongoc_topology_description_update_rs_from_primary, - _mongoc_topology_description_update_rs_from_primary}, - {/* SECONDARY */ - _mongoc_topology_description_transition_unknown_to_rs_no_primary, - _mongoc_topology_description_remove_server, - _mongoc_topology_description_update_rs_without_primary, - _mongoc_topology_description_update_rs_with_primary_from_member}, - {/* ARBITER */ - _mongoc_topology_description_transition_unknown_to_rs_no_primary, - _mongoc_topology_description_remove_server, - _mongoc_topology_description_update_rs_without_primary, - _mongoc_topology_description_update_rs_with_primary_from_member}, - {/* RS_OTHER */ - _mongoc_topology_description_transition_unknown_to_rs_no_primary, - _mongoc_topology_description_remove_server, - _mongoc_topology_description_update_rs_without_primary, - _mongoc_topology_description_update_rs_with_primary_from_member}, - {/* RS_GHOST */ - NULL, - _mongoc_topology_description_remove_server, - NULL, - _mongoc_topology_description_check_if_has_primary}}; - -#ifdef MONGOC_TRACE -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_type -- - * - * Get this topology's type, one of the types defined in the Server - * Discovery And Monitoring Spec. - * - * NOTE: this method should only be called while holding the mutex on - * the owning topology object. - * - * Returns: - * A string. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -static const char * -_mongoc_topology_description_type (mongoc_topology_description_t *topology) -{ - switch (topology->type) { - case MONGOC_TOPOLOGY_UNKNOWN: - return "Unknown"; - case MONGOC_TOPOLOGY_SHARDED: - return "Sharded"; - case MONGOC_TOPOLOGY_RS_NO_PRIMARY: - return "RSNoPrimary"; - case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: - return "RSWithPrimary"; - case MONGOC_TOPOLOGY_SINGLE: - return "Single"; - case MONGOC_TOPOLOGY_DESCRIPTION_TYPES: - default: - MONGOC_ERROR ("Invalid mongoc_topology_description_type_t type"); - return "Invalid"; - } -} -#endif - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_update_session_timeout -- - * - * Fill out td.session_timeout_minutes. - * - * Server Discovery and Monitoring Spec: "set logicalSessionTimeoutMinutes - * to the smallest logicalSessionTimeoutMinutes value among all - * ServerDescriptions of known ServerType. If any ServerDescription of - * known ServerType has a null logicalSessionTimeoutMinutes, then - * logicalSessionTimeoutMinutes MUST be set to null." - * - * -------------------------------------------------------------------------- - */ - -static void -_mongoc_topology_description_update_session_timeout ( - mongoc_topology_description_t *td) -{ - mongoc_set_t *set; - size_t i; - mongoc_server_description_t *sd; - - set = td->servers; - - td->session_timeout_minutes = MONGOC_NO_SESSIONS; - - for (i = 0; i < set->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (set, (int) i); - if (!_is_data_node (sd)) { - continue; - } - - if (sd->session_timeout_minutes == MONGOC_NO_SESSIONS) { - td->session_timeout_minutes = MONGOC_NO_SESSIONS; - return; - } else if (td->session_timeout_minutes == MONGOC_NO_SESSIONS) { - td->session_timeout_minutes = sd->session_timeout_minutes; - } else if (td->session_timeout_minutes > sd->session_timeout_minutes) { - td->session_timeout_minutes = sd->session_timeout_minutes; - } - } -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_description_check_compatible -- - * - * Fill out td.compatibility_error if any server's wire versions do - * not overlap with ours. Otherwise clear td.compatibility_error. - * - * If any server is incompatible, the topology as a whole is considered - * incompatible. - * - *-------------------------------------------------------------------------- - */ - -static void -_mongoc_topology_description_check_compatible ( - mongoc_topology_description_t *td) -{ - size_t i; - mongoc_server_description_t *sd; - - memset (&td->compatibility_error, 0, sizeof (bson_error_t)); - - for (i = 0; i < td->servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, - (int) i); - if (sd->type == MONGOC_SERVER_UNKNOWN || - sd->type == MONGOC_SERVER_POSSIBLE_PRIMARY) { - continue; - } - - if (sd->min_wire_version > WIRE_VERSION_MAX) { - bson_set_error ( - &td->compatibility_error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "Server at %s requires wire version %d," - " but this version of libmongoc only supports up to %d", - sd->host.host_and_port, - sd->min_wire_version, - WIRE_VERSION_MAX); - } else if (sd->max_wire_version < WIRE_VERSION_MIN) { - bson_set_error ( - &td->compatibility_error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "Server at %s reports wire version %d, but this" - " version of libmongoc requires at least 3 (MongoDB 3.0)", - sd->host.host_and_port, - sd->max_wire_version); - } - } -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_handle_ismaster -- - * - * Handle an ismaster. This is called by the background SDAM process, - * and by client when invalidating servers. If there was an error - * calling ismaster, pass it in as @error. - * - * NOTE: this method should only be called while holding the mutex on - * the owning topology object. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_topology_description_handle_ismaster ( - mongoc_topology_description_t *topology, - uint32_t server_id, - const bson_t *ismaster_response, - int64_t rtt_msec, - const bson_error_t *error /* IN */) -{ - mongoc_topology_description_t *prev_td = NULL; - mongoc_server_description_t *prev_sd = NULL; - mongoc_server_description_t *sd; - - BSON_ASSERT (topology); - BSON_ASSERT (server_id != 0); - - sd = mongoc_topology_description_server_by_id (topology, server_id, NULL); - if (!sd) { - return; /* server already removed from topology */ - } - - if (topology->apm_callbacks.topology_changed) { - prev_td = bson_malloc0 (sizeof (mongoc_topology_description_t)); - _mongoc_topology_description_copy_to (topology, prev_td); - } - - if (topology->apm_callbacks.server_changed) { - prev_sd = mongoc_server_description_new_copy (sd); - } - - /* pass the current error in */ - mongoc_server_description_handle_ismaster ( - sd, ismaster_response, rtt_msec, error); - - mongoc_topology_description_update_cluster_time (topology, - ismaster_response); - _mongoc_topology_description_monitor_server_changed (topology, prev_sd, sd); - - if (gSDAMTransitionTable[sd->type][topology->type]) { - TRACE ("Transitioning to %s for %s", - _mongoc_topology_description_type (topology), - mongoc_server_description_type (sd)); - gSDAMTransitionTable[sd->type][topology->type](topology, sd); - } else { - TRACE ("No transition entry to %s for %s", - _mongoc_topology_description_type (topology), - mongoc_server_description_type (sd)); - } - - _mongoc_topology_description_update_session_timeout (topology); - - /* Don't bother checking wire version compatibility if we already errored */ - if (ismaster_response && (!error || !error->code)) { - _mongoc_topology_description_check_compatible (topology); - } - _mongoc_topology_description_monitor_changed (prev_td, topology); - - if (prev_td) { - mongoc_topology_description_destroy (prev_td); - bson_free (prev_td); - } - - if (prev_sd) { - mongoc_server_description_destroy (prev_sd); - } -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_has_readable_server -- - * - * SDAM Monitoring Spec: - * "Determines if the topology has a readable server available." - * - * NOTE: this method should only be called by user code in an SDAM - * Monitoring callback, while the monitoring framework holds the mutex - * on the owning topology object. - * - *-------------------------------------------------------------------------- - */ -bool -mongoc_topology_description_has_readable_server ( - mongoc_topology_description_t *td, const mongoc_read_prefs_t *prefs) -{ - bson_error_t error; - - if (!mongoc_topology_compatible (td, NULL, &error)) { - return false; - } - - /* local threshold argument doesn't matter */ - return mongoc_topology_description_select (td, MONGOC_SS_READ, prefs, 0) != - NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_has_writable_server -- - * - * SDAM Monitoring Spec: - * "Determines if the topology has a writable server available." - * - * NOTE: this method should only be called by user code in an SDAM - * Monitoring callback, while the monitoring framework holds the mutex - * on the owning topology object. - * - *-------------------------------------------------------------------------- - */ -bool -mongoc_topology_description_has_writable_server ( - mongoc_topology_description_t *td) -{ - bson_error_t error; - - if (!mongoc_topology_compatible (td, NULL, &error)) { - return false; - } - - return mongoc_topology_description_select (td, MONGOC_SS_WRITE, NULL, 0) != - NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_type -- - * - * Get this topology's type, one of the types defined in the Server - * Discovery And Monitoring Spec. - * - * NOTE: this method should only be called by user code in an SDAM - * Monitoring callback, while the monitoring framework holds the mutex - * on the owning topology object. - * - * Returns: - * A string. - * - *-------------------------------------------------------------------------- - */ -const char * -mongoc_topology_description_type (const mongoc_topology_description_t *td) -{ - switch (td->type) { - case MONGOC_TOPOLOGY_UNKNOWN: - return "Unknown"; - case MONGOC_TOPOLOGY_SHARDED: - return "Sharded"; - case MONGOC_TOPOLOGY_RS_NO_PRIMARY: - return "ReplicaSetNoPrimary"; - case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: - return "ReplicaSetWithPrimary"; - case MONGOC_TOPOLOGY_SINGLE: - return "Single"; - case MONGOC_TOPOLOGY_DESCRIPTION_TYPES: - default: - fprintf (stderr, "ERROR: Unknown topology type %d\n", td->type); - BSON_ASSERT (0); - } - - return NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_description_get_servers -- - * - * Fetch an array of server descriptions for all known servers in the - * topology. - * - * Returns: - * An array you must free with mongoc_server_descriptions_destroy_all. - * - *-------------------------------------------------------------------------- - */ -mongoc_server_description_t ** -mongoc_topology_description_get_servers ( - const mongoc_topology_description_t *td, size_t *n /* OUT */) -{ - size_t i; - mongoc_set_t *set; - mongoc_server_description_t **sds; - mongoc_server_description_t *sd; - - BSON_ASSERT (td); - BSON_ASSERT (n); - - set = td->servers; - - /* enough room for all descriptions, even if some are unknown */ - sds = (mongoc_server_description_t **) bson_malloc0 ( - sizeof (mongoc_server_description_t *) * set->items_len); - - *n = 0; - - for (i = 0; i < set->items_len; ++i) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (set, (int) i); - - if (sd->type != MONGOC_SERVER_UNKNOWN) { - sds[*n] = mongoc_server_description_new_copy (sd); - ++(*n); - } - } - - return sds; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description.h deleted file mode 100644 index 0125f30f202e2e806a52746daf6c3ac14c2cc4a7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-description.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2016 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_TOPOLOGY_DESCRIPTION_H -#define MONGOC_TOPOLOGY_DESCRIPTION_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-read-prefs.h" - - -BSON_BEGIN_DECLS - -typedef struct _mongoc_topology_description_t mongoc_topology_description_t; - -MONGOC_EXPORT (bool) -mongoc_topology_description_has_readable_server ( - mongoc_topology_description_t *td, const mongoc_read_prefs_t *prefs); -MONGOC_EXPORT (bool) -mongoc_topology_description_has_writable_server ( - mongoc_topology_description_t *td); -MONGOC_EXPORT (const char *) -mongoc_topology_description_type (const mongoc_topology_description_t *td); -MONGOC_EXPORT (mongoc_server_description_t **) -mongoc_topology_description_get_servers ( - const mongoc_topology_description_t *td, size_t *n); - -BSON_END_DECLS - -#endif /* MONGOC_TOPOLOGY_DESCRIPTION_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-private.h deleted file mode 100644 index ba3740ad944e32272deec76d621b11bf65facf2b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-private.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_TOPOLOGY_PRIVATE_H -#define MONGOC_TOPOLOGY_PRIVATE_H - -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-topology-scanner-private.h" -#include "mongoc/mongoc-server-description-private.h" -#include "mongoc/mongoc-topology-description-private.h" -#include "mongoc/mongoc-thread-private.h" -#include "mongoc/mongoc-uri.h" -#include "mongoc/mongoc-client-session-private.h" - -#define MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS 500 -#define MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS 5000 -#define MONGOC_TOPOLOGY_COOLDOWN_MS 5000 -#define MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS 15 -#define MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS 30000 -#define MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED 10000 -#define MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED 60000 -#define MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS 60000 - -typedef enum { - MONGOC_TOPOLOGY_SCANNER_OFF, - MONGOC_TOPOLOGY_SCANNER_BG_RUNNING, - MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN, - MONGOC_TOPOLOGY_SCANNER_SINGLE_THREADED, -} mongoc_topology_scanner_state_t; - -typedef struct _mongoc_topology_t { - mongoc_topology_description_t description; - mongoc_uri_t *uri; - mongoc_topology_scanner_t *scanner; - bool server_selection_try_once; - - int64_t last_scan; - int64_t local_threshold_msec; - int64_t connect_timeout_msec; - int64_t server_selection_timeout_msec; - /* defaults to 500ms, configurable by tests */ - int64_t min_heartbeat_frequency_msec; - - /* Minimum of SRV record TTLs, but no lower than 60 seconds. - * May be zero for non-SRV/non-MongoS topology. */ - int64_t rescanSRVIntervalMS; - int64_t last_srv_scan; - - bson_mutex_t mutex; - mongoc_cond_t cond_client; - mongoc_cond_t cond_server; - bson_thread_t thread; - - mongoc_topology_scanner_state_t scanner_state; - bool scan_requested; - bool single_threaded; - bool stale; - - mongoc_server_session_t *session_pool; -} mongoc_topology_t; - -mongoc_topology_t * -mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded); - -void -mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology, - mongoc_apm_callbacks_t *callbacks, - void *context); - -void -mongoc_topology_destroy (mongoc_topology_t *topology); - -void -mongoc_topology_reconcile (mongoc_topology_t *topology); - -bool -mongoc_topology_compatible (const mongoc_topology_description_t *td, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error); - -mongoc_server_description_t * -mongoc_topology_select (mongoc_topology_t *topology, - mongoc_ss_optype_t optype, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error); - -uint32_t -mongoc_topology_select_server_id (mongoc_topology_t *topology, - mongoc_ss_optype_t optype, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error); - -mongoc_server_description_t * -mongoc_topology_server_by_id (mongoc_topology_t *topology, - uint32_t id, - bson_error_t *error); - -mongoc_host_list_t * -_mongoc_topology_host_by_id (mongoc_topology_t *topology, - uint32_t id, - bson_error_t *error); - -void -mongoc_topology_invalidate_server (mongoc_topology_t *topology, - uint32_t id, - const bson_error_t *error); - -bool -_mongoc_topology_update_from_handshake (mongoc_topology_t *topology, - const mongoc_server_description_t *sd); - -void -_mongoc_topology_update_last_used (mongoc_topology_t *topology, - uint32_t server_id); - -int64_t -mongoc_topology_server_timestamp (mongoc_topology_t *topology, uint32_t id); - -mongoc_topology_description_type_t -_mongoc_topology_get_type (mongoc_topology_t *topology); - -bool -_mongoc_topology_start_background_scanner (mongoc_topology_t *topology); - -void -_mongoc_topology_background_thread_stop (mongoc_topology_t *topology); - -bool -_mongoc_topology_set_appname (mongoc_topology_t *topology, const char *appname); - -void -_mongoc_topology_update_cluster_time (mongoc_topology_t *topology, - const bson_t *reply); - -mongoc_server_session_t * -_mongoc_topology_pop_server_session (mongoc_topology_t *topology, - bson_error_t *error); - -void -_mongoc_topology_push_server_session (mongoc_topology_t *topology, - mongoc_server_session_t *server_session); - -bool -_mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd); - -void -_mongoc_topology_clear_session_pool (mongoc_topology_t *topology); - -void -_mongoc_topology_do_blocking_scan (mongoc_topology_t *topology, - bson_error_t *error); -const bson_t * -_mongoc_topology_get_ismaster (mongoc_topology_t *topology); -void -_mongoc_topology_request_scan (mongoc_topology_t *topology); - -void -_mongoc_topology_bypass_cooldown (mongoc_topology_t *topology); -#endif diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-scanner-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-scanner-private.h deleted file mode 100644 index 8042816914b46eb220f19e69463fda0f3e816b1c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-scanner-private.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_TOPOLOGY_SCANNER_PRIVATE_H -#define MONGOC_TOPOLOGY_SCANNER_PRIVATE_H - -/* TODO: rename to TOPOLOGY scanner */ - -#include <bson/bson.h> -#include "mongoc/mongoc-async-private.h" -#include "mongoc/mongoc-async-cmd-private.h" -#include "mongoc/mongoc-handshake-private.h" -#include "mongoc/mongoc-host-list.h" -#include "mongoc/mongoc-apm-private.h" - -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-ssl.h" -#endif - -BSON_BEGIN_DECLS - -typedef void (*mongoc_topology_scanner_setup_err_cb_t) ( - uint32_t id, void *data, const bson_error_t *error /* IN */); - -typedef void (*mongoc_topology_scanner_cb_t) ( - uint32_t id, - const bson_t *bson, - int64_t rtt, - void *data, - const bson_error_t *error /* IN */); - -struct mongoc_topology_scanner; -struct mongoc_topology_scanner_node; - -typedef struct mongoc_topology_scanner_node { - uint32_t id; - /* after scanning, this is set to the successful stream if one exists. */ - mongoc_stream_t *stream; - - int64_t timestamp; - int64_t last_used; - int64_t last_failed; - bool has_auth; - mongoc_host_list_t host; - struct mongoc_topology_scanner *ts; - - struct mongoc_topology_scanner_node *next; - struct mongoc_topology_scanner_node *prev; - - bool retired; - bson_error_t last_error; - - /* the hostname for a node may resolve to multiple DNS results. - * dns_results has the full list of DNS results, ordered by host preference. - * successful_dns_result is the most recent successful DNS result. - */ - struct addrinfo *dns_results; - struct addrinfo *successful_dns_result; - int64_t last_dns_cache; - - /* used by single-threaded clients to store negotiated sasl mechanisms on a - * node. */ - mongoc_handshake_sasl_supported_mechs_t sasl_supported_mechs; - bool negotiated_sasl_supported_mechs; -} mongoc_topology_scanner_node_t; - -typedef struct mongoc_topology_scanner { - mongoc_async_t *async; - int64_t connect_timeout_msec; - mongoc_topology_scanner_node_t *nodes; - bson_t ismaster_cmd; - bson_t ismaster_cmd_with_handshake; - bson_t cluster_time; - bool handshake_ok_to_send; - const char *appname; - - mongoc_topology_scanner_setup_err_cb_t setup_err_cb; - mongoc_topology_scanner_cb_t cb; - void *cb_data; - const mongoc_uri_t *uri; - mongoc_async_cmd_setup_t setup; - mongoc_stream_initiator_t initiator; - void *initiator_context; - bson_error_t error; - -#ifdef MONGOC_ENABLE_SSL - mongoc_ssl_opt_t *ssl_opts; -#endif - - mongoc_apm_callbacks_t apm_callbacks; - void *apm_context; - int64_t dns_cache_timeout_ms; - /* only used by single-threaded clients to negotiate auth mechanisms. */ - bool negotiate_sasl_supported_mechs; - bool bypass_cooldown; -} mongoc_topology_scanner_t; - -mongoc_topology_scanner_t * -mongoc_topology_scanner_new ( - const mongoc_uri_t *uri, - mongoc_topology_scanner_setup_err_cb_t setup_err_cb, - mongoc_topology_scanner_cb_t cb, - void *data, - int64_t connect_timeout_msec); - -void -mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts); - -bool -mongoc_topology_scanner_valid (mongoc_topology_scanner_t *ts); - -void -mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts, - const mongoc_host_list_t *host, - uint32_t id); - -void -mongoc_topology_scanner_scan (mongoc_topology_scanner_t *ts, uint32_t id); - -void -mongoc_topology_scanner_disconnect (mongoc_topology_scanner_t *scanner); - -void -mongoc_topology_scanner_node_retire (mongoc_topology_scanner_node_t *node); - -void -mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node, - bool failed); - -void -mongoc_topology_scanner_node_destroy (mongoc_topology_scanner_node_t *node, - bool failed); - -bool -mongoc_topology_scanner_in_cooldown (mongoc_topology_scanner_t *ts, - int64_t when); - -void -mongoc_topology_scanner_start (mongoc_topology_scanner_t *ts, - bool obey_cooldown); - -void -mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts); - -void -_mongoc_topology_scanner_finish (mongoc_topology_scanner_t *ts); - -void -mongoc_topology_scanner_get_error (mongoc_topology_scanner_t *ts, - bson_error_t *error); - -void -mongoc_topology_scanner_reset (mongoc_topology_scanner_t *ts); - -void -mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node, - bson_error_t *error); - -mongoc_topology_scanner_node_t * -mongoc_topology_scanner_get_node (mongoc_topology_scanner_t *ts, uint32_t id); - -const bson_t * -_mongoc_topology_scanner_get_ismaster (mongoc_topology_scanner_t *ts); - -bool -mongoc_topology_scanner_has_node_for_host (mongoc_topology_scanner_t *ts, - mongoc_host_list_t *host); - -void -mongoc_topology_scanner_set_stream_initiator (mongoc_topology_scanner_t *ts, - mongoc_stream_initiator_t si, - void *ctx); -bool -_mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts, - const char *name); -void -_mongoc_topology_scanner_set_cluster_time (mongoc_topology_scanner_t *ts, - const bson_t *cluster_time); - -void -_mongoc_topology_scanner_set_dns_cache_timeout (mongoc_topology_scanner_t *ts, - int64_t timeout_ms); - -#ifdef MONGOC_ENABLE_SSL -void -mongoc_topology_scanner_set_ssl_opts (mongoc_topology_scanner_t *ts, - mongoc_ssl_opt_t *opts); -#endif - -bool -mongoc_topology_scanner_node_in_cooldown (mongoc_topology_scanner_node_t *node, - int64_t when); - -/* for testing. */ -mongoc_stream_t * -_mongoc_topology_scanner_tcp_initiate (mongoc_async_cmd_t *acmd); - -BSON_END_DECLS - -#endif /* MONGOC_TOPOLOGY_SCANNER_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-scanner.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-scanner.c deleted file mode 100644 index 4b9e3751d88394f0aa9d8d8895e17bc273465e9a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology-scanner.c +++ /dev/null @@ -1,1179 +0,0 @@ -/* - * Copyright 2014 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 <bson/bson.h> - -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-topology-scanner-private.h" -#include "mongoc/mongoc-stream-private.h" -#include "mongoc/mongoc-stream-socket.h" - -#include "mongoc/mongoc-handshake.h" -#include "mongoc/mongoc-handshake-private.h" - -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-stream-tls.h" -#endif - -#include "mongoc/mongoc-counters-private.h" -#include "mongoc/utlist.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-uri-private.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "topology_scanner" - -#define DNS_CACHE_TIMEOUT_MS 10 * 60 * 1000 -#define HAPPY_EYEBALLS_DELAY_MS 250 - -/* forward declarations */ -static void -_async_connected (mongoc_async_cmd_t *acmd); - -static void -_async_success (mongoc_async_cmd_t *acmd, - const bson_t *ismaster_response, - int64_t duration_usec); - -static void -_async_error_or_timeout (mongoc_async_cmd_t *acmd, - int64_t duration_usec, - const char *default_err_msg); - -static void -_async_handler (mongoc_async_cmd_t *acmd, - mongoc_async_cmd_result_t async_status, - const bson_t *ismaster_response, - int64_t duration_usec); - -static void -_mongoc_topology_scanner_monitor_heartbeat_started ( - const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host); - -static void -_mongoc_topology_scanner_monitor_heartbeat_succeeded ( - const mongoc_topology_scanner_t *ts, - const mongoc_host_list_t *host, - const bson_t *reply, - int64_t duration_usec); - -static void -_mongoc_topology_scanner_monitor_heartbeat_failed ( - const mongoc_topology_scanner_t *ts, - const mongoc_host_list_t *host, - const bson_error_t *error, - int64_t duration_usec); - - -/* reset "retired" nodes that failed or were removed in the previous scan */ -static void -_delete_retired_nodes (mongoc_topology_scanner_t *ts); - -/* cancel any pending async commands for a specific node excluding acmd. - * If acmd is NULL, cancel all async commands on the node. */ -static void -_cancel_commands_excluding (mongoc_topology_scanner_node_t *node, - mongoc_async_cmd_t *acmd); - -/* return the number of pending async commands for a node. */ -static int -_count_acmds (mongoc_topology_scanner_node_t *node); - -/* if acmd fails, schedule the sibling commands sooner. */ -static void -_jumpstart_other_acmds (mongoc_topology_scanner_node_t *node, - mongoc_async_cmd_t *acmd); - -static void -_add_ismaster (bson_t *cmd) -{ - BSON_APPEND_INT32 (cmd, "isMaster", 1); -} - -static bool -_build_ismaster_with_handshake (mongoc_topology_scanner_t *ts) -{ - bson_t *doc = &ts->ismaster_cmd_with_handshake; - bson_t subdoc; - bson_iter_t iter; - const char *key; - int keylen; - bool res; - const bson_t *compressors; - int count = 0; - char buf[16]; - - _add_ismaster (doc); - - BSON_APPEND_DOCUMENT_BEGIN (doc, HANDSHAKE_FIELD, &subdoc); - res = _mongoc_handshake_build_doc_with_application (&subdoc, ts->appname); - bson_append_document_end (doc, &subdoc); - - BSON_APPEND_ARRAY_BEGIN (doc, "compression", &subdoc); - if (ts->uri) { - compressors = mongoc_uri_get_compressors (ts->uri); - - if (bson_iter_init (&iter, compressors)) { - while (bson_iter_next (&iter)) { - keylen = bson_uint32_to_string (count++, &key, buf, sizeof buf); - bson_append_utf8 ( - &subdoc, key, (int) keylen, bson_iter_key (&iter), -1); - } - } - } - bson_append_array_end (doc, &subdoc); - - /* Return whether the handshake doc fit the size limit */ - return res; -} - -/* Caller must lock topology->mutex to protect ismaster_cmd_with_handshake. This - * is called at the start of the scan in _mongoc_topology_run_background, when a - * node is added in _mongoc_topology_reconcile_add_nodes, or when running an - * ismaster directly on a node in _mongoc_stream_run_ismaster. */ -const bson_t * -_mongoc_topology_scanner_get_ismaster (mongoc_topology_scanner_t *ts) -{ - /* If this is the first time using the node or if it's the first time - * using it after a failure, build handshake doc */ - if (bson_empty (&ts->ismaster_cmd_with_handshake)) { - ts->handshake_ok_to_send = _build_ismaster_with_handshake (ts); - if (!ts->handshake_ok_to_send) { - MONGOC_WARNING ("Handshake doc too big, not including in isMaster"); - } - } - - /* If the doc turned out to be too big */ - if (!ts->handshake_ok_to_send) { - return &ts->ismaster_cmd; - } - - return &ts->ismaster_cmd_with_handshake; -} - -static void -_begin_ismaster_cmd (mongoc_topology_scanner_node_t *node, - mongoc_stream_t *stream, - bool is_setup_done, - struct addrinfo *dns_result, - int64_t initiate_delay_ms) -{ - mongoc_topology_scanner_t *ts = node->ts; - bson_t cmd; - - if (node->last_used != -1 && node->last_failed == -1) { - /* The node's been used before and not failed recently */ - bson_copy_to (&ts->ismaster_cmd, &cmd); - } else { - bson_copy_to (_mongoc_topology_scanner_get_ismaster (ts), &cmd); - } - - if (node->ts->negotiate_sasl_supported_mechs && - !node->negotiated_sasl_supported_mechs) { - _mongoc_handshake_append_sasl_supported_mechs (ts->uri, &cmd); - } - - if (!bson_empty (&ts->cluster_time)) { - bson_append_document (&cmd, "$clusterTime", 12, &ts->cluster_time); - } - - /* if the node should connect with a TCP socket, stream will be null, and - * dns_result will be set. The async loop is responsible for calling the - * _tcp_initiator to construct TCP sockets. */ - mongoc_async_cmd_new (ts->async, - stream, - is_setup_done, - dns_result, - _mongoc_topology_scanner_tcp_initiate, - initiate_delay_ms, - ts->setup, - node->host.host, - "admin", - &cmd, - &_async_handler, - node, - ts->connect_timeout_msec); - - bson_destroy (&cmd); -} - - -mongoc_topology_scanner_t * -mongoc_topology_scanner_new ( - const mongoc_uri_t *uri, - mongoc_topology_scanner_setup_err_cb_t setup_err_cb, - mongoc_topology_scanner_cb_t cb, - void *data, - int64_t connect_timeout_msec) -{ - mongoc_topology_scanner_t *ts = - (mongoc_topology_scanner_t *) bson_malloc0 (sizeof (*ts)); - - ts->async = mongoc_async_new (); - - bson_init (&ts->ismaster_cmd); - _add_ismaster (&ts->ismaster_cmd); - bson_init (&ts->ismaster_cmd_with_handshake); - bson_init (&ts->cluster_time); - - ts->setup_err_cb = setup_err_cb; - ts->cb = cb; - ts->cb_data = data; - ts->uri = uri; - ts->appname = NULL; - ts->handshake_ok_to_send = false; - ts->connect_timeout_msec = connect_timeout_msec; - /* may be overridden for testing. */ - ts->dns_cache_timeout_ms = DNS_CACHE_TIMEOUT_MS; - - return ts; -} - -#ifdef MONGOC_ENABLE_SSL -void -mongoc_topology_scanner_set_ssl_opts (mongoc_topology_scanner_t *ts, - mongoc_ssl_opt_t *opts) -{ - ts->ssl_opts = opts; - ts->setup = mongoc_async_cmd_tls_setup; -} -#endif - -void -mongoc_topology_scanner_set_stream_initiator (mongoc_topology_scanner_t *ts, - mongoc_stream_initiator_t si, - void *ctx) -{ - ts->initiator = si; - ts->initiator_context = ctx; - ts->setup = NULL; -} - -void -mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts) -{ - mongoc_topology_scanner_node_t *ele, *tmp; - - DL_FOREACH_SAFE (ts->nodes, ele, tmp) - { - mongoc_topology_scanner_node_destroy (ele, false); - } - - mongoc_async_destroy (ts->async); - bson_destroy (&ts->ismaster_cmd); - bson_destroy (&ts->ismaster_cmd_with_handshake); - bson_destroy (&ts->cluster_time); - - /* This field can be set by a mongoc_client */ - bson_free ((char *) ts->appname); - - bson_free (ts); -} - -/* whether the scanner was successfully initialized - false if a mongodb+srv - * URI failed to resolve to any hosts */ -bool -mongoc_topology_scanner_valid (mongoc_topology_scanner_t *ts) -{ - return ts->nodes != NULL; -} - -void -mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts, - const mongoc_host_list_t *host, - uint32_t id) -{ - mongoc_topology_scanner_node_t *node; - - node = (mongoc_topology_scanner_node_t *) bson_malloc0 (sizeof (*node)); - - memcpy (&node->host, host, sizeof (*host)); - - node->id = id; - node->ts = ts; - node->last_failed = -1; - node->last_used = -1; - - DL_APPEND (ts->nodes, node); -} - -void -mongoc_topology_scanner_scan (mongoc_topology_scanner_t *ts, uint32_t id) -{ - mongoc_topology_scanner_node_t *node; - - node = mongoc_topology_scanner_get_node (ts, id); - - /* begin non-blocking connection, don't wait for success */ - if (node) { - mongoc_topology_scanner_node_setup (node, &node->last_error); - } - - /* if setup fails the node stays in the scanner. destroyed after the scan. */ -} - -void -mongoc_topology_scanner_disconnect (mongoc_topology_scanner_t *scanner) -{ - mongoc_topology_scanner_node_t *node; - - BSON_ASSERT (scanner); - node = scanner->nodes; - - while (node) { - mongoc_topology_scanner_node_disconnect (node, false); - node = node->next; - } -} - -void -mongoc_topology_scanner_node_retire (mongoc_topology_scanner_node_t *node) -{ - /* cancel any pending commands. */ - _cancel_commands_excluding (node, NULL); - - node->retired = true; -} - -void -mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node, - bool failed) -{ - /* the node may or may not have succeeded in finding a working stream. */ - if (node->stream) { - if (failed) { - mongoc_stream_failed (node->stream); - } else { - mongoc_stream_destroy (node->stream); - } - - node->stream = NULL; - memset ( - &node->sasl_supported_mechs, 0, sizeof (node->sasl_supported_mechs)); - node->negotiated_sasl_supported_mechs = false; - } -} - -void -mongoc_topology_scanner_node_destroy (mongoc_topology_scanner_node_t *node, - bool failed) -{ - DL_DELETE (node->ts->nodes, node); - mongoc_topology_scanner_node_disconnect (node, failed); - if (node->dns_results) { - freeaddrinfo (node->dns_results); - } - bson_free (node); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_get_node -- - * - * Return the scanner node with the given id. - * - *-------------------------------------------------------------------------- - */ -mongoc_topology_scanner_node_t * -mongoc_topology_scanner_get_node (mongoc_topology_scanner_t *ts, uint32_t id) -{ - mongoc_topology_scanner_node_t *ele, *tmp; - - DL_FOREACH_SAFE (ts->nodes, ele, tmp) - { - if (ele->id == id) { - return ele; - } - - if (ele->id > id) { - break; - } - } - - return NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_has_node_for_host -- - * - * Whether the scanner has a node for the given host and port. - * - *-------------------------------------------------------------------------- - */ -bool -mongoc_topology_scanner_has_node_for_host (mongoc_topology_scanner_t *ts, - mongoc_host_list_t *host) -{ - mongoc_topology_scanner_node_t *ele, *tmp; - - DL_FOREACH_SAFE (ts->nodes, ele, tmp) - { - if (_mongoc_host_list_equal (&ele->host, host)) { - return true; - } - } - - return false; -} - -static void -_async_connected (mongoc_async_cmd_t *acmd) -{ - mongoc_topology_scanner_node_t *node = - (mongoc_topology_scanner_node_t *) acmd->data; - /* this cmd connected successfully, cancel other cmds on this node. */ - _cancel_commands_excluding (node, acmd); - node->successful_dns_result = acmd->dns_result; -} - -static void -_async_success (mongoc_async_cmd_t *acmd, - const bson_t *ismaster_response, - int64_t duration_usec) -{ - void *data = acmd->data; - mongoc_topology_scanner_node_t *node = - (mongoc_topology_scanner_node_t *) data; - mongoc_stream_t *stream = acmd->stream; - mongoc_topology_scanner_t *ts = node->ts; - - if (node->retired) { - if (stream) { - mongoc_stream_failed (stream); - } - return; - } - - node->last_used = bson_get_monotonic_time (); - node->last_failed = -1; - - _mongoc_topology_scanner_monitor_heartbeat_succeeded ( - ts, &node->host, ismaster_response, duration_usec); - - /* set our successful stream. */ - BSON_ASSERT (!node->stream); - node->stream = stream; - - if (ts->negotiate_sasl_supported_mechs && - !node->negotiated_sasl_supported_mechs) { - _mongoc_handshake_parse_sasl_supported_mechs ( - ismaster_response, &node->sasl_supported_mechs); - } - - /* mongoc_topology_scanner_cb_t takes rtt_msec, not usec */ - ts->cb (node->id, - ismaster_response, - duration_usec / 1000, - ts->cb_data, - &acmd->error); -} - -static void -_async_error_or_timeout (mongoc_async_cmd_t *acmd, - int64_t duration_usec, - const char *default_err_msg) -{ - void *data = acmd->data; - mongoc_topology_scanner_node_t *node = - (mongoc_topology_scanner_node_t *) data; - mongoc_stream_t *stream = acmd->stream; - mongoc_topology_scanner_t *ts = node->ts; - bson_error_t *error = &acmd->error; - int64_t now = bson_get_monotonic_time (); - const char *message; - - /* the stream may have failed on initiation. */ - if (stream) { - mongoc_stream_failed (stream); - } - - if (node->retired) { - return; - } - - node->last_used = now; - - if (!node->stream && _count_acmds (node) == 1) { - /* there are no remaining streams, connecting has failed. */ - node->last_failed = now; - if (error->code) { - message = error->message; - } else { - message = default_err_msg; - } - - /* invalidate any cached DNS results. */ - if (node->dns_results) { - freeaddrinfo (node->dns_results); - node->dns_results = NULL; - node->successful_dns_result = NULL; - } - - bson_set_error (&node->last_error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_STREAM_CONNECT, - "%s calling ismaster on \'%s\'", - message, - node->host.host_and_port); - - _mongoc_topology_scanner_monitor_heartbeat_failed ( - ts, &node->host, &node->last_error, duration_usec); - - /* call the topology scanner callback. cannot connect to this node. - * callback takes rtt_msec, not usec. */ - ts->cb (node->id, NULL, duration_usec / 1000, ts->cb_data, error); - } else { - /* there are still more commands left for this node or it succeeded - * with another stream. skip the topology scanner callback. */ - _jumpstart_other_acmds (node, acmd); - } -} - -/* - *----------------------------------------------------------------------- - * - * This is the callback passed to async_cmd when we're running - * ismasters from within the topology monitor. - * - *----------------------------------------------------------------------- - */ - -static void -_async_handler (mongoc_async_cmd_t *acmd, - mongoc_async_cmd_result_t async_status, - const bson_t *ismaster_response, - int64_t duration_usec) -{ - BSON_ASSERT (acmd->data); - - switch (async_status) { - case MONGOC_ASYNC_CMD_CONNECTED: - _async_connected (acmd); - return; - case MONGOC_ASYNC_CMD_SUCCESS: - _async_success (acmd, ismaster_response, duration_usec); - return; - case MONGOC_ASYNC_CMD_TIMEOUT: - _async_error_or_timeout (acmd, duration_usec, "connection timeout"); - return; - case MONGOC_ASYNC_CMD_ERROR: - _async_error_or_timeout (acmd, duration_usec, "connection error"); - return; - case MONGOC_ASYNC_CMD_IN_PROGRESS: - default: - fprintf (stderr, "unexpected async status: %d\n", async_status); - BSON_ASSERT (false); - return; - } -} - -mongoc_stream_t * -_mongoc_topology_scanner_node_setup_stream_for_tls ( - mongoc_topology_scanner_node_t *node, mongoc_stream_t *stream) -{ -#ifdef MONGOC_ENABLE_SSL - mongoc_stream_t *tls_stream; -#endif - if (!stream) { - return NULL; - } -#ifdef MONGOC_ENABLE_SSL - if (node->ts->ssl_opts) { - tls_stream = mongoc_stream_tls_new_with_hostname ( - stream, node->host.host, node->ts->ssl_opts, 1); - if (!tls_stream) { - mongoc_stream_destroy (stream); - return NULL; - } else { - return tls_stream; - } - } -#endif - return stream; -} - -/* attempt to create a new socket stream using this dns result. */ -mongoc_stream_t * -_mongoc_topology_scanner_tcp_initiate (mongoc_async_cmd_t *acmd) -{ - mongoc_topology_scanner_node_t *node = - (mongoc_topology_scanner_node_t *) acmd->data; - struct addrinfo *res = acmd->dns_result; - mongoc_socket_t *sock = NULL; - - BSON_ASSERT (acmd->dns_result); - /* create a new non-blocking socket. */ - if (!(sock = mongoc_socket_new ( - res->ai_family, res->ai_socktype, res->ai_protocol))) { - return NULL; - } - - (void) mongoc_socket_connect ( - sock, res->ai_addr, (mongoc_socklen_t) res->ai_addrlen, 0); - - return _mongoc_topology_scanner_node_setup_stream_for_tls ( - node, mongoc_stream_socket_new (sock)); -} -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_node_setup_tcp -- - * - * Create an async command for each DNS record found for this node. - * - * Returns: - * A bool. On failure error is set. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_topology_scanner_node_setup_tcp (mongoc_topology_scanner_node_t *node, - bson_error_t *error) -{ - struct addrinfo hints; - struct addrinfo *iter; - char portstr[8]; - mongoc_host_list_t *host; - int s; - int64_t delay = 0; - int64_t now = bson_get_monotonic_time (); - - ENTRY; - - host = &node->host; - - /* if cached dns results are expired, flush. */ - if (node->dns_results && - (now - node->last_dns_cache) > node->ts->dns_cache_timeout_ms * 1000) { - freeaddrinfo (node->dns_results); - node->dns_results = NULL; - node->successful_dns_result = NULL; - } - - if (!node->dns_results) { - bson_snprintf (portstr, sizeof portstr, "%hu", host->port); - - memset (&hints, 0, sizeof hints); - hints.ai_family = host->family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = 0; - hints.ai_protocol = 0; - - s = getaddrinfo (host->host, portstr, &hints, &node->dns_results); - - if (s != 0) { - mongoc_counter_dns_failure_inc (); - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NAME_RESOLUTION, - "Failed to resolve '%s'", - host->host); - RETURN (false); - } - - mongoc_counter_dns_success_inc (); - node->last_dns_cache = now; - } - - if (node->successful_dns_result) { - _begin_ismaster_cmd (node, NULL, false, node->successful_dns_result, 0); - } else { - LL_FOREACH2 (node->dns_results, iter, ai_next) - { - _begin_ismaster_cmd (node, NULL, false, iter, delay); - /* each subsequent DNS result will have an additional 250ms delay. */ - delay += HAPPY_EYEBALLS_DELAY_MS; - } - } - - RETURN (true); -} - -bool -mongoc_topology_scanner_node_connect_unix (mongoc_topology_scanner_node_t *node, - bson_error_t *error) -{ -#ifdef _WIN32 - ENTRY; - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "UNIX domain sockets not supported on win32."); - RETURN (false); -#else - struct sockaddr_un saddr; - mongoc_socket_t *sock; - mongoc_stream_t *stream; - mongoc_host_list_t *host; - - ENTRY; - - host = &node->host; - - memset (&saddr, 0, sizeof saddr); - saddr.sun_family = AF_UNIX; - bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host); - - sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0); - - if (sock == NULL) { - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to create socket."); - RETURN (false); - } - - if (-1 == mongoc_socket_connect ( - sock, (struct sockaddr *) &saddr, sizeof saddr, -1)) { - char buf[128]; - char *errstr; - - errstr = bson_strerror_r (mongoc_socket_errno (sock), buf, sizeof (buf)); - - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "Failed to connect to UNIX domain socket: %s", - errstr); - mongoc_socket_destroy (sock); - RETURN (false); - } - - stream = _mongoc_topology_scanner_node_setup_stream_for_tls ( - node, mongoc_stream_socket_new (sock)); - if (stream) { - _begin_ismaster_cmd (node, - stream, - false /* is_setup_done */, - NULL /* dns result */, - 0 /* delay */); - RETURN (true); - } - RETURN (false); -#endif -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_node_setup -- - * - * Create a stream and begin a non-blocking connect. - * - * Returns: - * true on success, or false and error is set. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node, - bson_error_t *error) -{ - bool success = false; - mongoc_stream_t *stream; - int64_t start; - - _mongoc_topology_scanner_monitor_heartbeat_started (node->ts, &node->host); - start = bson_get_monotonic_time (); - - /* if there is already a working stream, push it back to be re-scanned. */ - if (node->stream) { - _begin_ismaster_cmd ( - node, node->stream, true /* is_setup_done */, NULL, 0); - node->stream = NULL; - return; - } - - BSON_ASSERT (!node->retired); - - if (node->ts->initiator) { - stream = node->ts->initiator ( - node->ts->uri, &node->host, node->ts->initiator_context, error); - if (stream) { - success = true; - _begin_ismaster_cmd (node, stream, false, NULL, 0); - } - } else { - if (node->host.family == AF_UNIX) { - success = mongoc_topology_scanner_node_connect_unix (node, error); - } else { - success = mongoc_topology_scanner_node_setup_tcp (node, error); - } - } - - if (!success) { - _mongoc_topology_scanner_monitor_heartbeat_failed ( - node->ts, - &node->host, - error, - (bson_get_monotonic_time () - start) / 1000); - - node->ts->setup_err_cb (node->id, node->ts->cb_data, error); - return; - } - - node->has_auth = false; - node->timestamp = bson_get_monotonic_time (); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_node_in_cooldown -- - * - * Return true if @node has experienced a network error attempting - * to call "ismaster" less than 5 seconds before @when, a timestamp in - * microseconds. - * - * Server Discovery and Monitoring Spec: "After a single-threaded client - * gets a network error trying to check a server, the client skips - * re-checking the server until cooldownMS has passed. This avoids - * spending connectTimeoutMS on each unavailable server during each scan. - * This value MUST be 5000 ms, and it MUST NOT be configurable." - * - *-------------------------------------------------------------------------- - */ -bool -mongoc_topology_scanner_node_in_cooldown (mongoc_topology_scanner_node_t *node, - int64_t when) -{ - if (node->last_failed == -1 || node->ts->bypass_cooldown) { - return false; /* node is new, or connected */ - } - - return node->last_failed + 1000 * MONGOC_TOPOLOGY_COOLDOWN_MS >= when; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_in_cooldown -- - * - * Return true if all nodes will be in cooldown at time @when, a - * timestamp in microseconds. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_topology_scanner_in_cooldown (mongoc_topology_scanner_t *ts, - int64_t when) -{ - mongoc_topology_scanner_node_t *node; - - if (ts->bypass_cooldown) { - return false; - } - DL_FOREACH (ts->nodes, node) - { - if (!mongoc_topology_scanner_node_in_cooldown (node, when)) { - return false; - } - } - - return true; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_start -- - * - * Initializes the scanner and begins a full topology check. This - * should be called once before calling mongoc_topology_scanner_work() - * to complete the scan. - * - * The topology mutex must be held by the caller. - * - * If "obey_cooldown" is true, this is a single-threaded blocking scan - * that must obey the Server Discovery And Monitoring Spec's cooldownMS: - * - * "After a single-threaded client gets a network error trying to check - * a server, the client skips re-checking the server until cooldownMS has - * passed. - * - * "This avoids spending connectTimeoutMS on each unavailable server - * during each scan. - * - * "This value MUST be 5000 ms, and it MUST NOT be configurable." - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_topology_scanner_start (mongoc_topology_scanner_t *ts, - bool obey_cooldown) -{ - mongoc_topology_scanner_node_t *node, *tmp; - bool skip; - int64_t now; - - BSON_ASSERT (ts); - - _delete_retired_nodes (ts); - - now = bson_get_monotonic_time (); - - DL_FOREACH_SAFE (ts->nodes, node, tmp) - { - skip = - obey_cooldown && mongoc_topology_scanner_node_in_cooldown (node, now); - - if (!skip) { - mongoc_topology_scanner_node_setup (node, &node->last_error); - } - } -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_finish_scan -- - * - * Summarizes all scanner node errors into one error message, - * deletes retired nodes. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_topology_scanner_finish (mongoc_topology_scanner_t *ts) -{ - mongoc_topology_scanner_node_t *node, *tmp; - bson_error_t *error = &ts->error; - bson_string_t *msg; - - memset (&ts->error, 0, sizeof (bson_error_t)); - - msg = bson_string_new (NULL); - - DL_FOREACH_SAFE (ts->nodes, node, tmp) - { - if (node->last_error.code) { - if (msg->len) { - bson_string_append_c (msg, ' '); - } - - bson_string_append_printf (msg, "[%s]", node->last_error.message); - - /* last error domain and code win */ - error->domain = node->last_error.domain; - error->code = node->last_error.code; - } - } - - bson_strncpy ((char *) &error->message, msg->str, sizeof (error->message)); - bson_string_free (msg, true); - - _delete_retired_nodes (ts); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_work -- - * - * Crank the knob on the topology scanner state machine. This should - * be called only after mongoc_topology_scanner_start() has been used - * to begin the scan. - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts) -{ - mongoc_async_run (ts->async); - BSON_ASSERT (ts->async->ncmds == 0); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scanner_get_error -- - * - * Copy the scanner's current error; which may no-error (code 0). - * - *-------------------------------------------------------------------------- - */ - -void -mongoc_topology_scanner_get_error (mongoc_topology_scanner_t *ts, - bson_error_t *error) -{ - BSON_ASSERT (ts); - BSON_ASSERT (error); - - memcpy (error, &ts->error, sizeof (bson_error_t)); -} - -/* - * Set a field in the topology scanner. - */ -bool -_mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts, - const char *appname) -{ - if (!_mongoc_handshake_appname_is_valid (appname)) { - MONGOC_ERROR ("Cannot set appname: %s is invalid", appname); - return false; - } - - if (ts->appname != NULL) { - MONGOC_ERROR ("Cannot set appname more than once"); - return false; - } - - ts->appname = bson_strdup (appname); - return true; -} - -/* - * Set the scanner's clusterTime unconditionally: don't compare with prior - * @cluster_time is like {clusterTime: <timestamp>} - */ -void -_mongoc_topology_scanner_set_cluster_time (mongoc_topology_scanner_t *ts, - const bson_t *cluster_time) -{ - bson_destroy (&ts->cluster_time); - bson_copy_to (cluster_time, &ts->cluster_time); -} - -/* SDAM Monitoring Spec: send HeartbeatStartedEvent */ -static void -_mongoc_topology_scanner_monitor_heartbeat_started ( - const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host) -{ - if (ts->apm_callbacks.server_heartbeat_started) { - mongoc_apm_server_heartbeat_started_t event; - event.host = host; - event.context = ts->apm_context; - ts->apm_callbacks.server_heartbeat_started (&event); - } -} - -/* SDAM Monitoring Spec: send HeartbeatSucceededEvent */ -static void -_mongoc_topology_scanner_monitor_heartbeat_succeeded ( - const mongoc_topology_scanner_t *ts, - const mongoc_host_list_t *host, - const bson_t *reply, - int64_t duration_usec) -{ - if (ts->apm_callbacks.server_heartbeat_succeeded) { - mongoc_apm_server_heartbeat_succeeded_t event; - event.host = host; - event.context = ts->apm_context; - event.reply = reply; - event.duration_usec = duration_usec; - ts->apm_callbacks.server_heartbeat_succeeded (&event); - } -} - -/* SDAM Monitoring Spec: send HeartbeatFailedEvent */ -static void -_mongoc_topology_scanner_monitor_heartbeat_failed ( - const mongoc_topology_scanner_t *ts, - const mongoc_host_list_t *host, - const bson_error_t *error, - int64_t duration_usec) -{ - if (ts->apm_callbacks.server_heartbeat_failed) { - mongoc_apm_server_heartbeat_failed_t event; - event.host = host; - event.context = ts->apm_context; - event.error = error; - event.duration_usec = duration_usec; - ts->apm_callbacks.server_heartbeat_failed (&event); - } -} - -/* this is for testing the dns cache timeout. */ -void -_mongoc_topology_scanner_set_dns_cache_timeout (mongoc_topology_scanner_t *ts, - int64_t timeout_ms) -{ - ts->dns_cache_timeout_ms = timeout_ms; -} - -/* reset "retired" nodes that failed or were removed in the previous scan */ -static void -_delete_retired_nodes (mongoc_topology_scanner_t *ts) -{ - mongoc_topology_scanner_node_t *node, *tmp; - - DL_FOREACH_SAFE (ts->nodes, node, tmp) - { - if (node->retired) { - mongoc_topology_scanner_node_destroy (node, true); - } - } -} - -static void -_cancel_commands_excluding (mongoc_topology_scanner_node_t *node, - mongoc_async_cmd_t *acmd) -{ - mongoc_async_cmd_t *iter; - DL_FOREACH (node->ts->async->cmds, iter) - { - if ((mongoc_topology_scanner_node_t *) iter->data == node && - iter != acmd) { - iter->state = MONGOC_ASYNC_CMD_CANCELED_STATE; - } - } -} - -static int -_count_acmds (mongoc_topology_scanner_node_t *node) -{ - mongoc_async_cmd_t *iter; - int count = 0; - DL_FOREACH (node->ts->async->cmds, iter) - { - if ((mongoc_topology_scanner_node_t *) iter->data == node) { - ++count; - } - } - return count; -} - -static void -_jumpstart_other_acmds (mongoc_topology_scanner_node_t *node, - mongoc_async_cmd_t *acmd) -{ - mongoc_async_cmd_t *iter; - DL_FOREACH (node->ts->async->cmds, iter) - { - if ((mongoc_topology_scanner_node_t *) iter->data == node && - iter != acmd && acmd->initiate_delay_ms < iter->initiate_delay_ms) { - iter->initiate_delay_ms = - BSON_MAX (iter->initiate_delay_ms - HAPPY_EYEBALLS_DELAY_MS, 0); - } - } -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-topology.c deleted file mode 100644 index 0b365a963063c056e812e362a995bbb83a239757..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-topology.c +++ /dev/null @@ -1,1645 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-config.h" - -#include "mongoc/mongoc-handshake.h" -#include "mongoc/mongoc-handshake-private.h" - -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-topology-description-apm-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-cmd-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-trace-private.h" - -#include "mongoc/utlist.h" - -static bool -_mongoc_topology_reconcile_add_nodes (mongoc_server_description_t *sd, - mongoc_topology_t *topology) -{ - mongoc_topology_scanner_t *scanner = topology->scanner; - - /* quickly search by id, then check if a node for this host was retired in - * this scan. */ - if (!mongoc_topology_scanner_get_node (scanner, sd->id) && - !mongoc_topology_scanner_has_node_for_host (scanner, &sd->host)) { - mongoc_topology_scanner_add (scanner, &sd->host, sd->id); - mongoc_topology_scanner_scan (scanner, sd->id); - } - - return true; -} - -void -mongoc_topology_reconcile (mongoc_topology_t *topology) -{ - mongoc_topology_description_t *description; - mongoc_set_t *servers; - mongoc_server_description_t *sd; - int i; - mongoc_topology_scanner_node_t *ele, *tmp; - - description = &topology->description; - servers = description->servers; - - /* Add newly discovered nodes */ - for (i = 0; i < (int) servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (servers, i); - _mongoc_topology_reconcile_add_nodes (sd, topology); - } - - /* Remove removed nodes */ - DL_FOREACH_SAFE (topology->scanner->nodes, ele, tmp) - { - if (!mongoc_topology_description_server_by_id ( - description, ele->id, NULL)) { - mongoc_topology_scanner_node_retire (ele); - } - } -} - - -/* call this while already holding the lock */ -static bool -_mongoc_topology_update_no_lock (uint32_t id, - const bson_t *ismaster_response, - int64_t rtt_msec, - mongoc_topology_t *topology, - const bson_error_t *error /* IN */) -{ - mongoc_topology_description_handle_ismaster ( - &topology->description, id, ismaster_response, rtt_msec, error); - - /* return false if server removed from topology */ - return mongoc_topology_description_server_by_id ( - &topology->description, id, NULL) != NULL; -} - - -/* - *------------------------------------------------------------------------- - * - * _mongoc_topology_scanner_setup_err_cb -- - * - * Callback method to handle errors during topology scanner node - * setup, typically DNS or SSL errors. - * - *------------------------------------------------------------------------- - */ - -void -_mongoc_topology_scanner_setup_err_cb (uint32_t id, - void *data, - const bson_error_t *error /* IN */) -{ - mongoc_topology_t *topology; - - BSON_ASSERT (data); - - topology = (mongoc_topology_t *) data; - - mongoc_topology_description_handle_ismaster (&topology->description, - id, - NULL /* ismaster reply */, - -1 /* rtt_msec */, - error); -} - - -/* - *------------------------------------------------------------------------- - * - * _mongoc_topology_scanner_cb -- - * - * Callback method to handle ismaster responses received by async - * command objects. - * - * NOTE: This method locks the given topology's mutex. - * - *------------------------------------------------------------------------- - */ - -void -_mongoc_topology_scanner_cb (uint32_t id, - const bson_t *ismaster_response, - int64_t rtt_msec, - void *data, - const bson_error_t *error /* IN */) -{ - mongoc_topology_t *topology; - mongoc_server_description_t *sd; - - BSON_ASSERT (data); - - topology = (mongoc_topology_t *) data; - - bson_mutex_lock (&topology->mutex); - sd = mongoc_topology_description_server_by_id ( - &topology->description, id, NULL); - - /* Server Discovery and Monitoring Spec: "Once a server is connected, the - * client MUST change its type to Unknown only after it has retried the - * server once." */ - if (!ismaster_response && sd && sd->type != MONGOC_SERVER_UNKNOWN) { - _mongoc_topology_update_no_lock ( - id, ismaster_response, rtt_msec, topology, error); - - /* add another ismaster call to the current scan - the scan continues - * until all commands are done */ - mongoc_topology_scanner_scan (topology->scanner, sd->id); - } else { - _mongoc_topology_update_no_lock ( - id, ismaster_response, rtt_msec, topology, error); - - /* The processing of the ismaster results above may have added/removed - * server descriptions. We need to reconcile that with our monitoring - * agents - */ - mongoc_topology_reconcile (topology); - - mongoc_cond_broadcast (&topology->cond_client); - } - - bson_mutex_unlock (&topology->mutex); -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_new -- - * - * Creates and returns a new topology object. - * - * Returns: - * A new topology object. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ -mongoc_topology_t * -mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded) -{ - int64_t heartbeat_default; - int64_t heartbeat; - mongoc_topology_t *topology; - bool topology_valid; - mongoc_topology_description_type_t init_type; - const char *service; - char *prefixed_service; - uint32_t id; - const mongoc_host_list_t *hl; - mongoc_rr_data_t rr_data; - - BSON_ASSERT (uri); - -#ifndef MONGOC_ENABLE_CRYPTO - if (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_RETRYWRITES, MONGOC_DEFAULT_RETRYWRITES)) { - /* retryWrites requires sessions, which require crypto - just warn */ - MONGOC_WARNING ( - "retryWrites not supported without an SSL crypto library"); - } -#endif - - topology = (mongoc_topology_t *) bson_malloc0 (sizeof *topology); - topology->session_pool = NULL; - heartbeat_default = - single_threaded ? MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED - : MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED; - - heartbeat = mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_HEARTBEATFREQUENCYMS, heartbeat_default); - - mongoc_topology_description_init (&topology->description, heartbeat); - - topology->description.set_name = - bson_strdup (mongoc_uri_get_replica_set (uri)); - - topology->uri = mongoc_uri_copy (uri); - - topology->single_threaded = single_threaded; - if (single_threaded) { - /* Server Selection Spec: - * - * "Single-threaded drivers MUST provide a "serverSelectionTryOnce" - * mode, in which the driver scans the topology exactly once after - * server selection fails, then either selects a server or raises an - * error. - * - * "The serverSelectionTryOnce option MUST be true by default." - */ - topology->server_selection_try_once = mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_SERVERSELECTIONTRYONCE, true); - } else { - topology->server_selection_try_once = false; - } - - topology->server_selection_timeout_msec = mongoc_uri_get_option_as_int32 ( - topology->uri, - MONGOC_URI_SERVERSELECTIONTIMEOUTMS, - MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS); - - /* tests can override this */ - topology->min_heartbeat_frequency_msec = - MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS; - - topology->local_threshold_msec = - mongoc_uri_get_local_threshold_option (topology->uri); - - /* Total time allowed to check a server is connectTimeoutMS. - * Server Discovery And Monitoring Spec: - * - * "The socket used to check a server MUST use the same connectTimeoutMS as - * regular sockets. Multi-threaded clients SHOULD set monitoring sockets' - * socketTimeoutMS to the connectTimeoutMS." - */ - topology->connect_timeout_msec = - mongoc_uri_get_option_as_int32 (topology->uri, - MONGOC_URI_CONNECTTIMEOUTMS, - MONGOC_DEFAULT_CONNECTTIMEOUTMS); - - topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_OFF; - topology->scanner = - mongoc_topology_scanner_new (topology->uri, - _mongoc_topology_scanner_setup_err_cb, - _mongoc_topology_scanner_cb, - topology, - topology->connect_timeout_msec); - - bson_mutex_init (&topology->mutex); - mongoc_cond_init (&topology->cond_client); - mongoc_cond_init (&topology->cond_server); - - if (single_threaded) { - /* single threaded clients negotiate sasl supported mechanisms during - * a topology scan. */ - if (_mongoc_uri_requires_auth_negotiation (uri)) { - topology->scanner->negotiate_sasl_supported_mechs = true; - } - } - - topology_valid = true; - service = mongoc_uri_get_service (uri); - if (service) { - memset (&rr_data, 0, sizeof (mongoc_rr_data_t)); - - /* a mongodb+srv URI. try SRV lookup, if no error then also try TXT */ - prefixed_service = bson_strdup_printf ("_mongodb._tcp.%s", service); - if (!_mongoc_client_get_rr (prefixed_service, - MONGOC_RR_SRV, - topology->uri, - &rr_data, - &topology->scanner->error) || - !_mongoc_client_get_rr (service, - MONGOC_RR_TXT, - topology->uri, - NULL, - &topology->scanner->error)) { - topology_valid = false; - } else { - topology->last_srv_scan = bson_get_monotonic_time (); - topology->rescanSRVIntervalMS = BSON_MAX ( - rr_data.min_ttl * 1000, MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS); - } - - bson_free (prefixed_service); - } - - /* - * Set topology type from URI: - * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY - * - otherwise, if the seed list has a single host, initialize to SINGLE - * - everything else gets initialized to UNKNOWN - */ - hl = mongoc_uri_get_hosts (topology->uri); - if (mongoc_uri_get_replica_set (topology->uri)) { - init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY; - } else { - if (hl && hl->next) { - init_type = MONGOC_TOPOLOGY_UNKNOWN; - } else { - init_type = MONGOC_TOPOLOGY_SINGLE; - } - } - - topology->description.type = init_type; - - if (!topology_valid) { - /* add no nodes */ - return topology; - } - - while (hl) { - mongoc_topology_description_add_server ( - &topology->description, hl->host_and_port, &id); - mongoc_topology_scanner_add (topology->scanner, hl, id); - - hl = hl->next; - } - - return topology; -} -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_set_apm_callbacks -- - * - * Set Application Performance Monitoring callbacks. - * - *------------------------------------------------------------------------- - */ -void -mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology, - mongoc_apm_callbacks_t *callbacks, - void *context) -{ - if (callbacks) { - memcpy (&topology->description.apm_callbacks, - callbacks, - sizeof (mongoc_apm_callbacks_t)); - memcpy (&topology->scanner->apm_callbacks, - callbacks, - sizeof (mongoc_apm_callbacks_t)); - } else { - memset (&topology->description.apm_callbacks, - 0, - sizeof (mongoc_apm_callbacks_t)); - memset ( - &topology->scanner->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t)); - } - - topology->description.apm_context = context; - topology->scanner->apm_context = context; -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_destroy -- - * - * Free the memory associated with this topology object. - * - * Returns: - * None. - * - * Side effects: - * @topology will be cleaned up. - * - *------------------------------------------------------------------------- - */ -void -mongoc_topology_destroy (mongoc_topology_t *topology) -{ - if (!topology) { - return; - } - - _mongoc_topology_background_thread_stop (topology); - _mongoc_topology_description_monitor_closed (&topology->description); - - mongoc_uri_destroy (topology->uri); - mongoc_topology_description_destroy (&topology->description); - mongoc_topology_scanner_destroy (topology->scanner); - - /* If we are single-threaded, the client will try to call - _mongoc_topology_end_sessions_cmd when it dies. This removes - sessions from the pool as it calls endSessions on them. In - case this does not succeed, we clear the pool again here. */ - _mongoc_topology_clear_session_pool (topology); - - mongoc_cond_destroy (&topology->cond_client); - mongoc_cond_destroy (&topology->cond_server); - bson_mutex_destroy (&topology->mutex); - - bson_free (topology); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_clear_session_pool -- - * - * Clears the pool of server sessions without sending endSessions. - * - * Returns: - * Nothing. - * - * Side effects: - * Server session pool will be emptied. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_topology_clear_session_pool (mongoc_topology_t *topology) -{ - mongoc_server_session_t *ss, *tmp1, *tmp2; - - CDL_FOREACH_SAFE (topology->session_pool, ss, tmp1, tmp2) - { - _mongoc_server_session_destroy (ss); - } -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_rescan_srv -- - * - * Queries SRV records for new hosts in a mongos cluster. - * - * NOTE: this method expects @topology's mutex to be locked on entry. - * - * -------------------------------------------------------------------------- - */ -static void -mongoc_topology_rescan_srv (mongoc_topology_t *topology) -{ - mongoc_rr_data_t rr_data = {0}; - mongoc_host_list_t *h = NULL; - const char *service; - char *prefixed_service = NULL; - int64_t scan_time; - - if ((topology->description.type != MONGOC_TOPOLOGY_SHARDED) && - (topology->description.type != MONGOC_TOPOLOGY_UNKNOWN)) { - /* Only perform rescan for sharded topology. */ - return; - } - - service = mongoc_uri_get_service (topology->uri); - if (!service) { - /* Only rescan if we have a mongodb+srv:// URI. */ - return; - } - - scan_time = topology->last_srv_scan + (topology->rescanSRVIntervalMS * 1000); - if (bson_get_monotonic_time () < scan_time) { - /* Query SRV no more frequently than rescanSRVIntervalMS. */ - return; - } - - /* Go forth and query... */ - rr_data.hosts = - _mongoc_host_list_copy (mongoc_uri_get_hosts (topology->uri), NULL); - - prefixed_service = bson_strdup_printf ("_mongodb._tcp.%s", service); - if (!_mongoc_client_get_rr (prefixed_service, - MONGOC_RR_SRV, - topology->uri, - &rr_data, - &topology->scanner->error)) { - /* Failed querying, soldier on and try again next time. */ - topology->rescanSRVIntervalMS = topology->description.heartbeat_msec; - GOTO (done); - } - - topology->last_srv_scan = bson_get_monotonic_time (); - topology->rescanSRVIntervalMS = BSON_MAX ( - rr_data.min_ttl * 1000, MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS); - - if (rr_data.count == 0) { - /* Special case when DNS returns zero records successfully. - * Leave the toplogy alone and perform another scan at the next interval - * rather than removing all records and having nothing to connect to. - * For no verified hosts drivers "MUST temporarily set rescanSRVIntervalMS - * to heartbeatFrequencyMS until at least one verified SRV record is - * obtained." - */ - topology->rescanSRVIntervalMS = topology->description.heartbeat_msec; - GOTO (done); - } - - /* rr_data.hosts was initialized to the current set of known hosts - * on entry, and mongoc_client_get_rr will have stripped it down to - * only include hosts which were NOT included in the most recent query. - * Remove those hosts and we're left with only active servers. - */ - for (h = rr_data.hosts; h; h = rr_data.hosts) { - rr_data.hosts = h->next; - mongoc_uri_remove_host (topology->uri, h->host, h->port); - bson_free (h); - } - -done: - bson_free (prefixed_service); - _mongoc_host_list_destroy_all (rr_data.hosts); -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_scan_once -- - * - * Runs a single complete scan. - * - * NOTE: this method expects @topology's mutex to be locked on entry. - * - * NOTE: this method unlocks and re-locks @topology's mutex. - * - *-------------------------------------------------------------------------- - */ -static void -mongoc_topology_scan_once (mongoc_topology_t *topology, bool obey_cooldown) -{ - /* Prior to scanning hosts, update the list of SRV hosts, if applicable. */ - mongoc_topology_rescan_srv (topology); - - /* since the last scan, members may be added or removed from the topology - * description based on ismaster responses in connection handshakes, see - * _mongoc_topology_update_from_handshake. retire scanner nodes for removed - * members and create scanner nodes for new ones. */ - mongoc_topology_reconcile (topology); - mongoc_topology_scanner_start (topology->scanner, obey_cooldown); - - /* scanning locks and unlocks the mutex itself until the scan is done */ - bson_mutex_unlock (&topology->mutex); - mongoc_topology_scanner_work (topology->scanner); - - bson_mutex_lock (&topology->mutex); - - _mongoc_topology_scanner_finish (topology->scanner); - - topology->last_scan = bson_get_monotonic_time (); - topology->stale = false; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_do_blocking_scan -- - * - * Monitoring entry for single-threaded use case. Assumes the caller - * has checked that it's the right time to scan. - * - *-------------------------------------------------------------------------- - */ -void -_mongoc_topology_do_blocking_scan (mongoc_topology_t *topology, - bson_error_t *error) -{ - topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_SINGLE_THREADED; - - _mongoc_handshake_freeze (); - - bson_mutex_lock (&topology->mutex); - mongoc_topology_scan_once (topology, true /* obey cooldown */); - bson_mutex_unlock (&topology->mutex); - mongoc_topology_scanner_get_error (topology->scanner, error); -} - - -bool -mongoc_topology_compatible (const mongoc_topology_description_t *td, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) -{ - int64_t max_staleness_seconds; - int32_t max_wire_version; - - if (td->compatibility_error.code) { - if (error) { - memcpy (error, &td->compatibility_error, sizeof (bson_error_t)); - } - return false; - } - - if (!read_prefs) { - /* NULL means read preference Primary */ - return true; - } - - max_staleness_seconds = - mongoc_read_prefs_get_max_staleness_seconds (read_prefs); - - if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { - max_wire_version = - mongoc_topology_description_lowest_max_wire_version (td); - - if (max_wire_version < WIRE_VERSION_MAX_STALENESS) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "Not all servers support maxStalenessSeconds"); - return false; - } - - /* shouldn't happen if we've properly enforced wire version */ - if (!mongoc_topology_description_all_sds_have_write_date (td)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "Not all servers have lastWriteDate"); - return false; - } - - if (!_mongoc_topology_description_validate_max_staleness ( - td, max_staleness_seconds, error)) { - return false; - } - } - - return true; -} - - -static void -_mongoc_server_selection_error (const char *msg, - const bson_error_t *scanner_error, - bson_error_t *error) -{ - if (scanner_error && scanner_error->code) { - bson_set_error (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "%s: %s", - msg, - scanner_error->message); - } else { - bson_set_error (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "%s", - msg); - } -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_select -- - * - * Selects a server description for an operation based on @optype - * and @read_prefs. - * - * NOTE: this method returns a copy of the original server - * description. Callers must own and clean up this copy. - * - * NOTE: this method locks and unlocks @topology's mutex. - * - * Parameters: - * @topology: The topology. - * @optype: Whether we are selecting for a read or write operation. - * @read_prefs: Required, the read preferences for the command. - * @error: Required, out pointer for error info. - * - * Returns: - * A mongoc_server_description_t, or NULL on failure, in which case - * @error will be set. - * - * Side effects: - * @error may be set. - * - *------------------------------------------------------------------------- - */ -mongoc_server_description_t * -mongoc_topology_select (mongoc_topology_t *topology, - mongoc_ss_optype_t optype, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) -{ - uint32_t server_id = - mongoc_topology_select_server_id (topology, optype, read_prefs, error); - - if (server_id) { - /* new copy of the server description */ - return mongoc_topology_server_by_id (topology, server_id, error); - } else { - return NULL; - } -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_select_server_id -- - * - * Alternative to mongoc_topology_select when you only need the id. - * - * Returns: - * A server id, or 0 on failure, in which case @error will be set. - * - *------------------------------------------------------------------------- - */ -uint32_t -mongoc_topology_select_server_id (mongoc_topology_t *topology, - mongoc_ss_optype_t optype, - const mongoc_read_prefs_t *read_prefs, - bson_error_t *error) -{ - static const char *timeout_msg = - "No suitable servers found: `serverSelectionTimeoutMS` expired"; - - mongoc_topology_scanner_t *ts; - int r; - int64_t local_threshold_ms; - mongoc_server_description_t *selected_server = NULL; - bool try_once; - int64_t sleep_usec; - bool tried_once; - bson_error_t scanner_error = {0}; - int64_t heartbeat_msec; - uint32_t server_id; - - /* These names come from the Server Selection Spec pseudocode */ - int64_t loop_start; /* when we entered this function */ - int64_t loop_end; /* when we last completed a loop (single-threaded) */ - int64_t scan_ready; /* the soonest we can do a blocking scan */ - int64_t next_update; /* the latest we must do a blocking scan */ - int64_t expire_at; /* when server selection timeout expires */ - - BSON_ASSERT (topology); - ts = topology->scanner; - - bson_mutex_lock (&topology->mutex); - /* It isn't strictly necessary to lock here, because if the topology - * is invalid, it will never become valid. Lock anyway for consistency. */ - if (!mongoc_topology_scanner_valid (ts)) { - if (error) { - mongoc_topology_scanner_get_error (ts, error); - error->domain = MONGOC_ERROR_SERVER_SELECTION; - error->code = MONGOC_ERROR_SERVER_SELECTION_FAILURE; - } - bson_mutex_unlock (&topology->mutex); - return 0; - } - bson_mutex_unlock (&topology->mutex); - - heartbeat_msec = topology->description.heartbeat_msec; - local_threshold_ms = topology->local_threshold_msec; - try_once = topology->server_selection_try_once; - loop_start = loop_end = bson_get_monotonic_time (); - expire_at = - loop_start + ((int64_t) topology->server_selection_timeout_msec * 1000); - - if (topology->single_threaded) { - _mongoc_topology_description_monitor_opening (&topology->description); - - tried_once = false; - next_update = topology->last_scan + heartbeat_msec * 1000; - if (next_update < loop_start) { - /* we must scan now */ - topology->stale = true; - } - - /* until we find a server or time out */ - for (;;) { - if (topology->stale) { - /* how soon are we allowed to scan? */ - scan_ready = topology->last_scan + - topology->min_heartbeat_frequency_msec * 1000; - - if (scan_ready > expire_at && !try_once) { - /* selection timeout will expire before min heartbeat passes */ - _mongoc_server_selection_error ( - "No suitable servers found: " - "`serverselectiontimeoutms` timed out", - &scanner_error, - error); - - return 0; - } - - sleep_usec = scan_ready - loop_end; - if (sleep_usec > 0) { - if (try_once && - mongoc_topology_scanner_in_cooldown (ts, scan_ready)) { - _mongoc_server_selection_error ( - "No servers yet eligible for rescan", - &scanner_error, - error); - - return 0; - } - - _mongoc_usleep (sleep_usec); - } - - /* takes up to connectTimeoutMS. sets "last_scan", clears "stale" */ - _mongoc_topology_do_blocking_scan (topology, &scanner_error); - loop_end = topology->last_scan; - tried_once = true; - } - - if (!mongoc_topology_compatible ( - &topology->description, read_prefs, error)) { - return 0; - } - - selected_server = mongoc_topology_description_select ( - &topology->description, optype, read_prefs, local_threshold_ms); - - if (selected_server) { - return selected_server->id; - } - - topology->stale = true; - - if (try_once) { - if (tried_once) { - _mongoc_server_selection_error ( - "No suitable servers found (`serverSelectionTryOnce` set)", - &scanner_error, - error); - - return 0; - } - } else { - loop_end = bson_get_monotonic_time (); - - if (loop_end > expire_at) { - /* no time left in server_selection_timeout_msec */ - _mongoc_server_selection_error ( - timeout_msg, &scanner_error, error); - - return 0; - } - } - } - } - - /* With background thread */ - /* we break out when we've found a server or timed out */ - for (;;) { - bson_mutex_lock (&topology->mutex); - - if (!mongoc_topology_compatible ( - &topology->description, read_prefs, error)) { - bson_mutex_unlock (&topology->mutex); - return 0; - } - - selected_server = mongoc_topology_description_select ( - &topology->description, optype, read_prefs, local_threshold_ms); - - if (!selected_server) { - _mongoc_topology_request_scan (topology); - - r = mongoc_cond_timedwait (&topology->cond_client, - &topology->mutex, - (expire_at - loop_start) / 1000); - - mongoc_topology_scanner_get_error (ts, &scanner_error); - bson_mutex_unlock (&topology->mutex); - -#ifdef _WIN32 - if (r == WSAETIMEDOUT) { -#else - if (r == ETIMEDOUT) { -#endif - /* handle timeouts */ - _mongoc_server_selection_error (timeout_msg, &scanner_error, error); - - return 0; - } else if (r) { - bson_set_error (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "Unknown error '%d' received while waiting on " - "thread condition", - r); - return 0; - } - - loop_start = bson_get_monotonic_time (); - - if (loop_start > expire_at) { - _mongoc_server_selection_error (timeout_msg, &scanner_error, error); - - return 0; - } - } else { - server_id = selected_server->id; - bson_mutex_unlock (&topology->mutex); - return server_id; - } - } -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_server_by_id -- - * - * Get the server description for @id, if that server is present - * in @description. Otherwise, return NULL and fill out the optional - * @error. - * - * NOTE: this method returns a copy of the original server - * description. Callers must own and clean up this copy. - * - * NOTE: this method locks and unlocks @topology's mutex. - * - * Returns: - * A mongoc_server_description_t, or NULL. - * - * Side effects: - * Fills out optional @error if server not found. - * - *------------------------------------------------------------------------- - */ - -mongoc_server_description_t * -mongoc_topology_server_by_id (mongoc_topology_t *topology, - uint32_t id, - bson_error_t *error) -{ - mongoc_server_description_t *sd; - - bson_mutex_lock (&topology->mutex); - - sd = mongoc_server_description_new_copy ( - mongoc_topology_description_server_by_id ( - &topology->description, id, error)); - - bson_mutex_unlock (&topology->mutex); - - return sd; -} - -/* - *------------------------------------------------------------------------- - * - * mongoc_topology_host_by_id -- - * - * Copy the mongoc_host_list_t for @id, if that server is present - * in @description. Otherwise, return NULL and fill out the optional - * @error. - * - * NOTE: this method returns a copy of the original mongoc_host_list_t. - * Callers must own and clean up this copy. - * - * NOTE: this method locks and unlocks @topology's mutex. - * - * Returns: - * A mongoc_host_list_t, or NULL. - * - * Side effects: - * Fills out optional @error if server not found. - * - *------------------------------------------------------------------------- - */ - -mongoc_host_list_t * -_mongoc_topology_host_by_id (mongoc_topology_t *topology, - uint32_t id, - bson_error_t *error) -{ - mongoc_server_description_t *sd; - mongoc_host_list_t *host = NULL; - - bson_mutex_lock (&topology->mutex); - - /* not a copy - direct pointer into topology description data */ - sd = mongoc_topology_description_server_by_id ( - &topology->description, id, error); - - if (sd) { - host = bson_malloc0 (sizeof (mongoc_host_list_t)); - memcpy (host, &sd->host, sizeof (mongoc_host_list_t)); - } - - bson_mutex_unlock (&topology->mutex); - - return host; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_request_scan -- - * - * Non-locking variant - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_topology_request_scan (mongoc_topology_t *topology) -{ - topology->scan_requested = true; - - mongoc_cond_signal (&topology->cond_server); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_invalidate_server -- - * - * Invalidate the given server after receiving a network error in - * another part of the client. - * - * NOTE: this method uses @topology's mutex. - * - *-------------------------------------------------------------------------- - */ -void -mongoc_topology_invalidate_server (mongoc_topology_t *topology, - uint32_t id, - const bson_error_t *error) -{ - BSON_ASSERT (error); - - bson_mutex_lock (&topology->mutex); - mongoc_topology_description_invalidate_server ( - &topology->description, id, error); - bson_mutex_unlock (&topology->mutex); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_update_from_handshake -- - * - * A client opens a new connection and calls ismaster on it when it - * detects a closed connection in _mongoc_cluster_check_interval, or if - * mongoc_client_pool_pop creates a new client. Update the topology - * description from the ismaster response. - * - * NOTE: this method uses @topology's mutex. - * - * Returns: - * false if the server was removed from the topology - *-------------------------------------------------------------------------- - */ -bool -_mongoc_topology_update_from_handshake (mongoc_topology_t *topology, - const mongoc_server_description_t *sd) -{ - bool has_server; - - BSON_ASSERT (topology); - BSON_ASSERT (sd); - - bson_mutex_lock (&topology->mutex); - - /* return false if server was removed from topology */ - has_server = _mongoc_topology_update_no_lock ( - sd->id, &sd->last_is_master, sd->round_trip_time_msec, topology, NULL); - - /* if pooled, wake threads waiting in mongoc_topology_server_by_id */ - mongoc_cond_broadcast (&topology->cond_client); - bson_mutex_unlock (&topology->mutex); - - return has_server; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_update_last_used -- - * - * Internal function. In single-threaded mode only, track when the socket - * to a particular server was last used. This is required for - * mongoc_cluster_check_interval to know when a socket has been idle. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_topology_update_last_used (mongoc_topology_t *topology, - uint32_t server_id) -{ - mongoc_topology_scanner_node_t *node; - - if (!topology->single_threaded) { - return; - } - - node = mongoc_topology_scanner_get_node (topology->scanner, server_id); - if (node) { - node->last_used = bson_get_monotonic_time (); - } -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_server_timestamp -- - * - * Return the topology's scanner's timestamp for the given server, - * or -1 if there is no scanner node for the given server. - * - * NOTE: this method uses @topology's mutex. - * - * Returns: - * Timestamp, or -1 - * - *-------------------------------------------------------------------------- - */ -int64_t -mongoc_topology_server_timestamp (mongoc_topology_t *topology, uint32_t id) -{ - mongoc_topology_scanner_node_t *node; - int64_t timestamp = -1; - - bson_mutex_lock (&topology->mutex); - - node = mongoc_topology_scanner_get_node (topology->scanner, id); - if (node) { - timestamp = node->timestamp; - } - - bson_mutex_unlock (&topology->mutex); - - return timestamp; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_get_type -- - * - * Return the topology's description's type. - * - * NOTE: this method uses @topology's mutex. - * - * Returns: - * The topology description type. - * - *-------------------------------------------------------------------------- - */ -mongoc_topology_description_type_t -_mongoc_topology_get_type (mongoc_topology_t *topology) -{ - mongoc_topology_description_type_t td_type; - - bson_mutex_lock (&topology->mutex); - - td_type = topology->description.type; - - bson_mutex_unlock (&topology->mutex); - - return td_type; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_run_background -- - * - * The background topology monitoring thread runs in this loop. - * - * NOTE: this method uses @topology's mutex. - * - *-------------------------------------------------------------------------- - */ -static void * -_mongoc_topology_run_background (void *data) -{ - mongoc_topology_t *topology; - int64_t now; - int64_t last_scan; - int64_t timeout; - int64_t force_timeout; - int64_t heartbeat_msec; - int r; - - BSON_ASSERT (data); - - last_scan = 0; - topology = (mongoc_topology_t *) data; - heartbeat_msec = topology->description.heartbeat_msec; - - /* we exit this loop when shutting down, or on error */ - for (;;) { - /* unlocked after starting a scan or after breaking out of the loop */ - bson_mutex_lock (&topology->mutex); - if (!mongoc_topology_scanner_valid (topology->scanner)) { - bson_mutex_unlock (&topology->mutex); - goto DONE; - } - - /* we exit this loop on error, or when we should scan immediately */ - for (;;) { - if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN) { - bson_mutex_unlock (&topology->mutex); - goto DONE; - } - - now = bson_get_monotonic_time (); - - if (last_scan == 0) { - /* set up the "last scan" as exactly long enough to force an - * immediate scan on the first pass */ - last_scan = now - (heartbeat_msec * 1000); - } - - timeout = heartbeat_msec - ((now - last_scan) / 1000); - - /* if someone's specifically asked for a scan, use a shorter interval - */ - if (topology->scan_requested) { - force_timeout = topology->min_heartbeat_frequency_msec - - ((now - last_scan) / 1000); - - timeout = BSON_MIN (timeout, force_timeout); - } - - /* if we can start scanning, do so immediately */ - if (timeout <= 0) { - break; - } else { - /* otherwise wait until someone: - * o requests a scan - * o we time out - * o requests a shutdown - */ - r = mongoc_cond_timedwait ( - &topology->cond_server, &topology->mutex, timeout); - -#ifdef _WIN32 - if (!(r == 0 || r == WSAETIMEDOUT)) { -#else - if (!(r == 0 || r == ETIMEDOUT)) { -#endif - bson_mutex_unlock (&topology->mutex); - /* handle errors */ - goto DONE; - } - - /* if we timed out, or were woken up, check if it's time to scan - * again, or bail out */ - } - } - - topology->scan_requested = false; - mongoc_topology_scan_once (topology, false /* obey cooldown */); - bson_mutex_unlock (&topology->mutex); - - last_scan = bson_get_monotonic_time (); - } - -DONE: - return NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_start_background_scanner - * - * Start the topology background thread running. This should only be - * called once per pool. If clients are created separately (not - * through a pool) the SDAM logic will not be run in a background - * thread. Returns whether or not the scanner is running on termination - * of the function. - * - * NOTE: this method uses @topology's mutex. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_topology_start_background_scanner (mongoc_topology_t *topology) -{ - int r; - - if (topology->single_threaded) { - return false; - } - - bson_mutex_lock (&topology->mutex); - - if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) { - bson_mutex_unlock (&topology->mutex); - return true; - } - - BSON_ASSERT (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF); - - topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_BG_RUNNING; - - _mongoc_handshake_freeze (); - _mongoc_topology_description_monitor_opening (&topology->description); - - r = bson_thread_create ( - &topology->thread, _mongoc_topology_run_background, topology); - - if (r != 0) { - MONGOC_ERROR ("could not start topology scanner thread: %s", - strerror (r)); - abort (); - } - - bson_mutex_unlock (&topology->mutex); - - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_topology_background_thread_stop -- - * - * Stop the topology background thread. Called by the owning pool at - * its destruction. - * - * NOTE: this method uses @topology's mutex. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_topology_background_thread_stop (mongoc_topology_t *topology) -{ - bool join_thread = false; - - if (topology->single_threaded) { - return; - } - - bson_mutex_lock (&topology->mutex); - - BSON_ASSERT (topology->scanner_state != - MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN); - - if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) { - /* if the background thread is running, request a shutdown and signal the - * thread */ - topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN; - mongoc_cond_signal (&topology->cond_server); - join_thread = true; - } else { - /* nothing to do if it's already off */ - } - - bson_mutex_unlock (&topology->mutex); - - if (join_thread) { - /* if we're joining the thread, wait for it to come back and broadcast - * all listeners */ - bson_thread_join (topology->thread); - - bson_mutex_lock (&topology->mutex); - topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_OFF; - bson_mutex_unlock (&topology->mutex); - - mongoc_cond_broadcast (&topology->cond_client); - } -} - -bool -_mongoc_topology_set_appname (mongoc_topology_t *topology, const char *appname) -{ - bool ret = false; - bson_mutex_lock (&topology->mutex); - - if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF) { - ret = _mongoc_topology_scanner_set_appname (topology->scanner, appname); - } else { - MONGOC_ERROR ("Cannot set appname after handshake initiated"); - } - bson_mutex_unlock (&topology->mutex); - return ret; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_update_cluster_time -- - * - * Internal function. If the server reply has a later $clusterTime than - * any seen before, update the topology's clusterTime. See the Driver - * Sessions Spec. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_topology_update_cluster_time (mongoc_topology_t *topology, - const bson_t *reply) -{ - bson_mutex_lock (&topology->mutex); - mongoc_topology_description_update_cluster_time (&topology->description, - reply); - _mongoc_topology_scanner_set_cluster_time ( - topology->scanner, &topology->description.cluster_time); - bson_mutex_unlock (&topology->mutex); -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_pop_server_session -- - * - * Internal function. Get a server session from the pool or create - * one. On error, return NULL and fill out @error. - * - *-------------------------------------------------------------------------- - */ - -mongoc_server_session_t * -_mongoc_topology_pop_server_session (mongoc_topology_t *topology, - bson_error_t *error) -{ - int64_t timeout; - mongoc_server_session_t *ss = NULL; - mongoc_topology_description_t *td; - - ENTRY; - - bson_mutex_lock (&topology->mutex); - - td = &topology->description; - timeout = td->session_timeout_minutes; - - if (timeout == MONGOC_NO_SESSIONS) { - /* if needed, connect and check for session timeout again */ - if (!mongoc_topology_description_has_data_node (td)) { - bson_mutex_unlock (&topology->mutex); - if (!mongoc_topology_select_server_id ( - topology, MONGOC_SS_READ, NULL, error)) { - RETURN (NULL); - } - - bson_mutex_lock (&topology->mutex); - timeout = td->session_timeout_minutes; - } - - if (timeout == MONGOC_NO_SESSIONS) { - bson_mutex_unlock (&topology->mutex); - bson_set_error (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_SESSION_FAILURE, - "Server does not support sessions"); - RETURN (NULL); - } - } - - while (topology->session_pool) { - ss = topology->session_pool; - CDL_DELETE (topology->session_pool, ss); - if (_mongoc_server_session_timed_out (ss, timeout)) { - _mongoc_server_session_destroy (ss); - ss = NULL; - } else { - break; - } - } - - bson_mutex_unlock (&topology->mutex); - - if (!ss) { - ss = _mongoc_server_session_new (error); - } - - RETURN (ss); -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_push_server_session -- - * - * Internal function. Return a server session to the pool. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_topology_push_server_session (mongoc_topology_t *topology, - mongoc_server_session_t *server_session) -{ - int64_t timeout; - mongoc_server_session_t *ss; - - ENTRY; - - bson_mutex_lock (&topology->mutex); - - timeout = topology->description.session_timeout_minutes; - - /* start at back of queue and reap timed-out sessions */ - while (topology->session_pool && topology->session_pool->prev) { - ss = topology->session_pool->prev; - if (_mongoc_server_session_timed_out (ss, timeout)) { - BSON_ASSERT (ss->next); /* silences clang scan-build */ - CDL_DELETE (topology->session_pool, ss); - _mongoc_server_session_destroy (ss); - } else { - /* if ss is not timed out, sessions in front of it are ok too */ - break; - } - } - - if (_mongoc_server_session_timed_out (server_session, timeout)) { - _mongoc_server_session_destroy (server_session); - } else { - /* silences clang scan-build */ - BSON_ASSERT (!topology->session_pool || (topology->session_pool->next && - topology->session_pool->prev)); - CDL_PREPEND (topology->session_pool, server_session); - } - - bson_mutex_unlock (&topology->mutex); - - EXIT; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_end_sessions_cmd -- - * - * Internal function. End up to 10,000 server sessions. @cmd is an - * uninitialized document. Sessions are destroyed as their ids are - * appended to @cmd. - * - * Driver Sessions Spec: "If the number of sessions is very large the - * endSessions command SHOULD be run multiple times to end 10,000 - * sessions at a time (in order to avoid creating excessively large - * commands)." - * - * Returns: - * true if any session ids were appended to @cmd. - * - *-------------------------------------------------------------------------- - */ - -bool -_mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd) -{ - mongoc_server_session_t *ss, *tmp1, *tmp2; - char buf[16]; - const char *key; - uint32_t i; - bson_t ar; - - bson_init (cmd); - BSON_APPEND_ARRAY_BEGIN (cmd, "endSessions", &ar); - - i = 0; - CDL_FOREACH_SAFE (topology->session_pool, ss, tmp1, tmp2) - { - bson_uint32_to_string (i, &key, buf, sizeof buf); - BSON_APPEND_DOCUMENT (&ar, key, &ss->lsid); - CDL_DELETE (topology->session_pool, ss); - _mongoc_server_session_destroy (ss); - - if (++i == 10000) { - break; - } - } - - bson_append_array_end (cmd, &ar); - - return i > 0; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_topology_get_ismaster -- - * - * Locks topology->mutex and retrieves (possibly constructing) the - * handshake on the topology scanner. - * - * Returns: - * A bson_t representing an ismaster command. - * - *-------------------------------------------------------------------------- - */ -const bson_t * -_mongoc_topology_get_ismaster (mongoc_topology_t *topology) -{ - const bson_t *cmd; - bson_mutex_lock (&topology->mutex); - cmd = _mongoc_topology_scanner_get_ismaster (topology->scanner); - bson_mutex_unlock (&topology->mutex); - return cmd; -} - -void -_mongoc_topology_bypass_cooldown (mongoc_topology_t *topology) -{ - BSON_ASSERT (topology->single_threaded); - topology->scanner->bypass_cooldown = true; -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-trace-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-trace-private.h deleted file mode 100644 index 61b788b6c0f5ff0b4dae2963dc0476e96396d758..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-trace-private.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_TRACE_PRIVATE_H -#define MONGOC_TRACE_PRIVATE_H - - -#include <bson/bson.h> -#include <ctype.h> - -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-log-private.h" - - -BSON_BEGIN_DECLS - - -#ifdef MONGOC_TRACE -#define TRACE(msg, ...) \ - do { \ - mongoc_log (MONGOC_LOG_LEVEL_TRACE, \ - MONGOC_LOG_DOMAIN, \ - "TRACE: %s():%d " msg, \ - BSON_FUNC, \ - __LINE__, \ - __VA_ARGS__); \ - } while (0) -#define ENTRY \ - do { \ - mongoc_log (MONGOC_LOG_LEVEL_TRACE, \ - MONGOC_LOG_DOMAIN, \ - "ENTRY: %s():%d", \ - BSON_FUNC, \ - __LINE__); \ - } while (0) -#define EXIT \ - do { \ - mongoc_log (MONGOC_LOG_LEVEL_TRACE, \ - MONGOC_LOG_DOMAIN, \ - " EXIT: %s():%d", \ - BSON_FUNC, \ - __LINE__); \ - return; \ - } while (0) -#define RETURN(ret) \ - do { \ - mongoc_log (MONGOC_LOG_LEVEL_TRACE, \ - MONGOC_LOG_DOMAIN, \ - " EXIT: %s():%d", \ - BSON_FUNC, \ - __LINE__); \ - return ret; \ - } while (0) -#define GOTO(label) \ - do { \ - mongoc_log (MONGOC_LOG_LEVEL_TRACE, \ - MONGOC_LOG_DOMAIN, \ - " GOTO: %s():%d %s", \ - BSON_FUNC, \ - __LINE__, \ - #label); \ - goto label; \ - } while (0) -#define DUMP_BYTES(_n, _b, _l) \ - do { \ - mongoc_log (MONGOC_LOG_LEVEL_TRACE, \ - MONGOC_LOG_DOMAIN, \ - "TRACE: %s():%d %s = %p [%d]", \ - BSON_FUNC, \ - __LINE__, \ - #_n, \ - _b, \ - (int) _l); \ - mongoc_log_trace_bytes (MONGOC_LOG_DOMAIN, _b, _l); \ - } while (0) -#define DUMP_IOVEC(_n, _iov, _iovcnt) \ - do { \ - mongoc_log (MONGOC_LOG_LEVEL_TRACE, \ - MONGOC_LOG_DOMAIN, \ - "TRACE: %s():%d %s = %p [%d]", \ - BSON_FUNC, \ - __LINE__, \ - #_n, \ - _iov, \ - (int) _iovcnt); \ - mongoc_log_trace_iovec (MONGOC_LOG_DOMAIN, _iov, _iovcnt); \ - } while (0) -#else -#define TRACE(msg, ...) -#define ENTRY -#define EXIT return -#define RETURN(ret) return ret -#define GOTO(label) goto label -#define DUMP_BYTES(_n, _b, _l) -#define DUMP_IOVEC(_n, _iov, _iovcnt) -#endif - - -BSON_END_DECLS - - -#endif /* MONGOC_TRACE_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-uri-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-uri-private.h deleted file mode 100644 index 7fe6ef5f2c337d4f13e24983e6959b5f12d77453..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-uri-private.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_URI_PRIVATE_H -#define MONGOC_URI_PRIVATE_H - -#include "mongoc/mongoc-uri.h" - - -BSON_BEGIN_DECLS - - -bool -mongoc_uri_upsert_host_and_port (mongoc_uri_t *uri, - const char *host_and_port, - bson_error_t *error); -bool -mongoc_uri_upsert_host (mongoc_uri_t *uri, - const char *host, - uint16_t port, - bson_error_t *error); -void -mongoc_uri_remove_host (mongoc_uri_t *uri, const char *host, uint16_t port); - -bool -mongoc_uri_parse_host (mongoc_uri_t *uri, const char *str); -bool -mongoc_uri_parse_options (mongoc_uri_t *uri, - const char *str, - bool from_dns, - bson_error_t *error); -int32_t -mongoc_uri_get_local_threshold_option (const mongoc_uri_t *uri); - -bool -_mongoc_uri_requires_auth_negotiation (const mongoc_uri_t *uri); - -const char * -mongoc_uri_canonicalize_option (const char *key); - -mongoc_uri_t * -_mongoc_uri_copy_and_replace_host_list (const mongoc_uri_t *original, - const char *host); - -BSON_END_DECLS - - -#endif /* MONGOC_URI_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-uri.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-uri.c deleted file mode 100644 index 02bdbee844d6b0989bd0a38112e718c6823c04f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-uri.c +++ /dev/null @@ -1,2917 +0,0 @@ -/* - * Copyright 2013 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 <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <math.h> - -/* strcasecmp on windows */ -#include "mongoc/mongoc-util-private.h" - -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-host-list.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-handshake-private.h" -#include "mongoc/mongoc-socket.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-compression-private.h" -#include "mongoc/utlist.h" - -struct _mongoc_uri_t { - char *str; - bool is_srv; - char srv[BSON_HOST_NAME_MAX + 1]; - mongoc_host_list_t *hosts; - char *username; - char *password; - char *database; - bson_t raw; /* Unparsed options, see mongoc_uri_parse_options */ - bson_t options; /* Type-coerced and canonicalized options */ - bson_t credentials; - bson_t compressors; - mongoc_read_prefs_t *read_prefs; - mongoc_read_concern_t *read_concern; - mongoc_write_concern_t *write_concern; -}; - -#define MONGOC_URI_ERROR(error, format, ...) \ - bson_set_error (error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - format, \ - __VA_ARGS__); - - -static const char *escape_instructions = "Percent-encode username and password" - " according to RFC 3986"; - -static bool -_mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri, - const char *option, - int32_t value); - -static bool -_mongoc_uri_set_option_as_int32_with_error (mongoc_uri_t *uri, - const char *option, - int32_t value, - bson_error_t *error); - -static bool -_mongoc_uri_set_option_as_int64_with_error (mongoc_uri_t *uri, - const char *option, - int64_t value, - bson_error_t *error); - -static bool -ends_with (const char *str, const char *suffix); - -static void -mongoc_uri_do_unescape (char **str) -{ - char *tmp; - - if ((tmp = *str)) { - *str = mongoc_uri_unescape (tmp); - bson_free (tmp); - } -} - - -#define VALIDATE_SRV_ERR() \ - do { \ - bson_set_error (error, \ - MONGOC_ERROR_STREAM, \ - MONGOC_ERROR_STREAM_NAME_RESOLUTION, \ - "Invalid host \"%s\" returned for service \"%s\": " \ - "host must be subdomain of service name", \ - host, \ - service); \ - return false; \ - } while (0) - - -static int -count_dots (const char *s) -{ - int n = 0; - const char *dot = s; - - while ((dot = strchr (dot + 1, '.'))) { - n++; - } - - return n; -} - - -/* at least one character, and does not start or end with dot */ -static bool -valid_hostname (const char *s) -{ - size_t len = strlen (s); - - return len > 1 && s[0] != '.' && s[len - 1] != '.'; -} - - -static bool -validate_srv_result (mongoc_uri_t *uri, const char *host, bson_error_t *error) -{ - const char *service; - const char *service_root; - - service = mongoc_uri_get_service (uri); - BSON_ASSERT (service); - - if (!valid_hostname (host)) { - VALIDATE_SRV_ERR (); - } - - service_root = strchr (service, '.'); - BSON_ASSERT (service_root); - - /* host must be descendent of service root: if service is - * "a.foo.co" host can be like "a.foo.co", "b.foo.co", "a.b.foo.co", etc. - */ - if (strlen (host) < strlen (service_root)) { - VALIDATE_SRV_ERR (); - } - - if (!ends_with (host, service_root)) { - VALIDATE_SRV_ERR (); - } - - return true; -} - -/* upsert @host into @uri's host list. Side effect: modifies host->next when - * inserting. */ -static bool -_upsert_into_host_list (mongoc_uri_t *uri, - mongoc_host_list_t *host, - bson_error_t *error) -{ - if (uri->is_srv && !validate_srv_result (uri, host->host, error)) { - return false; - } - - _mongoc_host_list_upsert (&uri->hosts, host); - - return true; -} - -bool -mongoc_uri_upsert_host_and_port (mongoc_uri_t *uri, - const char *host_and_port, - bson_error_t *error) -{ - mongoc_host_list_t temp; - - memset (&temp, 0, sizeof (mongoc_host_list_t)); - if (!_mongoc_host_list_from_string_with_err (&temp, host_and_port, error)) { - return false; - } - - return _upsert_into_host_list (uri, &temp, error); -} - -bool -mongoc_uri_upsert_host (mongoc_uri_t *uri, - const char *host, - uint16_t port, - bson_error_t *error) -{ - mongoc_host_list_t temp; - - memset (&temp, 0, sizeof (mongoc_host_list_t)); - if (!_mongoc_host_list_from_hostport_with_err (&temp, host, port, error)) { - return false; - } - - return _upsert_into_host_list (uri, &temp, error); -} - -void -mongoc_uri_remove_host (mongoc_uri_t *uri, const char *host, uint16_t port) -{ - _mongoc_host_list_remove_host (&(uri->hosts), host, port); -} - -/* - *-------------------------------------------------------------------------- - * - * scan_to_unichar -- - * - * Scans 'str' until either a character matching 'match' is found, - * until one of the characters in 'terminators' is encountered, or - * until we reach the end of 'str'. - * - * NOTE: 'terminators' may not include multibyte UTF-8 characters. - * - * Returns: - * If 'match' is found, returns a copy of the section of 'str' before - * that character. Otherwise, returns NULL. - * - * Side Effects: - * If 'match' is found, sets 'end' to begin at the matching character - * in 'str'. - * - *-------------------------------------------------------------------------- - */ - -static char * -scan_to_unichar (const char *str, - bson_unichar_t match, - const char *terminators, - const char **end) -{ - bson_unichar_t c; - const char *iter; - - for (iter = str; iter && *iter && (c = bson_utf8_get_char (iter)); - iter = bson_utf8_next_char (iter)) { - if (c == match) { - *end = iter; - return bson_strndup (str, iter - str); - } else if (c == '\\') { - iter = bson_utf8_next_char (iter); - if (!bson_utf8_get_char (iter)) { - break; - } - } else { - const char *term_iter; - for (term_iter = terminators; *term_iter; term_iter++) { - if (c == *term_iter) { - return NULL; - } - } - } - } - - return NULL; -} - - -/* - *-------------------------------------------------------------------------- - * - * ends_with -- - * - * Return true if str ends with suffix. - * - *-------------------------------------------------------------------------- - */ -static bool -ends_with (const char *str, const char *suffix) -{ - size_t str_len = strlen (str); - size_t suffix_len = strlen (suffix); - const char *s1, *s2; - - if (str_len < suffix_len) { - return false; - } - - /* start at the ends of both strings */ - s1 = str + str_len; - s2 = suffix + suffix_len; - - /* until either pointer reaches start of its string, compare the pointers */ - for (; s1 >= str && s2 >= suffix; s1--, s2--) { - if (*s1 != *s2) { - return false; - } - } - - return true; -} - - -static bool -mongoc_uri_parse_scheme (mongoc_uri_t *uri, const char *str, const char **end) -{ - if (!strncmp (str, "mongodb+srv://", 14)) { - uri->is_srv = true; - *end = str + 14; - return true; - } - - if (!strncmp (str, "mongodb://", 10)) { - uri->is_srv = false; - *end = str + 10; - return true; - } - - return false; -} - - -static bool -mongoc_uri_has_unescaped_chars (const char *str, const char *chars) -{ - const char *c; - const char *tmp; - char *s; - - for (c = chars; *c; c++) { - s = scan_to_unichar (str, (bson_unichar_t) *c, "", &tmp); - if (s) { - bson_free (s); - return true; - } - } - - return false; -} - - -/* "str" is non-NULL, the part of URI between "mongodb://" and first "@" */ -static bool -mongoc_uri_parse_userpass (mongoc_uri_t *uri, - const char *str, - bson_error_t *error) -{ - const char *prohibited = "@:/"; - const char *end_user; - - BSON_ASSERT (str); - BSON_ASSERT (uri); - - if ((uri->username = scan_to_unichar (str, ':', "", &end_user))) { - uri->password = bson_strdup (end_user + 1); - } else { - uri->username = bson_strdup (str); - uri->password = NULL; - } - - if (mongoc_uri_has_unescaped_chars (uri->username, prohibited)) { - MONGOC_URI_ERROR (error, - "Username \"%s\" must not have unescaped chars. %s", - uri->username, - escape_instructions); - return false; - } - - mongoc_uri_do_unescape (&uri->username); - if (!uri->username) { - MONGOC_URI_ERROR ( - error, "Incorrect URI escapes in username. %s", escape_instructions); - return false; - } - - /* Providing password at all is optional */ - if (uri->password) { - if (mongoc_uri_has_unescaped_chars (uri->password, prohibited)) { - MONGOC_URI_ERROR (error, - "Password \"%s\" must not have unescaped chars. %s", - uri->password, - escape_instructions); - return false; - } - - mongoc_uri_do_unescape (&uri->password); - if (!uri->password) { - MONGOC_URI_ERROR (error, "%s", "Incorrect URI escapes in password"); - return false; - } - } - - return true; -} - -bool -mongoc_uri_parse_host (mongoc_uri_t *uri, const char *host_and_port_in) -{ - char *host_and_port = bson_strdup (host_and_port_in); - bson_error_t err = {0}; - bool r; - - /* unescape host. It doesn't hurt including port. */ - if (mongoc_uri_has_unescaped_chars (host_and_port, "/")) { - MONGOC_WARNING ("Unix Domain Sockets must be escaped (e.g. / = %%2F)"); - bson_free (host_and_port); - return false; - } - - mongoc_uri_do_unescape (&host_and_port); - if (!host_and_port) { - /* invalid */ - bson_free (host_and_port); - return false; - } - - r = mongoc_uri_upsert_host_and_port (uri, host_and_port, &err); - - if (!r) { - MONGOC_ERROR ("%s", err.message); - bson_free (host_and_port); - return false; - } - - bson_free (host_and_port); - return true; -} - - -bool -mongoc_uri_parse_srv (mongoc_uri_t *uri, const char *str) -{ - char *service; - - if (*str == '\0') { - return false; - } - - service = bson_strdup (str); - mongoc_uri_do_unescape (&service); - if (!service) { - /* invalid */ - return false; - } - - if (!valid_hostname (service) || count_dots (service) < 2) { - bson_free (service); - return false; - } - - bson_strncpy (uri->srv, service, sizeof uri->srv); - bson_free (service); - - if (strchr (uri->srv, ',') || strchr (uri->srv, ':')) { - /* prohibit port number or multiple service names */ - return false; - } - - return true; -} - - -/* "hosts" is non-NULL, the part between "mongodb://" or "@" and last "/" */ -static bool -mongoc_uri_parse_hosts (mongoc_uri_t *uri, const char *hosts) -{ - const char *next; - const char *end_hostport; - char *s; - BSON_ASSERT (hosts); - /* - * Parsing the series of hosts is a lot more complicated than you might - * imagine. This is due to some characters being both separators as well as - * valid characters within the "hostname". In particularly, we can have file - * paths to specify paths to UNIX domain sockets. We impose the restriction - * that they must be suffixed with ".sock" to simplify the parsing. - * - * You can separate hosts and file system paths to UNIX domain sockets with - * ",". - */ - s = scan_to_unichar (hosts, '?', "", &end_hostport); - if (s) { - MONGOC_WARNING ( - "%s", "A '/' is required between the host list and any options."); - goto error; - } - next = hosts; - do { - /* makes a copy of the section of the string */ - s = scan_to_unichar (next, ',', "", &end_hostport); - if (s) { - next = (char *) end_hostport + 1; - } else { - s = bson_strdup (next); - next = NULL; - } - if (!mongoc_uri_parse_host (uri, s)) { - goto error; - } - bson_free (s); - } while (next); - return true; -error: - bson_free (s); - return false; -} - -/* ----------------------------------------------------------------------------- - * - * mongoc_uri_parse_database -- - * - * Parse the database after @str. @str is expected to point after the - * host list to the character immediately after the / in the uri string. - * If no database is specified in the uri, e.g. the uri has a form like: - * mongodb://localhost/?option=X then uri->database remains NULL after - * parsing. - * - * Return: - * True if the parsed database is valid. An empty database is considered - * valid. - * ----------------------------------------------------------------------------- - */ -static bool -mongoc_uri_parse_database (mongoc_uri_t *uri, const char *str, const char **end) -{ - const char *end_database; - const char *c; - char *invalid_c; - const char *tmp; - - if ((uri->database = scan_to_unichar (str, '?', "", &end_database))) { - if (strcmp (uri->database, "") == 0) { - /* no database is found, don't store the empty string. */ - bson_free (uri->database); - uri->database = NULL; - /* but it is valid to have an empty database. */ - return true; - } - *end = end_database; - } else if (*str) { - uri->database = bson_strdup (str); - *end = str + strlen (str); - } - - mongoc_uri_do_unescape (&uri->database); - if (!uri->database) { - /* invalid */ - return false; - } - - /* invalid characters in database name */ - for (c = "/\\. \"$"; *c; c++) { - invalid_c = - scan_to_unichar (uri->database, (bson_unichar_t) *c, "", &tmp); - if (invalid_c) { - bson_free (invalid_c); - return false; - } - } - - return true; -} - - -static bool -mongoc_uri_parse_auth_mechanism_properties (mongoc_uri_t *uri, const char *str) -{ - char *field; - char *value; - const char *end_scan; - bson_t properties; - - bson_init (&properties); - - /* build up the properties document */ - while ((field = scan_to_unichar (str, ':', "&", &end_scan))) { - str = end_scan + 1; - if (!(value = scan_to_unichar (str, ',', ":&", &end_scan))) { - value = bson_strdup (str); - str = ""; - } else { - str = end_scan + 1; - } - bson_append_utf8 (&properties, field, -1, value, -1); - bson_free (field); - bson_free (value); - } - - /* append our auth properties to our credentials */ - if (!mongoc_uri_set_mechanism_properties (uri, &properties)) { - bson_destroy (&properties); - return false; - } - bson_destroy (&properties); - return true; -} - -static bool -mongoc_uri_parse_tags (mongoc_uri_t *uri, /* IN */ - const char *str) /* IN */ -{ - const char *end_keyval; - const char *end_key; - bson_t b; - char *keyval; - char *key; - - bson_init (&b); - -again: - if ((keyval = scan_to_unichar (str, ',', "", &end_keyval))) { - if (!(key = scan_to_unichar (keyval, ':', "", &end_key))) { - bson_free (keyval); - goto fail; - } - - bson_append_utf8 (&b, key, -1, end_key + 1, -1); - bson_free (key); - bson_free (keyval); - str = end_keyval + 1; - goto again; - } else if ((key = scan_to_unichar (str, ':', "", &end_key))) { - bson_append_utf8 (&b, key, -1, end_key + 1, -1); - bson_free (key); - } else if (strlen (str)) { - /* we're not finished but we couldn't parse the string */ - goto fail; - } - - mongoc_read_prefs_add_tag (uri->read_prefs, &b); - bson_destroy (&b); - - return true; - -fail: - MONGOC_WARNING ("Unsupported value for \"" MONGOC_URI_READPREFERENCETAGS - "\": \"%s\"", - str); - bson_destroy (&b); - return false; -} - - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_bson_append_or_replace_key -- - * - * - * Appends 'option' to the end of 'options' if not already set. - * - * Since we cannot grow utf8 strings inline, we have to allocate a - * temporary bson variable and splice in the new value if the key - * is already set. - * - * NOTE: This function keeps the order of the BSON keys. - * - * NOTE: 'option' is case*in*sensitive. - * - * - *-------------------------------------------------------------------------- - */ - -static void -mongoc_uri_bson_append_or_replace_key (bson_t *options, - const char *option, - const char *value) -{ - bson_iter_t iter; - bool found = false; - - if (bson_iter_init (&iter, options)) { - bson_t tmp = BSON_INITIALIZER; - - while (bson_iter_next (&iter)) { - const bson_value_t *bvalue; - - if (!strcasecmp (bson_iter_key (&iter), option)) { - bson_append_utf8 (&tmp, option, -1, value, -1); - found = true; - continue; - } - - bvalue = bson_iter_value (&iter); - BSON_APPEND_VALUE (&tmp, bson_iter_key (&iter), bvalue); - } - - if (!found) { - bson_append_utf8 (&tmp, option, -1, value, -1); - } - - bson_destroy (options); - bson_copy_to (&tmp, options); - bson_destroy (&tmp); - } -} - - -bool -mongoc_uri_option_is_int32 (const char *key) -{ - return mongoc_uri_option_is_int64 (key) || - !strcasecmp (key, MONGOC_URI_CONNECTTIMEOUTMS) || - !strcasecmp (key, MONGOC_URI_HEARTBEATFREQUENCYMS) || - !strcasecmp (key, MONGOC_URI_SERVERSELECTIONTIMEOUTMS) || - !strcasecmp (key, MONGOC_URI_SOCKETCHECKINTERVALMS) || - !strcasecmp (key, MONGOC_URI_SOCKETTIMEOUTMS) || - !strcasecmp (key, MONGOC_URI_LOCALTHRESHOLDMS) || - !strcasecmp (key, MONGOC_URI_MAXPOOLSIZE) || - !strcasecmp (key, MONGOC_URI_MAXSTALENESSSECONDS) || - !strcasecmp (key, MONGOC_URI_MINPOOLSIZE) || - !strcasecmp (key, MONGOC_URI_MAXIDLETIMEMS) || - !strcasecmp (key, MONGOC_URI_WAITQUEUEMULTIPLE) || - !strcasecmp (key, MONGOC_URI_WAITQUEUETIMEOUTMS) || - !strcasecmp (key, MONGOC_URI_ZLIBCOMPRESSIONLEVEL); -} - -bool -mongoc_uri_option_is_int64 (const char *key) -{ - return !strcasecmp (key, MONGOC_URI_WTIMEOUTMS); -} - -bool -mongoc_uri_option_is_bool (const char *key) -{ - return !strcasecmp (key, MONGOC_URI_CANONICALIZEHOSTNAME) || - !strcasecmp (key, MONGOC_URI_JOURNAL) || - !strcasecmp (key, MONGOC_URI_RETRYREADS) || - !strcasecmp (key, MONGOC_URI_RETRYWRITES) || - !strcasecmp (key, MONGOC_URI_SAFE) || - !strcasecmp (key, MONGOC_URI_SERVERSELECTIONTRYONCE) || - !strcasecmp (key, MONGOC_URI_SLAVEOK) || - !strcasecmp (key, MONGOC_URI_TLS) || - !strcasecmp (key, MONGOC_URI_TLSINSECURE) || - !strcasecmp (key, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) || - !strcasecmp (key, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES) || - /* deprecated options */ - !strcasecmp (key, MONGOC_URI_SSL) || - !strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES) || - !strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES); -} - -bool -mongoc_uri_option_is_utf8 (const char *key) -{ - return !strcasecmp (key, MONGOC_URI_APPNAME) || - !strcasecmp (key, MONGOC_URI_REPLICASET) || - !strcasecmp (key, MONGOC_URI_READPREFERENCE) || - !strcasecmp (key, MONGOC_URI_TLSCERTIFICATEKEYFILE) || - !strcasecmp (key, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD) || - !strcasecmp (key, MONGOC_URI_TLSCAFILE) || - /* deprecated options */ - !strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE) || - !strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD) || - !strcasecmp (key, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE); -} - -const char * -mongoc_uri_canonicalize_option (const char *key) -{ - if (!strcasecmp (key, MONGOC_URI_SSL)) { - return MONGOC_URI_TLS; - } else if (!strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE)) { - return MONGOC_URI_TLSCERTIFICATEKEYFILE; - } else if (!strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD)) { - return MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD; - } else if (!strcasecmp (key, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE)) { - return MONGOC_URI_TLSCAFILE; - } else if (!strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES)) { - return MONGOC_URI_TLSALLOWINVALIDCERTIFICATES; - } else if (!strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES)) { - return MONGOC_URI_TLSALLOWINVALIDHOSTNAMES; - } else { - return key; - } -} - -static bool -_mongoc_uri_parse_int64 (const char *key, const char *value, int64_t *result) -{ - char *endptr; - int64_t i; - - errno = 0; - i = bson_ascii_strtoll (value, &endptr, 10); - if (errno || endptr < value + strlen (value)) { - MONGOC_WARNING ("Invalid %s: cannot parse integer\n", key); - return false; - } - - *result = i; - return true; -} - - -static bool -mongoc_uri_parse_int32 (const char *key, const char *value, int32_t *result) -{ - int64_t i; - - if (!_mongoc_uri_parse_int64 (key, value, &i)) { - /* _mongoc_uri_parse_int64 emits a warning if it could not parse the - * given value, so we don't have to add one here. - */ - return false; - } - - if (i > INT32_MAX || i < INT32_MIN) { - MONGOC_WARNING ("Invalid %s: cannot fit in int32\n", key); - return false; - } - - *result = (int32_t) i; - return true; -} - - -static bool -dns_option_allowed (const char *lkey) -{ - /* Initial DNS Seedlist Discovery Spec: "A Client MUST only support the - * authSource and replicaSet options through a TXT record, and MUST raise an - * error if any other option is encountered." - */ - return !strcmp (lkey, MONGOC_URI_AUTHSOURCE) || - !strcmp (lkey, MONGOC_URI_REPLICASET); -} - - -/* Decompose a key=val pair and place them into a document. - * Includes case-folding for key portion. - */ -static bool -mongoc_uri_split_option (mongoc_uri_t *uri, - bson_t *options, - const char *str, - bool from_dns, - bson_error_t *error) -{ - bson_iter_t iter; - const char *end_key; - char *key = NULL; - char *lkey = NULL; - char *value = NULL; - const char *opt; - char *opt_end; - size_t opt_len; - bool ret = false; - - if (!(key = scan_to_unichar (str, '=', "", &end_key))) { - MONGOC_URI_ERROR (error, "URI option \"%s\" contains no \"=\" sign", str); - goto CLEANUP; - } - - value = bson_strdup (end_key + 1); - mongoc_uri_do_unescape (&value); - if (!value) { - /* do_unescape detected invalid UTF-8 and freed value */ - MONGOC_URI_ERROR ( - error, "Value for URI option \"%s\" contains invalid UTF-8", key); - goto CLEANUP; - } - - lkey = bson_strdup (key); - mongoc_lowercase (key, lkey); - - /* Initial DNS Seedlist Discovery Spec: "A Client MUST only support the - * authSource and replicaSet options through a TXT record, and MUST raise an - * error if any other option is encountered."*/ - if (from_dns && !dns_option_allowed (lkey)) { - MONGOC_URI_ERROR ( - error, "URI option \"%s\" prohibited in TXT record", key); - goto CLEANUP; - } - - /* Special case: READPREFERENCETAGS is a composing option. - * Multiple instances should append, not overwrite. - * Encode them directly to the options field, - * bypassing canonicalization and duplicate checks. - */ - if (!strcmp (lkey, MONGOC_URI_READPREFERENCETAGS)) { - if (!mongoc_uri_parse_tags (uri, value)) { - MONGOC_URI_ERROR ( - error, "Unsupported value for \"%s\": \"%s\"", key, value); - goto CLEANUP; - } - } else if (bson_iter_init_find (&iter, &uri->raw, lkey) || - bson_iter_init_find (&iter, options, lkey)) { - /* Special case, MONGOC_URI_W == "any non-int" is not overridden - * by later values. - */ - if (!strcmp (lkey, MONGOC_URI_W) && - (opt = bson_iter_utf8_unsafe (&iter, &opt_len))) { - strtol (opt, &opt_end, 10); - if (*opt_end != '\0') { - ret = true; - goto CLEANUP; - } - } - - /* Initial DNS Seedlist Discovery Spec: "Client MUST use options - * specified in the Connection String to override options provided - * through TXT records." So, do NOT override existing options with TXT - * options. */ - if (from_dns) { - MONGOC_WARNING ( - "Cannot override URI option \"%s\" from TXT record \"%s\"", - key, - str); - ret = true; - goto CLEANUP; - } - MONGOC_WARNING ("Overwriting previously provided value for '%s'", key); - } - - if (!(strcmp (lkey, MONGOC_URI_REPLICASET)) && *value == '\0') { - MONGOC_URI_ERROR ( - error, "Value for URI option \"%s\" cannot be empty string", lkey); - goto CLEANUP; - } - - mongoc_uri_bson_append_or_replace_key (options, lkey, value); - ret = true; - -CLEANUP: - bson_free (key); - bson_free (lkey); - bson_free (value); - - return ret; -} - - -/* Check for canonical/deprecated conflicts - * between the option list a, and b. - * If both names exist either way with differing values, error. - */ -static bool -mongoc_uri_options_validate_names (const bson_t *a, - const bson_t *b, - bson_error_t *error) -{ - bson_iter_t key_iter, canon_iter; - const char *key = NULL; - const char *canon = NULL; - const char *value = NULL; - const char *cval = NULL; - size_t value_len = 0; - size_t cval_len = 0; - - /* Scan `a` looking for deprecated names - * where the canonical name was also used in `a`, - * or was used in `b`. */ - bson_iter_init (&key_iter, a); - while (bson_iter_next (&key_iter)) { - key = bson_iter_key (&key_iter); - value = bson_iter_utf8_unsafe (&key_iter, &value_len); - canon = mongoc_uri_canonicalize_option (key); - - if (key == canon) { - /* Canonical form, no point checking `b`. */ - continue; - } - - /* Check for a conflict in `a`. */ - if (bson_iter_init_find (&canon_iter, a, canon)) { - cval = bson_iter_utf8_unsafe (&canon_iter, &cval_len); - if ((value_len != cval_len) || strcmp (value, cval)) { - goto HANDLE_CONFLICT; - } - } - - /* Check for a conflict in `b`. */ - if (bson_iter_init_find (&canon_iter, b, canon)) { - cval = bson_iter_utf8_unsafe (&canon_iter, &cval_len); - if ((value_len != cval_len) || strcmp (value, cval)) { - goto HANDLE_CONFLICT; - } - } - } - - return true; - -HANDLE_CONFLICT: - MONGOC_URI_ERROR (error, - "Deprecated option '%s=%s' conflicts with " - "canonical name '%s=%s'", - key, - value, - canon, - cval); - - return false; -} - - -#define HANDLE_DUPE() \ - if (from_dns) { \ - MONGOC_WARNING ("Cannot override URI option \"%s\" from TXT record", \ - key); \ - continue; \ - } else { \ - MONGOC_WARNING ("Overwriting previously provided value for '%s'", key); \ - } - -static bool -mongoc_uri_apply_options (mongoc_uri_t *uri, - const bson_t *options, - bool from_dns, - bson_error_t *error) -{ - bson_iter_t iter; - int32_t v_int; - int64_t v_int64; - const char *key = NULL; - const char *canon = NULL; - const char *value = NULL; - size_t value_len; - bool bval; - - bson_iter_init (&iter, options); - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - canon = mongoc_uri_canonicalize_option (key); - value = bson_iter_utf8_unsafe (&iter, &value_len); - - /* Keep a record of how the option was originally presented. */ - mongoc_uri_bson_append_or_replace_key (&uri->raw, key, value); - - /* This check precedes mongoc_uri_option_is_int32 as all 64-bit values are - * also recognised as 32-bit ints. - */ - if (mongoc_uri_option_is_int64 (key)) { - if (!_mongoc_uri_parse_int64 (key, value, &v_int64)) { - goto UNSUPPORTED_VALUE; - } - - if (!_mongoc_uri_set_option_as_int64_with_error ( - uri, canon, v_int64, error)) { - return false; - } - } else if (mongoc_uri_option_is_int32 (key)) { - if (!mongoc_uri_parse_int32 (key, value, &v_int)) { - goto UNSUPPORTED_VALUE; - } - - if (!_mongoc_uri_set_option_as_int32_with_error ( - uri, canon, v_int, error)) { - return false; - } - } else if (!strcmp (key, MONGOC_URI_W)) { - if (*value == '-' || isdigit (*value)) { - v_int = (int) strtol (value, NULL, 10); - _mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_W, v_int); - } else if (0 == strcasecmp (value, "majority")) { - mongoc_uri_bson_append_or_replace_key ( - &uri->options, MONGOC_URI_W, "majority"); - } else if (*value) { - mongoc_uri_bson_append_or_replace_key ( - &uri->options, MONGOC_URI_W, value); - } - - } else if (mongoc_uri_option_is_bool (key)) { - if (0 == strcasecmp (value, "true")) { - bval = true; - } else if (0 == strcasecmp (value, "false")) { - bval = false; - } else if ((0 == strcmp (value, "1")) || - (0 == strcasecmp (value, "yes")) || - (0 == strcasecmp (value, "y")) || - (0 == strcasecmp (value, "t"))) { - MONGOC_WARNING ("Deprecated boolean value for \"%s\": \"%s\", " - "please update to \"%s=true\"", - key, - value, - key); - bval = true; - } else if ((0 == strcasecmp (value, "0")) || - (0 == strcasecmp (value, "-1")) || - (0 == strcmp (value, "no")) || (0 == strcmp (value, "n")) || - (0 == strcmp (value, "f"))) { - MONGOC_WARNING ("Deprecated boolean value for \"%s\": \"%s\", " - "please update to \"%s=false\"", - key, - value, - key); - bval = false; - } else { - goto UNSUPPORTED_VALUE; - } - - if (!mongoc_uri_set_option_as_bool (uri, canon, bval)) { - return false; - } - - } else if (!strcmp (key, MONGOC_URI_READPREFERENCETAGS)) { - /* Skip this option here. - * It was marshalled during mongoc_uri_split_option() - * as a special case composing option. - */ - - } else if (!strcmp (key, MONGOC_URI_AUTHMECHANISM) || - !strcmp (key, MONGOC_URI_AUTHSOURCE)) { - if (bson_has_field (&uri->credentials, key)) { - HANDLE_DUPE (); - } - mongoc_uri_bson_append_or_replace_key ( - &uri->credentials, canon, value); - - } else if (!strcmp (key, MONGOC_URI_READCONCERNLEVEL)) { - if (!mongoc_read_concern_is_default (uri->read_concern)) { - HANDLE_DUPE (); - } - mongoc_read_concern_set_level (uri->read_concern, value); - - } else if (!strcmp (key, MONGOC_URI_GSSAPISERVICENAME)) { - char *tmp = bson_strdup_printf ("SERVICE_NAME:%s", value); - if (bson_has_field (&uri->credentials, - MONGOC_URI_AUTHMECHANISMPROPERTIES)) { - MONGOC_WARNING ("authMechanismProperties SERVICE_NAME already set, " - "ignoring '%s'", - key); - } else if (!mongoc_uri_parse_auth_mechanism_properties (uri, tmp)) { - bson_free (tmp); - goto UNSUPPORTED_VALUE; - } - bson_free (tmp); - - } else if (!strcmp (key, MONGOC_URI_AUTHMECHANISMPROPERTIES)) { - if (bson_has_field (&uri->credentials, key)) { - HANDLE_DUPE (); - } - if (!mongoc_uri_parse_auth_mechanism_properties (uri, value)) { - goto UNSUPPORTED_VALUE; - } - - } else if (!strcmp (key, MONGOC_URI_APPNAME)) { - /* Part of uri->options */ - if (!mongoc_uri_set_appname (uri, value)) { - goto UNSUPPORTED_VALUE; - } - - } else if (!strcmp (key, MONGOC_URI_COMPRESSORS)) { - if (!bson_empty (mongoc_uri_get_compressors (uri))) { - HANDLE_DUPE (); - } - if (!mongoc_uri_set_compressors (uri, value)) { - goto UNSUPPORTED_VALUE; - } - - } else if (mongoc_uri_option_is_utf8 (key)) { - mongoc_uri_bson_append_or_replace_key (&uri->options, canon, value); - - } else { - /* - * Keys that aren't supported by a driver MUST be ignored. - * - * A WARN level logging message MUST be issued - * https://github.com/mongodb/specifications/blob/master/source/connection-string/connection-string-spec.rst#keys - */ - MONGOC_WARNING ("Unsupported URI option \"%s\"", key); - } - } - - return true; - -UNSUPPORTED_VALUE: - MONGOC_URI_ERROR (error, "Unsupported value for \"%s\": \"%s\"", key, value); - - return false; -} - - -/* Processes a query string formatted set of driver options - * (i.e. tls=true&connectTimeoutMS=250 ) into a BSON dict of values. - * uri->raw is initially populated with the raw split of key/value pairs, - * then the keys are canonicalized and the values coerced - * to their appropriate type and stored in uri->options. - */ -bool -mongoc_uri_parse_options (mongoc_uri_t *uri, - const char *str, - bool from_dns, - bson_error_t *error) -{ - bson_t options; - const char *end_option; - char *option; - - bson_init (&options); - while ((option = scan_to_unichar (str, '&', "", &end_option))) { - if (!mongoc_uri_split_option (uri, &options, option, from_dns, error)) { - bson_free (option); - bson_destroy (&options); - return false; - } - bson_free (option); - str = end_option + 1; - } - - if (*str && !mongoc_uri_split_option (uri, &options, str, from_dns, error)) { - bson_destroy (&options); - return false; - } - - /* Walk both sides of this map to handle each ordering: - * deprecated first canonical later, and vice-versa. - * Then finalize parse by writing final values to uri->options. - */ - if (!mongoc_uri_options_validate_names (&uri->options, &options, error) || - !mongoc_uri_options_validate_names (&options, &uri->options, error) || - !mongoc_uri_apply_options (uri, &options, from_dns, error)) { - bson_destroy (&options); - return false; - } - - bson_destroy (&options); - return true; -} - - -static bool -mongoc_uri_finalize_tls (mongoc_uri_t *uri, bson_error_t *error) -{ - /* Initial DNS Seedlist Discovery Spec: "If mongodb+srv is used, a driver - * MUST implicitly also enable TLS." */ - if (uri->is_srv && !bson_has_field (&uri->options, MONGOC_URI_TLS)) { - mongoc_uri_set_option_as_bool (uri, MONGOC_URI_TLS, true); - } - - if (bson_has_field (&uri->options, MONGOC_URI_TLSINSECURE) && - (bson_has_field (&uri->options, - MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) || - bson_has_field (&uri->options, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES))) { - MONGOC_URI_ERROR (error, - "%s may not be specified with %s or %s", - MONGOC_URI_TLSINSECURE, - MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, - MONGOC_URI_TLSALLOWINVALIDHOSTNAMES); - return false; - } - - return true; -} - - -static bool -mongoc_uri_finalize_auth (mongoc_uri_t *uri, - bson_error_t *error, - bool require_auth) -{ - bson_iter_t iter; - const char *source = NULL; - - if (bson_iter_init_find_case ( - &iter, &uri->credentials, MONGOC_URI_AUTHSOURCE)) { - source = bson_iter_utf8 (&iter, NULL); - require_auth = true; - } - - if (mongoc_uri_get_auth_mechanism (uri)) { - /* authSource with GSSAPI or X509 should always be external */ - if (!strcasecmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI") || - !strcasecmp (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509")) { - if (source) { - if (strcasecmp (source, "$external")) { - MONGOC_URI_ERROR ( - error, - "%s", - "GSSAPI and X509 require \"$external\" authSource"); - return false; - } - } else { - bson_append_utf8 ( - &uri->credentials, MONGOC_URI_AUTHSOURCE, -1, "$external", -1); - } - } - /* MONGODB-X509 is the only mechanism that doesn't require username */ - if (strcasecmp (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509") != - 0) { - if (!mongoc_uri_get_username (uri) || - strcmp (mongoc_uri_get_username (uri), "") == 0) { - MONGOC_URI_ERROR (error, - "'%s' authentication mechanism requires username", - mongoc_uri_get_auth_mechanism (uri)); - return false; - } - } - /* MONGODB-X509 errors if a password is supplied. */ - if (strcasecmp (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509") == - 0) { - if (mongoc_uri_get_password (uri)) { - MONGOC_URI_ERROR ( - error, - "'%s' authentication mechanism does not accept a password", - mongoc_uri_get_auth_mechanism (uri)); - return false; - } - } - /* GSSAPI uses 'mongodb' as the default service name */ - if (strcasecmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI") == 0 && - !(bson_iter_init_find ( - &iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES) && - BSON_ITER_HOLDS_DOCUMENT (&iter) && - bson_iter_recurse (&iter, &iter) && - bson_iter_find_case (&iter, "SERVICE_NAME"))) { - bson_t tmp; - bson_t *props = NULL; - - props = mongoc_uri_get_mechanism_properties (uri, &tmp) - ? bson_copy (&tmp) - : bson_new (); - - BSON_APPEND_UTF8 (props, "SERVICE_NAME", "mongodb"); - mongoc_uri_set_mechanism_properties (uri, props); - - bson_destroy (props); - } - - } else if (require_auth) /* Default auth mechanism is used */ { - if (!mongoc_uri_get_username (uri) || - strcmp (mongoc_uri_get_username (uri), "") == 0) { - MONGOC_URI_ERROR ( - error, "%s", "Default authentication mechanism requires username"); - return false; - } - } - return true; -} - -static bool -mongoc_uri_parse_before_slash (mongoc_uri_t *uri, - const char *before_slash, - bson_error_t *error) -{ - char *userpass; - const char *hosts; - - userpass = scan_to_unichar (before_slash, '@', "", &hosts); - if (userpass) { - if (!mongoc_uri_parse_userpass (uri, userpass, error)) { - goto error; - } - - hosts++; /* advance past "@" */ - if (*hosts == '@') { - /* special case: "mongodb://alice@@localhost" */ - MONGOC_URI_ERROR ( - error, "Invalid username or password. %s", escape_instructions); - goto error; - } - } else { - hosts = before_slash; - } - - if (uri->is_srv) { - if (!mongoc_uri_parse_srv (uri, hosts)) { - MONGOC_URI_ERROR (error, "%s", "Invalid service name in URI"); - goto error; - } - } else { - if (!mongoc_uri_parse_hosts (uri, hosts)) { - MONGOC_URI_ERROR (error, "%s", "Invalid host string in URI"); - goto error; - } - } - - bson_free (userpass); - return true; - -error: - bson_free (userpass); - return false; -} - - -static bool -mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error) -{ - char *before_slash = NULL; - const char *tmp; - bool require_auth = false; - - if (!bson_utf8_validate (str, strlen (str), false /* allow_null */)) { - MONGOC_URI_ERROR (error, "%s", "Invalid UTF-8 in URI"); - goto error; - } - - if (!mongoc_uri_parse_scheme (uri, str, &str)) { - MONGOC_URI_ERROR ( - error, - "%s", - "Invalid URI Schema, expecting 'mongodb://' or 'mongodb+srv://'"); - goto error; - } - - before_slash = scan_to_unichar (str, '/', "", &tmp); - if (!before_slash) { - before_slash = bson_strdup (str); - str += strlen (before_slash); - } else { - str = tmp; - } - - if (!mongoc_uri_parse_before_slash (uri, before_slash, error)) { - goto error; - } - - if (*str) { - if (*str == '/') { - str++; - if (*str) { - if (!mongoc_uri_parse_database (uri, str, &str)) { - MONGOC_URI_ERROR (error, "%s", "Invalid database name in URI"); - goto error; - } - } - - if (*str == '?') { - str++; - if (*str) { - if (!mongoc_uri_parse_options ( - uri, str, false /* from DNS */, error)) { - goto error; - } - } - } - } else { - MONGOC_URI_ERROR (error, "%s", "Expected end of hostname delimiter"); - goto error; - } - } - - if (!mongoc_uri_finalize_tls (uri, error)) { - goto error; - } - - require_auth = uri->username != NULL; - if (!mongoc_uri_finalize_auth (uri, error, require_auth)) { - goto error; - } - - bson_free (before_slash); - return true; - -error: - bson_free (before_slash); - return false; -} - - -const mongoc_host_list_t * -mongoc_uri_get_hosts (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - return uri->hosts; -} - - -const char * -mongoc_uri_get_replica_set (const mongoc_uri_t *uri) -{ - bson_iter_t iter; - - BSON_ASSERT (uri); - - if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_REPLICASET) && - BSON_ITER_HOLDS_UTF8 (&iter)) { - return bson_iter_utf8 (&iter, NULL); - } - - return NULL; -} - - -const bson_t * -mongoc_uri_get_credentials (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - return &uri->credentials; -} - - -const char * -mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri) -{ - bson_iter_t iter; - - BSON_ASSERT (uri); - - if (bson_iter_init_find_case ( - &iter, &uri->credentials, MONGOC_URI_AUTHMECHANISM) && - BSON_ITER_HOLDS_UTF8 (&iter)) { - return bson_iter_utf8 (&iter, NULL); - } - - return NULL; -} - - -bool -mongoc_uri_set_auth_mechanism (mongoc_uri_t *uri, const char *value) -{ - size_t len; - - BSON_ASSERT (value); - - len = strlen (value); - - if (!bson_utf8_validate (value, len, false)) { - return false; - } - - mongoc_uri_bson_append_or_replace_key ( - &uri->credentials, MONGOC_URI_AUTHMECHANISM, value); - - return true; -} - - -bool -mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri, - bson_t *properties /* OUT */) -{ - bson_iter_t iter; - - BSON_ASSERT (uri); - BSON_ASSERT (properties); - - if (bson_iter_init_find_case ( - &iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES) && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - uint32_t len = 0; - const uint8_t *data = NULL; - - bson_iter_document (&iter, &len, &data); - BSON_ASSERT (bson_init_static (properties, data, len)); - - return true; - } - - return false; -} - - -bool -mongoc_uri_set_mechanism_properties (mongoc_uri_t *uri, - const bson_t *properties) -{ - bson_iter_t iter; - bson_t tmp = BSON_INITIALIZER; - bool r; - - BSON_ASSERT (uri); - BSON_ASSERT (properties); - - if (bson_iter_init_find ( - &iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES)) { - /* copy all elements to tmp besides authMechanismProperties */ - bson_copy_to_excluding_noinit (&uri->credentials, - &tmp, - MONGOC_URI_AUTHMECHANISMPROPERTIES, - (char *) NULL); - - r = BSON_APPEND_DOCUMENT ( - &tmp, MONGOC_URI_AUTHMECHANISMPROPERTIES, properties); - if (!r) { - bson_destroy (&tmp); - return false; - } - - bson_destroy (&uri->credentials); - bson_copy_to (&tmp, &uri->credentials); - bson_destroy (&tmp); - - return true; - } else { - bson_destroy (&tmp); - return BSON_APPEND_DOCUMENT ( - &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES, properties); - } -} - - -static bool -_mongoc_uri_assign_read_prefs_mode (mongoc_uri_t *uri, bson_error_t *error) -{ - const char *str; - bson_iter_t iter; - - BSON_ASSERT (uri); - - if (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_SLAVEOK, false)) { - mongoc_read_prefs_set_mode (uri->read_prefs, - MONGOC_READ_SECONDARY_PREFERRED); - } - - if (bson_iter_init_find_case ( - &iter, &uri->options, MONGOC_URI_READPREFERENCE) && - BSON_ITER_HOLDS_UTF8 (&iter)) { - str = bson_iter_utf8 (&iter, NULL); - - if (0 == strcasecmp ("primary", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_PRIMARY); - } else if (0 == strcasecmp ("primarypreferred", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, - MONGOC_READ_PRIMARY_PREFERRED); - } else if (0 == strcasecmp ("secondary", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_SECONDARY); - } else if (0 == strcasecmp ("secondarypreferred", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, - MONGOC_READ_SECONDARY_PREFERRED); - } else if (0 == strcasecmp ("nearest", str)) { - mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_NEAREST); - } else { - MONGOC_URI_ERROR ( - error, "Unsupported readPreference value [readPreference=%s]", str); - return false; - } - } - return true; -} - - -static bool -_mongoc_uri_build_write_concern (mongoc_uri_t *uri, bson_error_t *error) -{ - mongoc_write_concern_t *write_concern; - const char *str; - bson_iter_t iter; - int64_t wtimeoutms; - int value; - - BSON_ASSERT (uri); - - write_concern = mongoc_write_concern_new (); - uri->write_concern = write_concern; - - if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_SAFE) && - BSON_ITER_HOLDS_BOOL (&iter)) { - mongoc_write_concern_set_w ( - write_concern, - bson_iter_bool (&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); - } - - wtimeoutms = mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 0); - if (wtimeoutms < 0) { - MONGOC_URI_ERROR ( - error, "Unsupported wtimeoutMS value [w=%" PRId64 "]", wtimeoutms); - return false; - } else if (wtimeoutms > 0) { - mongoc_write_concern_set_wtimeout_int64 (write_concern, wtimeoutms); - } - - if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_JOURNAL) && - BSON_ITER_HOLDS_BOOL (&iter)) { - mongoc_write_concern_set_journal (write_concern, bson_iter_bool (&iter)); - } - - if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_W)) { - if (BSON_ITER_HOLDS_INT32 (&iter)) { - value = bson_iter_int32 (&iter); - - switch (value) { - case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED: - case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED: - if (mongoc_write_concern_get_journal (write_concern)) { - MONGOC_URI_ERROR ( - error, "Journal conflicts with w value [w=%d]", value); - return false; - } - mongoc_write_concern_set_w (write_concern, value); - break; - default: - if (value > 0) { - mongoc_write_concern_set_w (write_concern, value); - break; - } - MONGOC_URI_ERROR (error, "Unsupported w value [w=%d]", value); - return false; - } - } else if (BSON_ITER_HOLDS_UTF8 (&iter)) { - str = bson_iter_utf8 (&iter, NULL); - - if (0 == strcasecmp ("majority", str)) { - mongoc_write_concern_set_w (write_concern, - MONGOC_WRITE_CONCERN_W_MAJORITY); - } else { - mongoc_write_concern_set_wtag (write_concern, str); - } - } else { - BSON_ASSERT (false); - return false; - } - } - - return true; -} - -/* can't use mongoc_uri_get_option_as_int32, it treats 0 specially */ -static int32_t -_mongoc_uri_get_max_staleness_option (const mongoc_uri_t *uri) -{ - const bson_t *options; - bson_iter_t iter; - int32_t retval = MONGOC_NO_MAX_STALENESS; - - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case ( - &iter, options, MONGOC_URI_MAXSTALENESSSECONDS) && - BSON_ITER_HOLDS_INT32 (&iter)) { - retval = bson_iter_int32 (&iter); - if (retval == 0) { - MONGOC_WARNING ( - "Unsupported value for \"" MONGOC_URI_MAXSTALENESSSECONDS - "\": \"%d\"", - retval); - retval = -1; - } else if (retval < 0 && retval != -1) { - MONGOC_WARNING ( - "Unsupported value for \"" MONGOC_URI_MAXSTALENESSSECONDS - "\": \"%d\"", - retval); - retval = MONGOC_NO_MAX_STALENESS; - } - } - - return retval; -} - -mongoc_uri_t * -mongoc_uri_new_with_error (const char *uri_string, bson_error_t *error) -{ - mongoc_uri_t *uri; - int32_t max_staleness_seconds; - - uri = (mongoc_uri_t *) bson_malloc0 (sizeof *uri); - bson_init (&uri->raw); - bson_init (&uri->options); - bson_init (&uri->credentials); - bson_init (&uri->compressors); - - /* Initialize read_prefs, since parsing may add to it */ - uri->read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - /* Initialize empty read_concern */ - uri->read_concern = mongoc_read_concern_new (); - - if (!uri_string) { - uri_string = "mongodb://127.0.0.1/"; - } - - if (!mongoc_uri_parse (uri, uri_string, error)) { - mongoc_uri_destroy (uri); - return NULL; - } - - uri->str = bson_strdup (uri_string); - - if (!_mongoc_uri_assign_read_prefs_mode (uri, error)) { - mongoc_uri_destroy (uri); - return NULL; - } - max_staleness_seconds = _mongoc_uri_get_max_staleness_option (uri); - mongoc_read_prefs_set_max_staleness_seconds (uri->read_prefs, - max_staleness_seconds); - - if (!mongoc_read_prefs_is_valid (uri->read_prefs)) { - mongoc_uri_destroy (uri); - MONGOC_URI_ERROR (error, "%s", "Invalid readPreferences"); - return NULL; - } - - if (!_mongoc_uri_build_write_concern (uri, error)) { - mongoc_uri_destroy (uri); - return NULL; - } - - if (!mongoc_write_concern_is_valid (uri->write_concern)) { - mongoc_uri_destroy (uri); - MONGOC_URI_ERROR (error, "%s", "Invalid writeConcern"); - return NULL; - } - - return uri; -} - -mongoc_uri_t * -mongoc_uri_new (const char *uri_string) -{ - bson_error_t error = {0}; - mongoc_uri_t *uri; - - uri = mongoc_uri_new_with_error (uri_string, &error); - if (error.domain) { - MONGOC_WARNING ("Error parsing URI: '%s'", error.message); - } - - return uri; -} - - -mongoc_uri_t * -mongoc_uri_new_for_host_port (const char *hostname, uint16_t port) -{ - mongoc_uri_t *uri; - char *str; - - BSON_ASSERT (hostname); - BSON_ASSERT (port); - - str = bson_strdup_printf ("mongodb://%s:%hu/", hostname, port); - uri = mongoc_uri_new (str); - bson_free (str); - - return uri; -} - - -const char * -mongoc_uri_get_username (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - - return uri->username; -} - -bool -mongoc_uri_set_username (mongoc_uri_t *uri, const char *username) -{ - size_t len; - - BSON_ASSERT (username); - - len = strlen (username); - - if (!bson_utf8_validate (username, len, false)) { - return false; - } - - if (uri->username) { - bson_free (uri->username); - } - - uri->username = bson_strdup (username); - return true; -} - - -const char * -mongoc_uri_get_password (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - - return uri->password; -} - -bool -mongoc_uri_set_password (mongoc_uri_t *uri, const char *password) -{ - size_t len; - - BSON_ASSERT (password); - - len = strlen (password); - - if (!bson_utf8_validate (password, len, false)) { - return false; - } - - if (uri->password) { - bson_free (uri->password); - } - - uri->password = bson_strdup (password); - return true; -} - - -const char * -mongoc_uri_get_database (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - return uri->database; -} - -bool -mongoc_uri_set_database (mongoc_uri_t *uri, const char *database) -{ - size_t len; - - BSON_ASSERT (database); - - len = strlen (database); - - if (!bson_utf8_validate (database, len, false)) { - return false; - } - - if (uri->database) { - bson_free (uri->database); - } - - uri->database = bson_strdup (database); - return true; -} - - -const char * -mongoc_uri_get_auth_source (const mongoc_uri_t *uri) -{ - bson_iter_t iter; - const char *mechanism; - - BSON_ASSERT (uri); - - if (bson_iter_init_find_case ( - &iter, &uri->credentials, MONGOC_URI_AUTHSOURCE)) { - return bson_iter_utf8 (&iter, NULL); - } - - /* Auth spec: - * "For GSSAPI and MONGODB-X509 authMechanisms the authSource defaults to - * $external. For PLAIN the authSource defaults to the database name if - * supplied on the connection string or $external. For MONGODB-CR, - * SCRAM-SHA-1 and SCRAM-SHA-256 authMechanisms, the authSource defaults to - * the database name if supplied on the connection string or admin." - */ - mechanism = mongoc_uri_get_auth_mechanism (uri); - if (mechanism) { - if (!strcasecmp (mechanism, "GSSAPI") || - !strcasecmp (mechanism, "MONGODB-X509")) { - return "$external"; - } - if (!strcasecmp (mechanism, "PLAIN")) { - return uri->database ? uri->database : "$external"; - } - } - - return uri->database ? uri->database : "admin"; -} - - -bool -mongoc_uri_set_auth_source (mongoc_uri_t *uri, const char *value) -{ - size_t len; - - BSON_ASSERT (value); - - len = strlen (value); - - if (!bson_utf8_validate (value, len, false)) { - return false; - } - - mongoc_uri_bson_append_or_replace_key ( - &uri->credentials, MONGOC_URI_AUTHSOURCE, value); - - return true; -} - - -const char * -mongoc_uri_get_appname (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - - return mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_APPNAME, NULL); -} - - -bool -mongoc_uri_set_appname (mongoc_uri_t *uri, const char *value) -{ - BSON_ASSERT (value); - - if (!bson_utf8_validate (value, strlen (value), false)) { - return false; - } - - if (!_mongoc_handshake_appname_is_valid (value)) { - return false; - } - - mongoc_uri_bson_append_or_replace_key ( - &uri->options, MONGOC_URI_APPNAME, value); - - return true; -} - -bool -mongoc_uri_set_compressors (mongoc_uri_t *uri, const char *value) -{ - const char *end_compressor; - char *entry; - - bson_destroy (&uri->compressors); - bson_init (&uri->compressors); - - if (value && !bson_utf8_validate (value, strlen (value), false)) { - return false; - } - while ((entry = scan_to_unichar (value, ',', "", &end_compressor))) { - if (mongoc_compressor_supported (entry)) { - mongoc_uri_bson_append_or_replace_key ( - &uri->compressors, entry, "yes"); - } else { - MONGOC_WARNING ("Unsupported compressor: '%s'", entry); - } - value = end_compressor + 1; - bson_free (entry); - } - if (value) { - if (mongoc_compressor_supported (value)) { - mongoc_uri_bson_append_or_replace_key ( - &uri->compressors, value, "yes"); - } else { - MONGOC_WARNING ("Unsupported compressor: '%s'", value); - } - } - - return true; -} - -const bson_t * -mongoc_uri_get_compressors (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - return &uri->compressors; -} - - -/* can't use mongoc_uri_get_option_as_int32, it treats 0 specially */ -int32_t -mongoc_uri_get_local_threshold_option (const mongoc_uri_t *uri) -{ - const bson_t *options; - bson_iter_t iter; - int32_t retval = MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS; - - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, "localthresholdms") && - BSON_ITER_HOLDS_INT32 (&iter)) { - retval = bson_iter_int32 (&iter); - - if (retval < 0) { - MONGOC_WARNING ("Invalid localThresholdMS: %d", retval); - retval = MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS; - } - } - - return retval; -} - - -const char * -mongoc_uri_get_service (const mongoc_uri_t *uri) -{ - if (uri->is_srv) { - return uri->srv; - } - - return NULL; -} - - -const bson_t * -mongoc_uri_get_options (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - return &uri->options; -} - - -void -mongoc_uri_destroy (mongoc_uri_t *uri) -{ - if (uri) { - _mongoc_host_list_destroy_all (uri->hosts); - bson_free (uri->str); - bson_free (uri->database); - bson_free (uri->username); - bson_destroy (&uri->raw); - bson_destroy (&uri->options); - bson_destroy (&uri->credentials); - bson_destroy (&uri->compressors); - mongoc_read_prefs_destroy (uri->read_prefs); - mongoc_read_concern_destroy (uri->read_concern); - mongoc_write_concern_destroy (uri->write_concern); - - if (uri->password) { - bson_zero_free (uri->password, strlen (uri->password)); - } - - bson_free (uri); - } -} - - -mongoc_uri_t * -mongoc_uri_copy (const mongoc_uri_t *uri) -{ - mongoc_uri_t *copy; - mongoc_host_list_t *iter; - bson_error_t error; - - BSON_ASSERT (uri); - - copy = (mongoc_uri_t *) bson_malloc0 (sizeof (*copy)); - - copy->str = bson_strdup (uri->str); - copy->is_srv = uri->is_srv; - bson_strncpy (copy->srv, uri->srv, sizeof uri->srv); - copy->username = bson_strdup (uri->username); - copy->password = bson_strdup (uri->password); - copy->database = bson_strdup (uri->database); - - copy->read_prefs = mongoc_read_prefs_copy (uri->read_prefs); - copy->read_concern = mongoc_read_concern_copy (uri->read_concern); - copy->write_concern = mongoc_write_concern_copy (uri->write_concern); - - LL_FOREACH (uri->hosts, iter) - { - if (!mongoc_uri_upsert_host (copy, iter->host, iter->port, &error)) { - MONGOC_ERROR ("%s", error.message); - mongoc_uri_destroy (copy); - return NULL; - } - } - - bson_copy_to (&uri->raw, ©->raw); - bson_copy_to (&uri->options, ©->options); - bson_copy_to (&uri->credentials, ©->credentials); - bson_copy_to (&uri->compressors, ©->compressors); - - return copy; -} - - -const char * -mongoc_uri_get_string (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - return uri->str; -} - - -const bson_t * -mongoc_uri_get_read_prefs (const mongoc_uri_t *uri) -{ - BSON_ASSERT (uri); - return mongoc_read_prefs_get_tags (uri->read_prefs); -} - -char * -mongoc_uri_unescape (const char *escaped_string) -{ - bson_unichar_t c; - bson_string_t *str; - unsigned int hex = 0; - const char *ptr; - const char *end; - size_t len; - - BSON_ASSERT (escaped_string); - - len = strlen (escaped_string); - - /* - * Double check that this is a UTF-8 valid string. Bail out if necessary. - */ - if (!bson_utf8_validate (escaped_string, len, false)) { - MONGOC_WARNING ("%s(): escaped_string contains invalid UTF-8", BSON_FUNC); - return NULL; - } - - ptr = escaped_string; - end = ptr + len; - str = bson_string_new (NULL); - - for (; *ptr; ptr = bson_utf8_next_char (ptr)) { - c = bson_utf8_get_char (ptr); - switch (c) { - case '%': - if (((end - ptr) < 2) || !isxdigit (ptr[1]) || !isxdigit (ptr[2]) || -#ifdef _MSC_VER - (1 != sscanf_s (&ptr[1], "%02x", &hex)) || -#else - (1 != sscanf (&ptr[1], "%02x", &hex)) || -#endif - !isprint (hex)) { - bson_string_free (str, true); - MONGOC_WARNING ("Invalid %% escape sequence"); - return NULL; - } - bson_string_append_c (str, hex); - ptr += 2; - break; - default: - bson_string_append_unichar (str, c); - break; - } - } - - return bson_string_free (str, false); -} - - -const mongoc_read_prefs_t * -mongoc_uri_get_read_prefs_t (const mongoc_uri_t *uri) /* IN */ -{ - BSON_ASSERT (uri); - - return uri->read_prefs; -} - - -void -mongoc_uri_set_read_prefs_t (mongoc_uri_t *uri, - const mongoc_read_prefs_t *prefs) -{ - BSON_ASSERT (uri); - BSON_ASSERT (prefs); - - mongoc_read_prefs_destroy (uri->read_prefs); - uri->read_prefs = mongoc_read_prefs_copy (prefs); -} - - -const mongoc_read_concern_t * -mongoc_uri_get_read_concern (const mongoc_uri_t *uri) /* IN */ -{ - BSON_ASSERT (uri); - - return uri->read_concern; -} - - -void -mongoc_uri_set_read_concern (mongoc_uri_t *uri, const mongoc_read_concern_t *rc) -{ - BSON_ASSERT (uri); - BSON_ASSERT (rc); - - mongoc_read_concern_destroy (uri->read_concern); - uri->read_concern = mongoc_read_concern_copy (rc); -} - - -const mongoc_write_concern_t * -mongoc_uri_get_write_concern (const mongoc_uri_t *uri) /* IN */ -{ - BSON_ASSERT (uri); - - return uri->write_concern; -} - - -void -mongoc_uri_set_write_concern (mongoc_uri_t *uri, - const mongoc_write_concern_t *wc) -{ - BSON_ASSERT (uri); - BSON_ASSERT (wc); - - mongoc_write_concern_destroy (uri->write_concern); - uri->write_concern = mongoc_write_concern_copy (wc); -} - - -bool -mongoc_uri_get_tls (const mongoc_uri_t *uri) /* IN */ -{ - bson_iter_t iter; - - BSON_ASSERT (uri); - - if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_TLS) && - BSON_ITER_HOLDS_BOOL (&iter)) { - return bson_iter_bool (&iter); - } - if (bson_has_field (&uri->options, MONGOC_URI_TLSCERTIFICATEKEYFILE) || - bson_has_field (&uri->options, MONGOC_URI_TLSCAFILE) || - bson_has_field (&uri->options, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) || - bson_has_field (&uri->options, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES)) { - return true; - } - - return false; -} - -bool -mongoc_uri_get_ssl (const mongoc_uri_t *uri) /* IN */ -{ - return mongoc_uri_get_tls (uri); -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_get_option_as_int32 -- - * - * Checks if the URI 'option' is set and of correct type (int32). - * The special value '0' is considered as "unset". - * This is so users can provide - * sprintf("mongodb://localhost/?option=%d", myvalue) style connection - * strings, and still apply default values. - * - * If not set, or set to invalid type, 'fallback' is returned. - * - * NOTE: 'option' is case*in*sensitive. - * - * Returns: - * The value of 'option' if available as int32 (and not 0), or - * 'fallback'. - * - *-------------------------------------------------------------------------- - */ - -int32_t -mongoc_uri_get_option_as_int32 (const mongoc_uri_t *uri, - const char *option_orig, - int32_t fallback) -{ - const char *option; - const bson_t *options; - bson_iter_t iter; - int64_t retval = 0; - - option = mongoc_uri_canonicalize_option (option_orig); - - /* BC layer to allow retrieving 32-bit values stored in 64-bit options */ - if (mongoc_uri_option_is_int64 (option_orig)) { - retval = mongoc_uri_get_option_as_int64 (uri, option_orig, 0); - - if (retval > INT32_MAX || retval < INT32_MIN) { - MONGOC_WARNING ("Cannot read 64-bit value for \"%s\": %" PRId64, - option_orig, - retval); - - retval = 0; - } - } else if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, option) && - BSON_ITER_HOLDS_INT32 (&iter)) { - retval = bson_iter_int32 (&iter); - } - - if (!retval) { - retval = fallback; - } - - return (int32_t) retval; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_set_option_as_int32 -- - * - * Sets a URI option 'after the fact'. Allows users to set individual - * URI options without passing them as a connection string. - * - * Only allows a set of known options to be set. - * @see mongoc_uri_option_is_int32 (). - * - * Does in-place-update of the option BSON if 'option' is already set. - * Appends the option to the end otherwise. - * - * NOTE: If 'option' is already set, and is of invalid type, this - * function will return false. - * - * NOTE: 'option' is case*in*sensitive. - * - * Returns: - * true on successfully setting the option, false on failure. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri, - const char *option_orig, - int32_t value) -{ - const char *option; - bson_error_t error; - bool r; - - if (mongoc_uri_option_is_int64 (option_orig)) { - return mongoc_uri_set_option_as_int64 (uri, option_orig, value); - } - - option = mongoc_uri_canonicalize_option (option_orig); - - if (!mongoc_uri_option_is_int32 (option)) { - MONGOC_WARNING ( - "Unsupported value for \"%s\": %d, \"%s\" is not an int32 option", - option_orig, - value, - option); - return false; - } - - r = _mongoc_uri_set_option_as_int32_with_error (uri, option, value, &error); - if (!r) { - MONGOC_WARNING ("%s", error.message); - } - - return r; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_uri_set_option_as_int32_with_error -- - * - * Same as mongoc_uri_set_option_as_int32, with error reporting. - * - * Precondition: - * mongoc_uri_option_is_int32(option) must be true. - * - * Returns: - * true on successfully setting the option, false on failure. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_uri_set_option_as_int32_with_error (mongoc_uri_t *uri, - const char *option_orig, - int32_t value, - bson_error_t *error) -{ - const char *option; - const bson_t *options; - bson_iter_t iter; - - option = mongoc_uri_canonicalize_option (option_orig); - /* Server Discovery and Monitoring Spec: "the driver MUST NOT permit users - * to configure it less than minHeartbeatFrequencyMS (500ms)." */ - if (!bson_strcasecmp (option, MONGOC_URI_HEARTBEATFREQUENCYMS) && - value < MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS) { - MONGOC_URI_ERROR (error, - "Invalid \"%s\" of %d: must be at least %d", - option_orig, - value, - MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS); - return false; - } - - /* zlib levels are from -1 (default) through 9 (best compression) */ - if (!bson_strcasecmp (option, MONGOC_URI_ZLIBCOMPRESSIONLEVEL) && - (value < -1 || value > 9)) { - MONGOC_URI_ERROR (error, - "Invalid \"%s\" of %d: must be between -1 and 9", - option_orig, - value); - return false; - } - - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, option)) { - if (BSON_ITER_HOLDS_INT32 (&iter)) { - bson_iter_overwrite_int32 (&iter, value); - return true; - } else { - MONGOC_URI_ERROR (error, - "Cannot set URI option \"%s\" to %d, it already has " - "a non-32-bit integer value", - option, - value); - return false; - } - } - - if (!bson_append_int32 (&uri->options, option, -1, value)) { - MONGOC_URI_ERROR ( - error, "Failed to set URI option \"%s\" to %d", option_orig, value); - - return false; - } - - return true; -} - - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_uri_set_option_as_int32 -- - * - * Same as mongoc_uri_set_option_as_int32, except the option is not - * validated against valid int32 options - * - * Returns: - * true on successfully setting the option, false on failure. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri, - const char *option_orig, - int32_t value) -{ - const char *option; - const bson_t *options; - bson_iter_t iter; - - option = mongoc_uri_canonicalize_option (option_orig); - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, option)) { - if (BSON_ITER_HOLDS_INT32 (&iter)) { - bson_iter_overwrite_int32 (&iter, value); - return true; - } else { - return false; - } - } - - bson_append_int32 (&uri->options, option, -1, value); - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_get_option_as_int64 -- - * - * Checks if the URI 'option' is set and of correct type (int32 or - * int64). - * The special value '0' is considered as "unset". - * This is so users can provide - * sprintf("mongodb://localhost/?option=%" PRId64, myvalue) style - * connection strings, and still apply default values. - * - * If not set, or set to invalid type, 'fallback' is returned. - * - * NOTE: 'option' is case*in*sensitive. - * - * Returns: - * The value of 'option' if available as int64 or int32 (and not 0), or - * 'fallback'. - * - *-------------------------------------------------------------------------- - */ - -int64_t -mongoc_uri_get_option_as_int64 (const mongoc_uri_t *uri, - const char *option_orig, - int64_t fallback) -{ - const char *option; - const bson_t *options; - bson_iter_t iter; - int64_t retval = fallback; - - option = mongoc_uri_canonicalize_option (option_orig); - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, option)) { - if (BSON_ITER_HOLDS_INT (&iter)) { - if (!(retval = bson_iter_as_int64 (&iter))) { - retval = fallback; - } - } - } - - return retval; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_set_option_as_int64 -- - * - * Sets a URI option 'after the fact'. Allows users to set individual - * URI options without passing them as a connection string. - * - * Only allows a set of known options to be set. - * @see mongoc_uri_option_is_int64 (). - * - * Does in-place-update of the option BSON if 'option' is already set. - * Appends the option to the end otherwise. - * - * NOTE: If 'option' is already set, and is of invalid type, this - * function will return false. - * - * NOTE: 'option' is case*in*sensitive. - * - * Returns: - * true on successfully setting the option, false on failure. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_uri_set_option_as_int64 (mongoc_uri_t *uri, - const char *option_orig, - int64_t value) -{ - const char *option; - bson_error_t error; - bool r; - - option = mongoc_uri_canonicalize_option (option_orig); - if (!mongoc_uri_option_is_int64 (option)) { - if (mongoc_uri_option_is_int32 (option_orig)) { - if (value >= INT32_MIN && value <= INT32_MAX) { - MONGOC_WARNING ( - "Setting value for 32-bit option \"%s\" through 64-bit method", - option_orig); - - return mongoc_uri_set_option_as_int32 ( - uri, option_orig, (int32_t) value); - } - - MONGOC_WARNING ("Unsupported value for \"%s\": %" PRId64 - ", \"%s\" is not an int64 option", - option_orig, - value, - option); - return false; - } - } - - r = _mongoc_uri_set_option_as_int64_with_error (uri, option, value, &error); - if (!r) { - MONGOC_WARNING ("%s", error.message); - } - - return r; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_uri_set_option_as_int64_with_error -- - * - * Same as mongoc_uri_set_option_as_int64, with error reporting. - * - * Precondition: - * mongoc_uri_option_is_int64(option) must be true. - * - * Returns: - * true on successfully setting the option, false on failure. - * - *-------------------------------------------------------------------------- - */ - -static bool -_mongoc_uri_set_option_as_int64_with_error (mongoc_uri_t *uri, - const char *option_orig, - int64_t value, - bson_error_t *error) -{ - const char *option; - const bson_t *options; - bson_iter_t iter; - - option = mongoc_uri_canonicalize_option (option_orig); - - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, option)) { - if (BSON_ITER_HOLDS_INT64 (&iter)) { - bson_iter_overwrite_int64 (&iter, value); - return true; - } else { - MONGOC_URI_ERROR (error, - "Cannot set URI option \"%s\" to %" PRId64 - ", it already has " - "a non-64-bit integer value", - option, - value); - return false; - } - } - - if (!bson_append_int64 (&uri->options, option, -1, value)) { - MONGOC_URI_ERROR (error, - "Failed to set URI option \"%s\" to %" PRId64, - option_orig, - value); - - return false; - } - - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_get_option_as_bool -- - * - * Checks if the URI 'option' is set and of correct type (bool). - * - * If not set, or set to invalid type, 'fallback' is returned. - * - * NOTE: 'option' is case*in*sensitive. - * - * Returns: - * The value of 'option' if available as bool, or 'fallback'. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri, - const char *option_orig, - bool fallback) -{ - const char *option; - const bson_t *options; - bson_iter_t iter; - - option = mongoc_uri_canonicalize_option (option_orig); - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, option) && - BSON_ITER_HOLDS_BOOL (&iter)) { - return bson_iter_bool (&iter); - } - - return fallback; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_set_option_as_bool -- - * - * Sets a URI option 'after the fact'. Allows users to set individual - * URI options without passing them as a connection string. - * - * Only allows a set of known options to be set. - * @see mongoc_uri_option_is_bool (). - * - * Does in-place-update of the option BSON if 'option' is already set. - * Appends the option to the end otherwise. - * - * NOTE: If 'option' is already set, and is of invalid type, this - * function will return false. - * - * NOTE: 'option' is case*in*sensitive. - * - * Returns: - * true on successfully setting the option, false on failure. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_uri_set_option_as_bool (mongoc_uri_t *uri, - const char *option_orig, - bool value) -{ - const char *option; - const bson_t *options; - bson_iter_t iter; - - option = mongoc_uri_canonicalize_option (option_orig); - BSON_ASSERT (option); - - if (!mongoc_uri_option_is_bool (option)) { - return false; - } - - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, option)) { - if (BSON_ITER_HOLDS_BOOL (&iter)) { - bson_iter_overwrite_bool (&iter, value); - return true; - } else { - return false; - } - } - - bson_append_bool (&uri->options, option, -1, value); - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_get_option_as_utf8 -- - * - * Checks if the URI 'option' is set and of correct type (utf8). - * - * If not set, or set to invalid type, 'fallback' is returned. - * - * NOTE: 'option' is case*in*sensitive. - * - * Returns: - * The value of 'option' if available as utf8, or 'fallback'. - * - *-------------------------------------------------------------------------- - */ - -const char * -mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri, - const char *option_orig, - const char *fallback) -{ - const char *option; - const bson_t *options; - bson_iter_t iter; - - option = mongoc_uri_canonicalize_option (option_orig); - if ((options = mongoc_uri_get_options (uri)) && - bson_iter_init_find_case (&iter, options, option) && - BSON_ITER_HOLDS_UTF8 (&iter)) { - return bson_iter_utf8 (&iter, NULL); - } - - return fallback; -} - -/* - *-------------------------------------------------------------------------- - * - * mongoc_uri_set_option_as_utf8 -- - * - * Sets a URI option 'after the fact'. Allows users to set individual - * URI options without passing them as a connection string. - * - * Only allows a set of known options to be set. - * @see mongoc_uri_option_is_utf8 (). - * - * If the option is not already set, this function will append it to - *the end of the options bson. NOTE: If the option is already set the entire - *options bson will be overwritten, containing the new option=value - *(at the same position). - * - * NOTE: If 'option' is already set, and is of invalid type, this - * function will return false. - * - * NOTE: 'option' must be valid utf8. - * - * NOTE: 'option' is case*in*sensitive. - * - * Returns: - * true on successfully setting the option, false on failure. - * - *-------------------------------------------------------------------------- - */ - -bool -mongoc_uri_set_option_as_utf8 (mongoc_uri_t *uri, - const char *option_orig, - const char *value) -{ - const char *option; - size_t len; - - option = mongoc_uri_canonicalize_option (option_orig); - BSON_ASSERT (option); - - len = strlen (value); - - if (!bson_utf8_validate (value, len, false)) { - return false; - } - - if (!mongoc_uri_option_is_utf8 (option)) { - return false; - } - if (!bson_strcasecmp (option, MONGOC_URI_APPNAME)) { - return mongoc_uri_set_appname (uri, value); - } else { - mongoc_uri_bson_append_or_replace_key (&uri->options, option, value); - } - - return true; -} - -/* - *-------------------------------------------------------------------------- - * - * _mongoc_uri_requires_auth_negotiation -- - * - * Returns true if auth mechanism is necessary for this uri. According - * to the auth spec: "If an application provides a username but does - * not provide an authentication mechanism, drivers MUST negotiate a - * mechanism". - * - * Returns: - * true if the driver should negotiate the auth mechanism for the uri - * - *-------------------------------------------------------------------------- - */ -bool -_mongoc_uri_requires_auth_negotiation (const mongoc_uri_t *uri) -{ - return mongoc_uri_get_username (uri) && !mongoc_uri_get_auth_mechanism (uri); -} - - -/* A bit of a hack. Needed for multi mongos tests to create a URI with the same - * auth, SSL, and compressors settings but with only one specific host. */ -mongoc_uri_t * -_mongoc_uri_copy_and_replace_host_list (const mongoc_uri_t *original, - const char *host) -{ - mongoc_uri_t *uri = mongoc_uri_copy (original); - _mongoc_host_list_destroy_all (uri->hosts); - uri->hosts = bson_malloc0 (sizeof (mongoc_host_list_t)); - _mongoc_host_list_from_string (uri->hosts, host); - return uri; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-uri.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-uri.h deleted file mode 100644 index 1b98764f2e91ac4201fc00ca3c2960e3a611d1f2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-uri.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_URI_H -#define MONGOC_URI_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-host-list.h" -#include "mongoc/mongoc-read-prefs.h" -#include "mongoc/mongoc-read-concern.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-config.h" - - -#ifndef MONGOC_DEFAULT_PORT -#define MONGOC_DEFAULT_PORT 27017 -#endif - -#define MONGOC_URI_APPNAME "appname" -#define MONGOC_URI_AUTHMECHANISM "authmechanism" -#define MONGOC_URI_AUTHMECHANISMPROPERTIES "authmechanismproperties" -#define MONGOC_URI_AUTHSOURCE "authsource" -#define MONGOC_URI_CANONICALIZEHOSTNAME "canonicalizehostname" -#define MONGOC_URI_CONNECTTIMEOUTMS "connecttimeoutms" -#define MONGOC_URI_COMPRESSORS "compressors" -#define MONGOC_URI_GSSAPISERVICENAME "gssapiservicename" -#define MONGOC_URI_HEARTBEATFREQUENCYMS "heartbeatfrequencyms" -#define MONGOC_URI_JOURNAL "journal" -#define MONGOC_URI_LOCALTHRESHOLDMS "localthresholdms" -#define MONGOC_URI_MAXIDLETIMEMS "maxidletimems" -#define MONGOC_URI_MAXPOOLSIZE "maxpoolsize" -#define MONGOC_URI_MAXSTALENESSSECONDS "maxstalenessseconds" -#define MONGOC_URI_MINPOOLSIZE "minpoolsize" -#define MONGOC_URI_READCONCERNLEVEL "readconcernlevel" -#define MONGOC_URI_READPREFERENCE "readpreference" -#define MONGOC_URI_READPREFERENCETAGS "readpreferencetags" -#define MONGOC_URI_REPLICASET "replicaset" -#define MONGOC_URI_RETRYREADS "retryreads" -#define MONGOC_URI_RETRYWRITES "retrywrites" -#define MONGOC_URI_SAFE "safe" -#define MONGOC_URI_SERVERSELECTIONTIMEOUTMS "serverselectiontimeoutms" -#define MONGOC_URI_SERVERSELECTIONTRYONCE "serverselectiontryonce" -#define MONGOC_URI_SLAVEOK "slaveok" -#define MONGOC_URI_SOCKETCHECKINTERVALMS "socketcheckintervalms" -#define MONGOC_URI_SOCKETTIMEOUTMS "sockettimeoutms" -#define MONGOC_URI_TLS "tls" -#define MONGOC_URI_TLSCERTIFICATEKEYFILE "tlscertificatekeyfile" -#define MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD "tlscertificatekeyfilepassword" -#define MONGOC_URI_TLSCAFILE "tlscafile" -#define MONGOC_URI_TLSALLOWINVALIDCERTIFICATES "tlsallowinvalidcertificates" -#define MONGOC_URI_TLSALLOWINVALIDHOSTNAMES "tlsallowinvalidhostnames" -#define MONGOC_URI_TLSINSECURE "tlsinsecure" -#define MONGOC_URI_W "w" -#define MONGOC_URI_WAITQUEUEMULTIPLE "waitqueuemultiple" -#define MONGOC_URI_WAITQUEUETIMEOUTMS "waitqueuetimeoutms" -#define MONGOC_URI_WTIMEOUTMS "wtimeoutms" -#define MONGOC_URI_ZLIBCOMPRESSIONLEVEL "zlibcompressionlevel" - -/* Deprecated in MongoDB 4.2, use "tls" variants instead. */ -#define MONGOC_URI_SSL "ssl" -#define MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE "sslclientcertificatekeyfile" -#define MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD \ - "sslclientcertificatekeypassword" -#define MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE "sslcertificateauthorityfile" -#define MONGOC_URI_SSLALLOWINVALIDCERTIFICATES "sslallowinvalidcertificates" -#define MONGOC_URI_SSLALLOWINVALIDHOSTNAMES "sslallowinvalidhostnames" - -BSON_BEGIN_DECLS - - -typedef struct _mongoc_uri_t mongoc_uri_t; - - -MONGOC_EXPORT (mongoc_uri_t *) -mongoc_uri_copy (const mongoc_uri_t *uri); -MONGOC_EXPORT (void) -mongoc_uri_destroy (mongoc_uri_t *uri); -MONGOC_EXPORT (mongoc_uri_t *) -mongoc_uri_new (const char *uri_string) BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (mongoc_uri_t *) -mongoc_uri_new_with_error (const char *uri_string, - bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (mongoc_uri_t *) -mongoc_uri_new_for_host_port (const char *hostname, - uint16_t port) BSON_GNUC_WARN_UNUSED_RESULT; -MONGOC_EXPORT (const mongoc_host_list_t *) -mongoc_uri_get_hosts (const mongoc_uri_t *uri); -MONGOC_EXPORT (const char *) -mongoc_uri_get_service (const mongoc_uri_t *uri); -MONGOC_EXPORT (const char *) -mongoc_uri_get_database (const mongoc_uri_t *uri); -MONGOC_EXPORT (bool) -mongoc_uri_set_database (mongoc_uri_t *uri, const char *database); -MONGOC_EXPORT (const bson_t *) -mongoc_uri_get_compressors (const mongoc_uri_t *uri); -MONGOC_EXPORT (const bson_t *) -mongoc_uri_get_options (const mongoc_uri_t *uri); -MONGOC_EXPORT (const char *) -mongoc_uri_get_password (const mongoc_uri_t *uri); -MONGOC_EXPORT (bool) -mongoc_uri_set_password (mongoc_uri_t *uri, const char *password); -MONGOC_EXPORT (bool) -mongoc_uri_option_is_int32 (const char *key); -MONGOC_EXPORT (bool) -mongoc_uri_option_is_int64 (const char *key); -MONGOC_EXPORT (bool) -mongoc_uri_option_is_bool (const char *key); -MONGOC_EXPORT (bool) -mongoc_uri_option_is_utf8 (const char *key); -MONGOC_EXPORT (int32_t) -mongoc_uri_get_option_as_int32 (const mongoc_uri_t *uri, - const char *option, - int32_t fallback); -MONGOC_EXPORT (int64_t) -mongoc_uri_get_option_as_int64 (const mongoc_uri_t *uri, - const char *option, - int64_t fallback); -MONGOC_EXPORT (bool) -mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri, - const char *option, - bool fallback); -MONGOC_EXPORT (const char *) -mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri, - const char *option, - const char *fallback); -MONGOC_EXPORT (bool) -mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri, - const char *option, - int32_t value); -MONGOC_EXPORT (bool) -mongoc_uri_set_option_as_int64 (mongoc_uri_t *uri, - const char *option, - int64_t value); -MONGOC_EXPORT (bool) -mongoc_uri_set_option_as_bool (mongoc_uri_t *uri, - const char *option, - bool value); -MONGOC_EXPORT (bool) -mongoc_uri_set_option_as_utf8 (mongoc_uri_t *uri, - const char *option, - const char *value); -MONGOC_EXPORT (const bson_t *) -mongoc_uri_get_read_prefs (const mongoc_uri_t *uri) - BSON_GNUC_DEPRECATED_FOR (mongoc_uri_get_read_prefs_t); -MONGOC_EXPORT (const char *) -mongoc_uri_get_replica_set (const mongoc_uri_t *uri); -MONGOC_EXPORT (const char *) -mongoc_uri_get_string (const mongoc_uri_t *uri); -MONGOC_EXPORT (const char *) -mongoc_uri_get_username (const mongoc_uri_t *uri); -MONGOC_EXPORT (bool) -mongoc_uri_set_username (mongoc_uri_t *uri, const char *username); -MONGOC_EXPORT (const bson_t *) -mongoc_uri_get_credentials (const mongoc_uri_t *uri); -MONGOC_EXPORT (const char *) -mongoc_uri_get_auth_source (const mongoc_uri_t *uri); -MONGOC_EXPORT (bool) -mongoc_uri_set_auth_source (mongoc_uri_t *uri, const char *value); -MONGOC_EXPORT (const char *) -mongoc_uri_get_appname (const mongoc_uri_t *uri); -MONGOC_EXPORT (bool) -mongoc_uri_set_appname (mongoc_uri_t *uri, const char *value); -MONGOC_EXPORT (bool) -mongoc_uri_set_compressors (mongoc_uri_t *uri, const char *value); -MONGOC_EXPORT (const char *) -mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri); -MONGOC_EXPORT (bool) -mongoc_uri_set_auth_mechanism (mongoc_uri_t *uri, const char *value); -MONGOC_EXPORT (bool) -mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri, - bson_t *properties); -MONGOC_EXPORT (bool) -mongoc_uri_set_mechanism_properties (mongoc_uri_t *uri, - const bson_t *properties); -MONGOC_EXPORT (bool) -mongoc_uri_get_ssl (const mongoc_uri_t *uri) - BSON_GNUC_DEPRECATED_FOR (mongoc_uri_get_tls); -MONGOC_EXPORT (bool) -mongoc_uri_get_tls (const mongoc_uri_t *uri); -MONGOC_EXPORT (char *) -mongoc_uri_unescape (const char *escaped_string); -MONGOC_EXPORT (const mongoc_read_prefs_t *) -mongoc_uri_get_read_prefs_t (const mongoc_uri_t *uri); -MONGOC_EXPORT (void) -mongoc_uri_set_read_prefs_t (mongoc_uri_t *uri, - const mongoc_read_prefs_t *prefs); -MONGOC_EXPORT (const mongoc_write_concern_t *) -mongoc_uri_get_write_concern (const mongoc_uri_t *uri); -MONGOC_EXPORT (void) -mongoc_uri_set_write_concern (mongoc_uri_t *uri, - const mongoc_write_concern_t *wc); -MONGOC_EXPORT (const mongoc_read_concern_t *) -mongoc_uri_get_read_concern (const mongoc_uri_t *uri); -MONGOC_EXPORT (void) -mongoc_uri_set_read_concern (mongoc_uri_t *uri, - const mongoc_read_concern_t *rc); - -BSON_END_DECLS - - -#endif /* MONGOC_URI_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-util-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-util-private.h deleted file mode 100644 index 1fcf27fdf1b5b7e5420b2905e5f13efa5738eff9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-util-private.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_UTIL_PRIVATE_H -#define MONGOC_UTIL_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc.h" - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - -/* string comparison functions for Windows */ -#ifdef _WIN32 -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#endif - -#if BSON_GNUC_CHECK_VERSION(4, 6) -#define BEGIN_IGNORE_DEPRECATIONS \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#define END_IGNORE_DEPRECATIONS _Pragma ("GCC diagnostic pop") -#elif defined(__clang__) -#define BEGIN_IGNORE_DEPRECATIONS \ - _Pragma ("clang diagnostic push") \ - _Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#define END_IGNORE_DEPRECATIONS _Pragma ("clang diagnostic pop") -#else -#define BEGIN_IGNORE_DEPRECATIONS -#define END_IGNORE_DEPRECATIONS -#endif - -#ifndef _WIN32 -#define MONGOC_PRINTF_FORMAT(a, b) __attribute__ ((format (__printf__, a, b))) -#else -#define MONGOC_PRINTF_FORMAT(a, b) /* no-op */ -#endif - -#define COALESCE(x, y) ((x == 0) ? (y) : (x)) - - -/* Helper macros for stringifying things */ -#define MONGOC_STR(s) #s -#define MONGOC_EVALUATE_STR(s) MONGOC_STR (s) - -BSON_BEGIN_DECLS - -extern const bson_validate_flags_t _mongoc_default_insert_vflags; -extern const bson_validate_flags_t _mongoc_default_replace_vflags; -extern const bson_validate_flags_t _mongoc_default_update_vflags; - -int -_mongoc_rand_simple (unsigned int *seed); - -char * -_mongoc_hex_md5 (const char *input); - -void -_mongoc_usleep (int64_t usec); - -const char * -_mongoc_get_command_name (const bson_t *command); - -const char * -_mongoc_get_documents_field_name (const char *command_name); - -bool -_mongoc_lookup_bool (const bson_t *bson, const char *key, bool default_value); - -void -_mongoc_get_db_name (const char *ns, char *db /* OUT */); - -void -_mongoc_bson_init_if_set (bson_t *bson); - -const char * -_mongoc_bson_type_to_str (bson_type_t t); - -bool -_mongoc_get_server_id_from_opts (const bson_t *opts, - mongoc_error_domain_t domain, - mongoc_error_code_t code, - uint32_t *server_id, - bson_error_t *error); - -bool -_mongoc_validate_new_document (const bson_t *insert, - bson_validate_flags_t vflags, - bson_error_t *error); - -bool -_mongoc_validate_replace (const bson_t *insert, - bson_validate_flags_t vflags, - bson_error_t *error); - -bool -_mongoc_validate_update (const bson_t *update, - bson_validate_flags_t vflags, - bson_error_t *error); - -void -mongoc_lowercase (const char *src, char *buf /* OUT */); - -bool -mongoc_parse_port (uint16_t *port, const char *str); - -void -_mongoc_bson_array_add_label (bson_t *bson, const char *label); - -void -_mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst); - -void -_mongoc_bson_init_with_transient_txn_error (const mongoc_client_session_t *cs, - bson_t *reply); - -bool -_mongoc_document_is_pipeline (const bson_t *document); - -BSON_END_DECLS - -#endif /* MONGOC_UTIL_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-util.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-util.c deleted file mode 100644 index 6cfa751118ab7216c119682b92047eea9d1829d3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-util.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright 2013 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. - */ - -#ifdef _WIN32 -#define _CRT_RAND_S -#endif - -#include <string.h> - -#include "common-md5-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-client-session-private.h" -#include "mongoc/mongoc-trace-private.h" - -const bson_validate_flags_t _mongoc_default_insert_vflags = - BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | - BSON_VALIDATE_EMPTY_KEYS | BSON_VALIDATE_DOT_KEYS | - BSON_VALIDATE_DOLLAR_KEYS; - -const bson_validate_flags_t _mongoc_default_replace_vflags = - BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | - BSON_VALIDATE_EMPTY_KEYS | BSON_VALIDATE_DOT_KEYS | - BSON_VALIDATE_DOLLAR_KEYS; - -const bson_validate_flags_t _mongoc_default_update_vflags = - BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | - BSON_VALIDATE_EMPTY_KEYS; - -int -_mongoc_rand_simple (unsigned int *seed) -{ -#ifdef _WIN32 - /* ignore the seed */ - unsigned int ret = 0; - errno_t err; - - err = rand_s (&ret); - if (0 != err) { - MONGOC_ERROR ("rand_s failed: %"); - } - - return (int) ret; -#else - return rand_r (seed); -#endif -} - - -char * -_mongoc_hex_md5 (const char *input) -{ - uint8_t digest[16]; - bson_md5_t md5; - char digest_str[33]; - int i; - - _bson_md5_init (&md5); - _bson_md5_append (&md5, (const uint8_t *) input, (uint32_t) strlen (input)); - _bson_md5_finish (&md5, digest); - - for (i = 0; i < sizeof digest; i++) { - bson_snprintf (&digest_str[i * 2], 3, "%02x", digest[i]); - } - digest_str[sizeof digest_str - 1] = '\0'; - - return bson_strdup (digest_str); -} - - -void -_mongoc_usleep (int64_t usec) -{ -#ifdef _WIN32 - LARGE_INTEGER ft; - HANDLE timer; - - BSON_ASSERT (usec >= 0); - - ft.QuadPart = -(10 * usec); - timer = CreateWaitableTimer (NULL, true, NULL); - SetWaitableTimer (timer, &ft, 0, NULL, NULL, 0); - WaitForSingleObject (timer, INFINITE); - CloseHandle (timer); -#else - BSON_ASSERT (usec >= 0); - usleep ((useconds_t) usec); -#endif -} - - -const char * -_mongoc_get_command_name (const bson_t *command) -{ - bson_iter_t iter; - const char *name; - bson_iter_t child; - const char *wrapper_name = NULL; - - BSON_ASSERT (command); - - if (!bson_iter_init (&iter, command) || !bson_iter_next (&iter)) { - return NULL; - } - - name = bson_iter_key (&iter); - - /* wrapped in "$query" or "query"? - * - * {$query: {count: "collection"}, $readPreference: {...}} - */ - if (name[0] == '$') { - wrapper_name = "$query"; - } else if (!strcmp (name, "query")) { - wrapper_name = "query"; - } - - if (wrapper_name && bson_iter_init_find (&iter, command, wrapper_name) && - BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child) && - bson_iter_next (&child)) { - name = bson_iter_key (&child); - } - - return name; -} - - -const char * -_mongoc_get_documents_field_name (const char *command_name) -{ - if (!strcmp (command_name, "insert")) { - return "documents"; - } - - if (!strcmp (command_name, "update")) { - return "updates"; - } - - if (!strcmp (command_name, "delete")) { - return "deletes"; - } - - return NULL; -} - -bool -_mongoc_lookup_bool (const bson_t *bson, const char *key, bool default_value) -{ - bson_iter_t iter; - bson_iter_t child; - - if (!bson) { - return default_value; - } - - BSON_ASSERT (bson_iter_init (&iter, bson)); - if (!bson_iter_find_descendant (&iter, key, &child)) { - return default_value; - } - - return bson_iter_as_bool (&child); -} - -void -_mongoc_get_db_name (const char *ns, char *db /* OUT */) -{ - size_t dblen; - const char *dot; - - BSON_ASSERT (ns); - - dot = strstr (ns, "."); - - if (dot) { - dblen = BSON_MIN (dot - ns + 1, MONGOC_NAMESPACE_MAX); - bson_strncpy (db, ns, dblen); - } else { - bson_strncpy (db, ns, MONGOC_NAMESPACE_MAX); - } -} - -void -_mongoc_bson_init_if_set (bson_t *bson) -{ - if (bson) { - bson_init (bson); - } -} - -const char * -_mongoc_bson_type_to_str (bson_type_t t) -{ - switch (t) { - case BSON_TYPE_EOD: - return "EOD"; - case BSON_TYPE_DOUBLE: - return "DOUBLE"; - case BSON_TYPE_UTF8: - return "UTF8"; - case BSON_TYPE_DOCUMENT: - return "DOCUMENT"; - case BSON_TYPE_ARRAY: - return "ARRAY"; - case BSON_TYPE_BINARY: - return "BINARY"; - case BSON_TYPE_UNDEFINED: - return "UNDEFINED"; - case BSON_TYPE_OID: - return "OID"; - case BSON_TYPE_BOOL: - return "BOOL"; - case BSON_TYPE_DATE_TIME: - return "DATE_TIME"; - case BSON_TYPE_NULL: - return "NULL"; - case BSON_TYPE_REGEX: - return "REGEX"; - case BSON_TYPE_DBPOINTER: - return "DBPOINTER"; - case BSON_TYPE_CODE: - return "CODE"; - case BSON_TYPE_SYMBOL: - return "SYMBOL"; - case BSON_TYPE_CODEWSCOPE: - return "CODEWSCOPE"; - case BSON_TYPE_INT32: - return "INT32"; - case BSON_TYPE_TIMESTAMP: - return "TIMESTAMP"; - case BSON_TYPE_INT64: - return "INT64"; - case BSON_TYPE_MAXKEY: - return "MAXKEY"; - case BSON_TYPE_MINKEY: - return "MINKEY"; - case BSON_TYPE_DECIMAL128: - return "DECIMAL128"; - default: - return "Unknown"; - } -} - - -/* Get "serverId" from opts. Sets *server_id to the serverId from "opts" or 0 - * if absent. On error, fills out *error with domain and code and return false. - */ -bool -_mongoc_get_server_id_from_opts (const bson_t *opts, - mongoc_error_domain_t domain, - mongoc_error_code_t code, - uint32_t *server_id, - bson_error_t *error) -{ - bson_iter_t iter; - - ENTRY; - - BSON_ASSERT (server_id); - - *server_id = 0; - - if (!opts || !bson_iter_init_find (&iter, opts, "serverId")) { - RETURN (true); - } - - if (!BSON_ITER_HOLDS_INT (&iter)) { - bson_set_error ( - error, domain, code, "The serverId option must be an integer"); - RETURN (false); - } - - if (bson_iter_as_int64 (&iter) <= 0) { - bson_set_error (error, domain, code, "The serverId option must be >= 1"); - RETURN (false); - } - - *server_id = (uint32_t) bson_iter_as_int64 (&iter); - - RETURN (true); -} - - -bool -_mongoc_validate_new_document (const bson_t *doc, - bson_validate_flags_t vflags, - bson_error_t *error) -{ - bson_error_t validate_err; - - if (vflags == BSON_VALIDATE_NONE) { - return true; - } - - if (!bson_validate_with_error (doc, vflags, &validate_err)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document for insert: %s", - validate_err.message); - return false; - } - - return true; -} - - -bool -_mongoc_validate_replace (const bson_t *doc, - bson_validate_flags_t vflags, - bson_error_t *error) -{ - bson_error_t validate_err; - - if (vflags == BSON_VALIDATE_NONE) { - return true; - } - - if (!bson_validate_with_error (doc, vflags, &validate_err)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid argument for replace: %s", - validate_err.message); - return false; - } - - return true; -} - - -bool -_mongoc_validate_update (const bson_t *update, - bson_validate_flags_t vflags, - bson_error_t *error) -{ - bson_error_t validate_err; - bson_iter_t iter; - const char *key; - - if (vflags == BSON_VALIDATE_NONE) { - return true; - } - - if (!bson_validate_with_error (update, vflags, &validate_err)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid argument for update: %s", - validate_err.message); - return false; - } - - if (_mongoc_document_is_pipeline (update)) { - return true; - } - - if (!bson_iter_init (&iter, update)) { - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "update document is corrupt"); - return false; - } - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - if (key[0] != '$') { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid key '%s': update only works with $ operators" - " and pipelines", - key); - - return false; - } - } - - return true; -} - -void -mongoc_lowercase (const char *src, char *buf /* OUT */) -{ - for (; *src; ++src, ++buf) { - /* UTF8 non-ascii characters have a 1 at the leftmost bit. If this is the - * case, just copy */ - if ((*src & (0x1 << 7)) == 0) { - *buf = (char) tolower (*src); - } else { - *buf = *src; - } - } -} - -bool -mongoc_parse_port (uint16_t *port, const char *str) -{ - unsigned long ul_port; - - ul_port = strtoul (str, NULL, 10); - - if (ul_port == 0 || ul_port > UINT16_MAX) { - /* Parse error or port number out of range. mongod prohibits port 0. */ - return false; - } - - *port = (uint16_t) ul_port; - return true; -} - - -/*-------------------------------------------------------------------------- - * - * _mongoc_bson_array_add_label -- - * - * Append an error label like "TransientTransactionError" to a BSON - * array iff the array does not already contain it. - * - * Side effects: - * Aborts if the array is invalid or contains non-string elements. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_bson_array_add_label (bson_t *bson, const char *label) -{ - bson_iter_t iter; - char buf[16]; - uint32_t i = 0; - const char *key; - - BSON_ASSERT (bson_iter_init (&iter, bson)); - while (bson_iter_next (&iter)) { - if (!strcmp (bson_iter_utf8 (&iter, NULL), label)) { - /* already included once */ - return; - } - - i++; - } - - bson_uint32_to_string (i, &key, buf, sizeof buf); - BSON_APPEND_UTF8 (bson, key, label); -} - - -/*-------------------------------------------------------------------------- - * - * _mongoc_bson_array_copy_labels_to -- - * - * Copy error labels like "TransientTransactionError" from a server - * reply to a BSON array iff the array does not already contain it. - * - * Side effects: - * Aborts if @dst is invalid or contains non-string elements. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst) -{ - bson_iter_t iter; - bson_iter_t label; - - if (bson_iter_init_find (&iter, reply, "errorLabels")) { - BSON_ASSERT (bson_iter_recurse (&iter, &label)); - while (bson_iter_next (&label)) { - if (BSON_ITER_HOLDS_UTF8 (&label)) { - _mongoc_bson_array_add_label (dst, bson_iter_utf8 (&label, NULL)); - } - } - } -} - - -/*-------------------------------------------------------------------------- - * - * _mongoc_bson_init_with_transient_txn_error -- - * - * If @reply is not NULL, initialize it. If @cs is not NULL and in a - * transaction, add errorLabels: ["TransientTransactionError"] to @cs. - * - * Transactions Spec: TransientTransactionError includes "server - * selection error encountered running any command besides - * commitTransaction in a transaction. ...in the case of network errors - * or server selection errors where the client receives no server reply, - * the client adds the label." - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -_mongoc_bson_init_with_transient_txn_error (const mongoc_client_session_t *cs, - bson_t *reply) -{ - bson_t labels; - - if (!reply) { - return; - } - - bson_init (reply); - - if (_mongoc_client_session_in_txn (cs)) { - BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels); - BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR); - bson_append_array_end (reply, &labels); - } -} - -bool -_mongoc_document_is_pipeline (const bson_t *document) -{ - bson_iter_t iter; - bson_iter_t child; - const char *key; - int i = 0; - char *i_str; - - if (!bson_iter_init (&iter, document)) { - return false; - } - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - i_str = bson_strdup_printf ("%d", i++); - - if (strcmp (key, i_str)) { - bson_free (i_str); - return false; - } - - bson_free (i_str); - - if (BSON_ITER_HOLDS_DOCUMENT (&iter)) { - if (!bson_iter_recurse (&iter, &child)) { - return false; - } - if (!bson_iter_next (&child)) { - return false; - } - key = bson_iter_key (&child); - if (key[0] != '$') { - return false; - } - } else { - return false; - } - } - - /* should return false when the document is empty */ - return i != 0; -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-version-functions.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-version-functions.c deleted file mode 100644 index ca770bbf6a4edb280ae813122446b078ad8c0871..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-version-functions.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-version.h" -#include "mongoc/mongoc-version-functions.h" - -/** - * mongoc_get_major_version: - * - * Helper function to return the runtime major version of the library. - */ -int -mongoc_get_major_version (void) -{ - return MONGOC_MAJOR_VERSION; -} - - -/** - * mongoc_get_minor_version: - * - * Helper function to return the runtime minor version of the library. - */ -int -mongoc_get_minor_version (void) -{ - return MONGOC_MINOR_VERSION; -} - -/** - * mongoc_get_micro_version: - * - * Helper function to return the runtime micro version of the library. - */ -int -mongoc_get_micro_version (void) -{ - return MONGOC_MICRO_VERSION; -} - -/** - * mongoc_get_version: - * - * Helper function to return the runtime string version of the library. - */ -const char * -mongoc_get_version (void) -{ - return MONGOC_VERSION_S; -} - -/** - * mongoc_check_version: - * - * True if libmongoc's version is greater than or equal to the required - * version. - */ -bool -mongoc_check_version (int required_major, - int required_minor, - int required_micro) -{ - return MONGOC_CHECK_VERSION (required_major, required_minor, required_micro); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-version-functions.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-version-functions.h deleted file mode 100644 index 44745690951fb9157212e47e1ee297055c86b089..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-version-functions.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_VERSION_FUNCTIONS_H -#define MONGOC_VERSION_FUNCTIONS_H - -#include <bson/bson.h> /* for "bool" */ - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - -MONGOC_EXPORT (int) -mongoc_get_major_version (void); -MONGOC_EXPORT (int) -mongoc_get_minor_version (void); -MONGOC_EXPORT (int) -mongoc_get_micro_version (void); -MONGOC_EXPORT (const char *) -mongoc_get_version (void); -MONGOC_EXPORT (bool) -mongoc_check_version (int required_major, - int required_minor, - int required_micro); - -BSON_END_DECLS - -#endif /* MONGOC_VERSION_FUNCTIONS_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-version.h.in b/lib/mongoc/libmongoc/src/mongoc/mongoc-version.h.in deleted file mode 100644 index 8108e892ecd01d2aef4e66a436ee3678b5f6f521..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-version.h.in +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013 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. - */ - - -#if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) -#error "Only <mongoc/mongoc.h> can be included directly." -#endif - - -#ifndef MONGOC_VERSION_H -#define MONGOC_VERSION_H - - -/** - * MONGOC_MAJOR_VERSION: - * - * MONGOC major version component (e.g. 1 if %MONGOC_VERSION is 1.2.3) - */ -#define MONGOC_MAJOR_VERSION (@MONGOC_MAJOR_VERSION@) - - -/** - * MONGOC_MINOR_VERSION: - * - * MONGOC minor version component (e.g. 2 if %MONGOC_VERSION is 1.2.3) - */ -#define MONGOC_MINOR_VERSION (@MONGOC_MINOR_VERSION@) - - -/** - * MONGOC_MICRO_VERSION: - * - * MONGOC micro version component (e.g. 3 if %MONGOC_VERSION is 1.2.3) - */ -#define MONGOC_MICRO_VERSION (@MONGOC_MICRO_VERSION@) - - -/** - * MONGOC_PRERELEASE_VERSION: - * - * MONGOC prerelease version component (e.g. pre if %MONGOC_VERSION is 1.2.3-pre) - */ -#define MONGOC_PRERELEASE_VERSION (@MONGOC_PRERELEASE_VERSION@) - - -/** - * MONGOC_VERSION: - * - * MONGOC version. - */ -#define MONGOC_VERSION (@MONGOC_VERSION@) - - -/** - * MONGOC_VERSION_S: - * - * MONGOC version, encoded as a string, useful for printing and - * concatenation. - */ -#define MONGOC_VERSION_S "@MONGOC_VERSION@" - - -/** - * MONGOC_VERSION_HEX: - * - * MONGOC version, encoded as an hexadecimal number, useful for - * integer comparisons. - */ -#define MONGOC_VERSION_HEX (MONGOC_MAJOR_VERSION << 24 | \ - MONGOC_MINOR_VERSION << 16 | \ - MONGOC_MICRO_VERSION << 8) - - -/** - * MONGOC_CHECK_VERSION: - * @major: required major version - * @minor: required minor version - * @micro: required micro version - * - * Compile-time version checking. Evaluates to %TRUE if the version - * of MONGOC is greater than the required one. - */ -#define MONGOC_CHECK_VERSION(major,minor,micro) \ - (MONGOC_MAJOR_VERSION > (major) || \ - (MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION > (minor)) || \ - (MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION == (minor) && \ - MONGOC_MICRO_VERSION >= (micro))) - -#endif /* MONGOC_VERSION_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h deleted file mode 100644 index 4c688eee169c25f404e19cde054c49930e5edcd7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2014-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 "mongoc/mongoc-prelude.h" - - -#ifndef MONGOC_WRITE_COMMAND_LEGACY_PRIVATE_H -#define MONGOC_WRITE_COMMAND_LEGACY_PRIVATE_H - -#include <bson/bson.h> -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-write-command-private.h" - -BSON_BEGIN_DECLS - -void -_mongoc_write_command_insert_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error); -void -_mongoc_write_command_update_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error); -void -_mongoc_write_command_delete_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error); -BSON_END_DECLS - - -#endif /* MONGOC_WRITE_COMMAND_LEGACY_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-legacy.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-legacy.c deleted file mode 100644 index 1d5318dd14222504d5331b55e3a1aa22c8ace2b9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-legacy.c +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright 2014-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 <bson/bson.h> - -#include "mongoc/mongoc-write-command-legacy-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-util-private.h" - -static void -_mongoc_monitor_legacy_write (mongoc_client_t *client, - mongoc_write_command_t *command, - const char *db, - const char *collection, - mongoc_server_stream_t *stream, - int64_t request_id) -{ - bson_t doc; - bson_t wc; - mongoc_apm_command_started_t event; - - ENTRY; - - if (!client->apm_callbacks.started) { - EXIT; - } - - bson_init (&doc); - _mongoc_write_command_init (&doc, command, collection); - BSON_APPEND_DOCUMENT_BEGIN (&doc, "writeConcern", &wc); - BSON_APPEND_INT32 (&wc, "w", 0); - bson_append_document_end (&doc, &wc); - - _append_array_from_command (command, &doc); - - mongoc_apm_command_started_init ( - &event, - &doc, - db, - _mongoc_command_type_to_name (command->type), - request_id, - command->operation_id, - &stream->sd->host, - stream->sd->id, - client->apm_context); - - client->apm_callbacks.started (&event); - - mongoc_apm_command_started_cleanup (&event); - bson_destroy (&doc); -} - - -/* fire command-succeeded event as if we'd used a modern write command. - * note, cluster.request_id was incremented once for the write, again - * for the getLastError, so cluster.request_id is no longer valid; used the - * passed-in request_id instead. - */ -static void -_mongoc_monitor_legacy_write_succeeded (mongoc_client_t *client, - int64_t duration, - mongoc_write_command_t *command, - mongoc_server_stream_t *stream, - int64_t request_id) -{ - bson_t doc; - - mongoc_apm_command_succeeded_t event; - - ENTRY; - - if (!client->apm_callbacks.succeeded) { - EXIT; - } - - bson_init (&doc); - /* - * Unacknowledged writes must provide a CommandSucceededEvent with a { ok: 1 - * } reply. - * https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#unacknowledged-acknowledged-writes - */ - bson_append_int32 (&doc, "ok", 2, 1); - bson_append_int32 (&doc, "n", 1, (int32_t) command->n_documents); - - mongoc_apm_command_succeeded_init ( - &event, - duration, - &doc, - _mongoc_command_type_to_name (command->type), - request_id, - command->operation_id, - &stream->sd->host, - stream->sd->id, - client->apm_context); - - client->apm_callbacks.succeeded (&event); - - mongoc_apm_command_succeeded_cleanup (&event); - bson_destroy (&doc); - - EXIT; -} - - -void -_mongoc_write_command_delete_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error) -{ - int64_t started; - int32_t max_bson_obj_size; - const uint8_t *data; - mongoc_rpc_t rpc; - uint32_t request_id; - bson_iter_t q_iter; - uint32_t len; - int64_t limit = 0; - char ns[MONGOC_NAMESPACE_MAX + 1]; - bool r; - bson_reader_t *reader; - const bson_t *bson; - bool eof; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - - started = bson_get_monotonic_time (); - - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - - if (!command->n_documents) { - bson_set_error (error, - MONGOC_ERROR_COLLECTION, - MONGOC_ERROR_COLLECTION_DELETE_FAILED, - "Cannot do an empty delete."); - result->failed = true; - EXIT; - } - - bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); - - reader = - bson_reader_new_from_data (command->payload.data, command->payload.len); - while ((bson = bson_reader_read (reader, &eof))) { - /* the document is like { "q": { <selector> }, limit: <0 or 1> } */ - r = (bson_iter_init (&q_iter, bson) && bson_iter_find (&q_iter, "q") && - BSON_ITER_HOLDS_DOCUMENT (&q_iter)); - - BSON_ASSERT (r); - bson_iter_document (&q_iter, &len, &data); - BSON_ASSERT (data); - BSON_ASSERT (len >= 5); - if (len > max_bson_obj_size) { - _mongoc_write_command_too_large_error ( - error, 0, len, max_bson_obj_size); - result->failed = true; - bson_reader_destroy (reader); - EXIT; - } - - request_id = ++client->cluster.request_id; - - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_DELETE; - rpc.delete_.zero = 0; - rpc.delete_.collection = ns; - - if (bson_iter_find (&q_iter, "limit") && - (BSON_ITER_HOLDS_INT (&q_iter))) { - limit = bson_iter_as_int64 (&q_iter); - } - - rpc.delete_.flags = - limit ? MONGOC_DELETE_SINGLE_REMOVE : MONGOC_DELETE_NONE; - rpc.delete_.selector = data; - - _mongoc_monitor_legacy_write ( - client, command, database, collection, server_stream, request_id); - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - &client->cluster, &rpc, server_stream, error)) { - result->failed = true; - bson_reader_destroy (reader); - EXIT; - } - - _mongoc_monitor_legacy_write_succeeded (client, - bson_get_monotonic_time () - - started, - command, - server_stream, - request_id); - - started = bson_get_monotonic_time (); - } - bson_reader_destroy (reader); - - EXIT; -} - - -void -_mongoc_write_command_insert_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error) -{ - int64_t started; - mongoc_iovec_t *iov; - mongoc_rpc_t rpc; - uint32_t size = 0; - bool has_more; - char ns[MONGOC_NAMESPACE_MAX + 1]; - uint32_t n_docs_in_batch; - uint32_t request_id = 0; - uint32_t idx = 0; - int32_t max_msg_size; - int32_t max_bson_obj_size; - bson_reader_t *reader; - const bson_t *bson; - bool eof; - int data_offset = 0; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT); - - started = bson_get_monotonic_time (); - - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - max_msg_size = mongoc_server_stream_max_msg_size (server_stream); - - if (!command->n_documents) { - bson_set_error (error, - MONGOC_ERROR_COLLECTION, - MONGOC_ERROR_COLLECTION_INSERT_FAILED, - "Cannot do an empty insert."); - result->failed = true; - EXIT; - } - - bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); - - iov = (mongoc_iovec_t *) bson_malloc ((sizeof *iov) * command->n_documents); - -again: - has_more = false; - n_docs_in_batch = 0; - size = (uint32_t) (sizeof (mongoc_rpc_header_t) + 4 + strlen (database) + 1 + - strlen (collection) + 1); - - reader = bson_reader_new_from_data (command->payload.data + data_offset, - command->payload.len - data_offset); - while ((bson = bson_reader_read (reader, &eof))) { - BSON_ASSERT (n_docs_in_batch <= idx); - BSON_ASSERT (idx <= command->n_documents); - - if (bson->len > max_bson_obj_size) { - /* document is too large */ - _mongoc_write_command_too_large_error ( - error, idx, bson->len, max_bson_obj_size); - - data_offset += bson->len; - - if (command->flags.ordered) { - /* send the batch so far (if any) and return the error */ - break; - } - } else if (size > (max_msg_size - bson->len)) { - /* batch is full, send it and then start the next batch */ - has_more = true; - break; - } else { - /* add document to batch and continue building the batch */ - iov[n_docs_in_batch].iov_base = (void *) bson_get_data (bson); - iov[n_docs_in_batch].iov_len = bson->len; - size += bson->len; - n_docs_in_batch++; - data_offset += bson->len; - } - - idx++; - } - bson_reader_destroy (reader); - - if (n_docs_in_batch) { - request_id = ++client->cluster.request_id; - - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_INSERT; - rpc.insert.flags = - ((command->flags.ordered) ? MONGOC_INSERT_NONE - : MONGOC_INSERT_CONTINUE_ON_ERROR); - rpc.insert.collection = ns; - rpc.insert.documents = iov; - rpc.insert.n_documents = n_docs_in_batch; - - _mongoc_monitor_legacy_write ( - client, command, database, collection, server_stream, request_id); - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - &client->cluster, &rpc, server_stream, error)) { - result->failed = true; - GOTO (cleanup); - } - - _mongoc_monitor_legacy_write_succeeded (client, - bson_get_monotonic_time () - - started, - command, - server_stream, - request_id); - - started = bson_get_monotonic_time (); - } - -cleanup: - - if (has_more) { - GOTO (again); - } - - bson_free (iov); - - EXIT; -} - - -void -_mongoc_write_command_update_legacy (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error) -{ - int64_t started; - int32_t max_bson_obj_size; - mongoc_rpc_t rpc; - uint32_t request_id = 0; - bson_iter_t subiter, subsubiter; - bson_t doc; - bson_t update, selector; - const uint8_t *data = NULL; - uint32_t len = 0; - size_t err_offset; - bool val = false; - char ns[MONGOC_NAMESPACE_MAX + 1]; - int vflags = (BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | - BSON_VALIDATE_DOLLAR_KEYS | BSON_VALIDATE_DOT_KEYS); - bson_reader_t *reader; - const bson_t *bson; - bool eof; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - - started = bson_get_monotonic_time (); - - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - - reader = - bson_reader_new_from_data (command->payload.data, command->payload.len); - while ((bson = bson_reader_read (reader, &eof))) { - if (bson_iter_init (&subiter, bson) && bson_iter_find (&subiter, "u") && - BSON_ITER_HOLDS_DOCUMENT (&subiter)) { - bson_iter_document (&subiter, &len, &data); - BSON_ASSERT (bson_init_static (&doc, data, len)); - - if (bson_iter_init (&subsubiter, &doc) && - bson_iter_next (&subsubiter) && - (bson_iter_key (&subsubiter)[0] != '$') && - !bson_validate ( - &doc, (bson_validate_flags_t) vflags, &err_offset)) { - result->failed = true; - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "update document is corrupt or contains " - "invalid keys including $ or ."); - bson_reader_destroy (reader); - EXIT; - } - } else { - result->failed = true; - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "updates is malformed."); - bson_reader_destroy (reader); - EXIT; - } - } - - bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); - - bson_reader_destroy (reader); - reader = - bson_reader_new_from_data (command->payload.data, command->payload.len); - while ((bson = bson_reader_read (reader, &eof))) { - request_id = ++client->cluster.request_id; - - rpc.header.msg_len = 0; - rpc.header.request_id = request_id; - rpc.header.response_to = 0; - rpc.header.opcode = MONGOC_OPCODE_UPDATE; - rpc.update.zero = 0; - rpc.update.collection = ns; - rpc.update.flags = MONGOC_UPDATE_NONE; - - BSON_ASSERT (bson_iter_init (&subiter, bson)); - while (bson_iter_next (&subiter)) { - if (strcmp (bson_iter_key (&subiter), "u") == 0) { - bson_iter_document (&subiter, &len, &data); - if (len > max_bson_obj_size) { - _mongoc_write_command_too_large_error ( - error, 0, len, max_bson_obj_size); - result->failed = true; - bson_reader_destroy (reader); - EXIT; - } - - rpc.update.update = data; - BSON_ASSERT (bson_init_static (&update, data, len)); - } else if (strcmp (bson_iter_key (&subiter), "q") == 0) { - bson_iter_document (&subiter, &len, &data); - if (len > max_bson_obj_size) { - _mongoc_write_command_too_large_error ( - error, 0, len, max_bson_obj_size); - result->failed = true; - bson_reader_destroy (reader); - EXIT; - } - - rpc.update.selector = data; - BSON_ASSERT (bson_init_static (&selector, data, len)); - } else if (strcmp (bson_iter_key (&subiter), "multi") == 0) { - val = bson_iter_bool (&subiter); - if (val) { - rpc.update.flags = (mongoc_update_flags_t) ( - rpc.update.flags | MONGOC_UPDATE_MULTI_UPDATE); - } - } else if (strcmp (bson_iter_key (&subiter), "upsert") == 0) { - val = bson_iter_bool (&subiter); - if (val) { - rpc.update.flags = (mongoc_update_flags_t) ( - rpc.update.flags | MONGOC_UPDATE_UPSERT); - } - } - } - - _mongoc_monitor_legacy_write ( - client, command, database, collection, server_stream, request_id); - - if (!mongoc_cluster_legacy_rpc_sendv_to_server ( - &client->cluster, &rpc, server_stream, error)) { - result->failed = true; - bson_reader_destroy (reader); - EXIT; - } - - _mongoc_monitor_legacy_write_succeeded (client, - bson_get_monotonic_time () - - started, - command, - server_stream, - request_id); - - started = bson_get_monotonic_time (); - } - bson_reader_destroy (reader); -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-private.h deleted file mode 100644 index 72227bbb354cd235e3b2ef89eff504c69a3b7eb4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command-private.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2014 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_WRITE_COMMAND_PRIVATE_H -#define MONGOC_WRITE_COMMAND_PRIVATE_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-server-stream-private.h" -#include "mongoc/mongoc-buffer-private.h" - - -BSON_BEGIN_DECLS - -/* forward decl */ -struct _mongoc_crud_opts_t; - -#define MONGOC_WRITE_COMMAND_DELETE 0 -#define MONGOC_WRITE_COMMAND_INSERT 1 -#define MONGOC_WRITE_COMMAND_UPDATE 2 - -/* MongoDB has a extra allowance to allow updating 16mb document, as the update - * operators would otherwise overflow the 16mb object limit. See SERVER-10643 - * for context. */ -#define BSON_OBJECT_ALLOWANCE (16 * 1024) - -struct _mongoc_bulk_write_flags_t { - bool ordered; - bool bypass_document_validation; - bool has_collation; - bool has_multi_write; - bool has_array_filters; -}; - - -typedef struct { - int type; - mongoc_buffer_t payload; - uint32_t n_documents; - mongoc_bulk_write_flags_t flags; - int64_t operation_id; - bson_t cmd_opts; -} mongoc_write_command_t; - - -typedef struct { - uint32_t nInserted; - uint32_t nMatched; - uint32_t nModified; - uint32_t nRemoved; - uint32_t nUpserted; - /* like [{"index": int, "code": int, "errmsg": str}, ...] */ - bson_t writeErrors; - /* like [{"index": int, "_id": value}, ...] */ - bson_t upserted; - uint32_t n_writeConcernErrors; - /* like [{"code": 64, "errmsg": "duplicate"}, ...] */ - bson_t writeConcernErrors; - /* like ["TransientTransactionError", ...] */ - bson_t errorLabels; - bool failed; /* The command failed */ - bool must_stop; /* The stream may have been disconnected */ - bson_error_t error; - uint32_t upsert_append_count; -} mongoc_write_result_t; - - -typedef enum { - MONGOC_WRITE_ERR_NONE, - MONGOC_WRITE_ERR_OTHER, - MONGOC_WRITE_ERR_RETRY, - MONGOC_WRITE_ERR_WRITE_CONCERN, -} mongoc_write_err_type_t; - - -const char * -_mongoc_command_type_to_field_name (int command_type); -const char * -_mongoc_command_type_to_name (int command_type); - -void -_mongoc_write_command_destroy (mongoc_write_command_t *command); -void -_mongoc_write_command_init (bson_t *doc, - mongoc_write_command_t *command, - const char *collection); -void -_mongoc_write_command_init_insert (mongoc_write_command_t *command, - const bson_t *document, - const bson_t *cmd_opts, - mongoc_bulk_write_flags_t flags, - int64_t operation_id); -void -_mongoc_write_command_init_insert_idl (mongoc_write_command_t *command, - const bson_t *document, - const bson_t *cmd_opts, - int64_t operation_id); -void -_mongoc_write_command_init_delete (mongoc_write_command_t *command, - const bson_t *selectors, - const bson_t *cmd_opts, - const bson_t *opts, - mongoc_bulk_write_flags_t flags, - int64_t operation_id); -void -_mongoc_write_command_init_delete_idl (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *cmd_opts, - const bson_t *opts, - int64_t operation_id); -void -_mongoc_write_command_init_update (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - mongoc_bulk_write_flags_t flags, - int64_t operation_id); -void -_mongoc_write_command_init_update_idl (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - int64_t operation_id); -void -_mongoc_write_command_insert_append (mongoc_write_command_t *command, - const bson_t *document); -void -_mongoc_write_command_update_append (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *update, - const bson_t *opts); - -void -_mongoc_write_command_delete_append (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *opts); - -void -_mongoc_write_command_too_large_error (bson_error_t *error, - int32_t idx, - int32_t len, - int32_t max_bson_size); -void -_mongoc_write_command_execute (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - const mongoc_write_concern_t *write_concern, - uint32_t offset, - mongoc_client_session_t *cs, - mongoc_write_result_t *result); -void -_mongoc_write_command_execute_idl (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - const struct _mongoc_crud_opts_t *crud, - mongoc_write_result_t *result); -void -_mongoc_write_result_init (mongoc_write_result_t *result); -void -_mongoc_write_result_append_upsert (mongoc_write_result_t *result, - int32_t idx, - const bson_value_t *value); -int32_t -_mongoc_write_result_merge_arrays (uint32_t offset, - mongoc_write_result_t *result, - bson_t *dest, - bson_iter_t *iter); -void -_mongoc_write_result_merge (mongoc_write_result_t *result, - mongoc_write_command_t *command, - const bson_t *reply, - uint32_t offset); -#define MONGOC_WRITE_RESULT_COMPLETE(_result, ...) \ - _mongoc_write_result_complete (_result, __VA_ARGS__, NULL) -bool -_mongoc_write_result_complete (mongoc_write_result_t *result, - int32_t error_api_version, - const mongoc_write_concern_t *wc, - mongoc_error_domain_t err_domain_override, - bson_t *reply, - bson_error_t *error, - ...); -void -_mongoc_write_result_destroy (mongoc_write_result_t *result); - -void -_append_array_from_command (mongoc_write_command_t *command, bson_t *bson); - -mongoc_write_err_type_t -_mongoc_write_error_get_type (bool cmd_ret, - const bson_error_t *cmd_err, - const bson_t *reply); - -bool -_mongoc_write_error_update_if_unsupported_storage_engine (bool cmd_ret, - bson_error_t *cmd_err, - bson_t *reply); - -BSON_END_DECLS - - -#endif /* MONGOC_WRITE_COMMAND_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command.c deleted file mode 100644 index 8c0b851fbf1d2e1bc213670084247a151e7a0381..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-command.c +++ /dev/null @@ -1,1571 +0,0 @@ -/* - * Copyright 2014 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 <bson/bson.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-client-session-private.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-trace-private.h" -#include "mongoc/mongoc-write-command-private.h" -#include "mongoc/mongoc-write-command-legacy-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-opts-private.h" - - -/* - * TODO: - * - * - Remove error parameter to ops, favor result->error. - */ - -typedef void (*mongoc_write_op_t) (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error); - - -/* indexed by MONGOC_WRITE_COMMAND_DELETE, INSERT, UPDATE */ -static const char *gCommandNames[] = {"delete", "insert", "update"}; -static const char *gCommandFields[] = {"deletes", "documents", "updates"}; -static const uint32_t gCommandFieldLens[] = {7, 9, 7}; - -static mongoc_write_op_t gLegacyWriteOps[3] = { - _mongoc_write_command_delete_legacy, - _mongoc_write_command_insert_legacy, - _mongoc_write_command_update_legacy}; - - -const char * -_mongoc_command_type_to_name (int command_type) -{ - return gCommandNames[command_type]; -} - -const char * -_mongoc_command_type_to_field_name (int command_type) -{ - return gCommandFields[command_type]; -} - -void -_mongoc_write_command_insert_append (mongoc_write_command_t *command, - const bson_t *document) -{ - bson_iter_t iter; - bson_oid_t oid; - bson_t tmp; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT); - BSON_ASSERT (document); - BSON_ASSERT (document->len >= 5); - - /* - * If the document does not contain an "_id" field, we need to generate - * a new oid for "_id". - */ - if (!bson_iter_init_find (&iter, document, "_id")) { - bson_init (&tmp); - bson_oid_init (&oid, NULL); - BSON_APPEND_OID (&tmp, "_id", &oid); - bson_concat (&tmp, document); - _mongoc_buffer_append (&command->payload, bson_get_data (&tmp), tmp.len); - bson_destroy (&tmp); - } else { - _mongoc_buffer_append ( - &command->payload, bson_get_data (document), document->len); - } - - command->n_documents++; - - EXIT; -} - -void -_mongoc_write_command_update_append (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *update, - const bson_t *opts) -{ - bson_t document; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_UPDATE); - BSON_ASSERT (selector && update); - - bson_init (&document); - BSON_APPEND_DOCUMENT (&document, "q", selector); - if (_mongoc_document_is_pipeline (update)) { - BSON_APPEND_ARRAY (&document, "u", update); - } else { - BSON_APPEND_DOCUMENT (&document, "u", update); - } - if (opts) { - bson_concat (&document, opts); - } - - _mongoc_buffer_append ( - &command->payload, bson_get_data (&document), document.len); - command->n_documents++; - - bson_destroy (&document); - - EXIT; -} - -void -_mongoc_write_command_delete_append (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *opts) -{ - bson_t document; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_DELETE); - BSON_ASSERT (selector); - - BSON_ASSERT (selector->len >= 5); - - bson_init (&document); - BSON_APPEND_DOCUMENT (&document, "q", selector); - if (opts) { - bson_concat (&document, opts); - } - - _mongoc_buffer_append ( - &command->payload, bson_get_data (&document), document.len); - command->n_documents++; - - bson_destroy (&document); - - EXIT; -} - -void -_mongoc_write_command_init_bulk (mongoc_write_command_t *command, - int type, - mongoc_bulk_write_flags_t flags, - int64_t operation_id, - const bson_t *opts) -{ - ENTRY; - - BSON_ASSERT (command); - - command->type = type; - command->flags = flags; - command->operation_id = operation_id; - if (!bson_empty0 (opts)) { - bson_copy_to (opts, &command->cmd_opts); - } else { - bson_init (&command->cmd_opts); - } - - _mongoc_buffer_init (&command->payload, NULL, 0, NULL, NULL); - command->n_documents = 0; - - EXIT; -} - - -void -_mongoc_write_command_init_insert (mongoc_write_command_t *command, /* IN */ - const bson_t *document, /* IN */ - const bson_t *cmd_opts, /* IN */ - mongoc_bulk_write_flags_t flags, /* IN */ - int64_t operation_id) /* IN */ -{ - ENTRY; - - BSON_ASSERT (command); - - _mongoc_write_command_init_bulk ( - command, MONGOC_WRITE_COMMAND_INSERT, flags, operation_id, cmd_opts); - - /* must handle NULL document from mongoc_collection_insert_bulk */ - if (document) { - _mongoc_write_command_insert_append (command, document); - } - - EXIT; -} - - -void -_mongoc_write_command_init_insert_idl (mongoc_write_command_t *command, - const bson_t *document, - const bson_t *cmd_opts, - int64_t operation_id) -{ - mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT; - - ENTRY; - - BSON_ASSERT (command); - - _mongoc_write_command_init_bulk ( - command, MONGOC_WRITE_COMMAND_INSERT, flags, operation_id, cmd_opts); - - /* must handle NULL document from mongoc_collection_insert_bulk */ - if (document) { - _mongoc_write_command_insert_append (command, document); - } - - EXIT; -} - - -void -_mongoc_write_command_init_delete (mongoc_write_command_t *command, /* IN */ - const bson_t *selector, /* IN */ - const bson_t *cmd_opts, /* IN */ - const bson_t *opts, /* IN */ - mongoc_bulk_write_flags_t flags, /* IN */ - int64_t operation_id) /* IN */ -{ - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (selector); - - _mongoc_write_command_init_bulk ( - command, MONGOC_WRITE_COMMAND_DELETE, flags, operation_id, cmd_opts); - _mongoc_write_command_delete_append (command, selector, opts); - - EXIT; -} - - -void -_mongoc_write_command_init_delete_idl (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *cmd_opts, - const bson_t *opts, - int64_t operation_id) -{ - mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (selector); - - _mongoc_write_command_init_bulk ( - command, MONGOC_WRITE_COMMAND_DELETE, flags, operation_id, cmd_opts); - - _mongoc_write_command_delete_append (command, selector, opts); - - EXIT; -} - - -void -_mongoc_write_command_init_update (mongoc_write_command_t *command, /* IN */ - const bson_t *selector, /* IN */ - const bson_t *update, /* IN */ - const bson_t *opts, /* IN */ - mongoc_bulk_write_flags_t flags, /* IN */ - int64_t operation_id) /* IN */ -{ - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (selector); - BSON_ASSERT (update); - - _mongoc_write_command_init_bulk ( - command, MONGOC_WRITE_COMMAND_UPDATE, flags, operation_id, NULL); - _mongoc_write_command_update_append (command, selector, update, opts); - - EXIT; -} - - -void -_mongoc_write_command_init_update_idl (mongoc_write_command_t *command, - const bson_t *selector, - const bson_t *update, - const bson_t *opts, - int64_t operation_id) -{ - mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT; - - ENTRY; - - BSON_ASSERT (command); - - _mongoc_write_command_init_bulk ( - command, MONGOC_WRITE_COMMAND_UPDATE, flags, operation_id, NULL); - _mongoc_write_command_update_append (command, selector, update, opts); - - EXIT; -} - - -/* takes initialized bson_t *doc and begins formatting a write command */ -void -_mongoc_write_command_init (bson_t *doc, - mongoc_write_command_t *command, - const char *collection) -{ - ENTRY; - - if (!command->n_documents) { - EXIT; - } - - BSON_APPEND_UTF8 (doc, gCommandNames[command->type], collection); - BSON_APPEND_BOOL (doc, "ordered", command->flags.ordered); - - if (command->flags.bypass_document_validation) { - BSON_APPEND_BOOL (doc, - "bypassDocumentValidation", - command->flags.bypass_document_validation); - } - - EXIT; -} - - -/* - *------------------------------------------------------------------------- - * - * _mongoc_write_command_too_large_error -- - * - * Fill a bson_error_t and optional bson_t with error info after - * receiving a document for bulk insert, update, or remove that is - * larger than max_bson_size. - * - * "err_doc" should be NULL or an empty initialized bson_t. - * - * Returns: - * None. - * - * Side effects: - * "error" and optionally "err_doc" are filled out. - * - *------------------------------------------------------------------------- - */ - -void -_mongoc_write_command_too_large_error (bson_error_t *error, - int32_t idx, - int32_t len, - int32_t max_bson_size) -{ - bson_set_error (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Document %u is too large for the cluster. " - "Document is %u bytes, max is %d.", - idx, - len, - max_bson_size); -} - - -void -_empty_error (mongoc_write_command_t *command, bson_error_t *error) -{ - static const uint32_t codes[] = {MONGOC_ERROR_COLLECTION_DELETE_FAILED, - MONGOC_ERROR_COLLECTION_INSERT_FAILED, - MONGOC_ERROR_COLLECTION_UPDATE_FAILED}; - - bson_set_error (error, - MONGOC_ERROR_COLLECTION, - codes[command->type], - "Cannot do an empty %s", - gCommandNames[command->type]); -} - - -bool -_mongoc_write_command_will_overflow (uint32_t len_so_far, - uint32_t document_len, - uint32_t n_documents_written, - int32_t max_bson_size, - int32_t max_write_batch_size) -{ - /* max BSON object size + 16k bytes. - * server guarantees there is enough room: SERVER-10643 - */ - int32_t max_cmd_size = max_bson_size + BSON_OBJECT_ALLOWANCE; - - BSON_ASSERT (max_bson_size); - - if (len_so_far + document_len > max_cmd_size) { - return true; - } else if (max_write_batch_size > 0 && - n_documents_written >= max_write_batch_size) { - return true; - } - - return false; -} - - -static void -_mongoc_write_opmsg (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - const mongoc_write_concern_t *write_concern, - uint32_t index_offset, - mongoc_client_session_t *cs, - mongoc_write_result_t *result, - bson_error_t *error) -{ - mongoc_cmd_parts_t parts; - bson_iter_t iter; - bson_t cmd; - bson_t reply; - bool ret = false; - int32_t max_msg_size; - int32_t max_bson_obj_size; - int32_t max_document_count; - uint32_t header; - uint32_t payload_batch_size = 0; - uint32_t payload_total_offset = 0; - bool ship_it = false; - int document_count = 0; - int32_t len; - mongoc_server_stream_t *retry_server_stream = NULL; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - max_msg_size = mongoc_server_stream_max_msg_size (server_stream); - if (client->cse_enabled) { - max_msg_size = MONGOC_REDUCED_MAX_MSG_SIZE_FOR_FLE; - } - max_document_count = - mongoc_server_stream_max_write_batch_size (server_stream); - - bson_init (&cmd); - _mongoc_write_command_init (&cmd, command, collection); - mongoc_cmd_parts_init (&parts, client, database, MONGOC_QUERY_NONE, &cmd); - parts.assembled.operation_id = command->operation_id; - parts.is_write_command = true; - if (!mongoc_cmd_parts_set_write_concern ( - &parts, write_concern, server_stream->sd->max_wire_version, error)) { - bson_destroy (&cmd); - mongoc_cmd_parts_cleanup (&parts); - EXIT; - } - - if (parts.assembled.is_acknowledged) { - mongoc_cmd_parts_set_session (&parts, cs); - } - - /* Write commands that include multi-document operations are not retryable. - * Set this explicitly so that mongoc_cmd_parts_assemble does not need to - * inspect the command body later. */ - parts.allow_txn_number = - (command->flags.has_multi_write || !parts.assembled.is_acknowledged) - ? MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_NO - : MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES; - - BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts)); - if (!mongoc_cmd_parts_append_opts ( - &parts, &iter, server_stream->sd->max_wire_version, error)) { - bson_destroy (&cmd); - mongoc_cmd_parts_cleanup (&parts); - EXIT; - } - - if (!mongoc_cmd_parts_assemble (&parts, server_stream, error)) { - bson_destroy (&cmd); - mongoc_cmd_parts_cleanup (&parts); - EXIT; - } - - /* - * OP_MSG header == 16 byte - * + 4 bytes flagBits - * + 1 byte payload type = 1 - * + 1 byte payload type = 2 - * + 4 byte size of payload - * == 26 bytes opcode overhead - * + X Full command document {insert: "test", writeConcern: {...}} - * + Y command identifier ("documents", "deletes", "updates") ( + \0) - */ - - header = - 26 + parts.assembled.command->len + gCommandFieldLens[command->type] + 1; - - do { - memcpy (&len, - command->payload.data + payload_batch_size + payload_total_offset, - 4); - len = BSON_UINT32_FROM_LE (len); - - if (len > max_bson_obj_size + BSON_OBJECT_ALLOWANCE) { - /* Quit if the document is too large */ - _mongoc_write_command_too_large_error ( - error, index_offset, len, max_bson_obj_size); - result->failed = true; - break; - - } else if ((payload_batch_size + header) + len <= max_msg_size) { - /* The current batch is still under max batch size in bytes */ - payload_batch_size += len; - - /* If this document filled the maximum document count */ - if (++document_count == max_document_count) { - ship_it = true; - /* If this document is the last document we have */ - } else if (payload_batch_size + payload_total_offset == - command->payload.len) { - ship_it = true; - } else { - ship_it = false; - } - } else { - ship_it = true; - } - - if (ship_it) { - bool is_retryable = parts.is_retryable_write; - mongoc_write_err_type_t error_type; - - /* Seek past the document offset we have already sent */ - parts.assembled.payload = command->payload.data + payload_total_offset; - /* Only send the documents up to this size */ - parts.assembled.payload_size = payload_batch_size; - parts.assembled.payload_identifier = gCommandFields[command->type]; - - /* increment the transaction number for the first attempt of each - * retryable write command */ - if (is_retryable) { - bson_iter_t txn_number_iter; - BSON_ASSERT (bson_iter_init_find ( - &txn_number_iter, parts.assembled.command, "txnNumber")); - bson_iter_overwrite_int64 ( - &txn_number_iter, - ++parts.assembled.session->server_session->txn_number); - } - retry: - ret = mongoc_cluster_run_command_monitored ( - &client->cluster, &parts.assembled, &reply, error); - - /* Add this batch size so we skip these documents next time */ - payload_total_offset += payload_batch_size; - payload_batch_size = 0; - - /* If a retryable error is encountered and the write is retryable, - * select a new writable stream and retry. If server selection fails or - * the selected server does not support retryable writes, fall through - * and allow the original error to be reported. */ - error_type = _mongoc_write_error_get_type (ret, error, &reply); - if (is_retryable) { - _mongoc_write_error_update_if_unsupported_storage_engine ( - ret, error, &reply); - } - if (is_retryable && error_type == MONGOC_WRITE_ERR_RETRY) { - bson_error_t ignored_error; - - /* each write command may be retried at most once */ - is_retryable = false; - - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } - - retry_server_stream = mongoc_cluster_stream_for_writes ( - &client->cluster, cs, NULL, &ignored_error); - - if (retry_server_stream && - retry_server_stream->sd->max_wire_version >= - WIRE_VERSION_RETRY_WRITES) { - parts.assembled.server_stream = retry_server_stream; - bson_destroy (&reply); - GOTO (retry); - } - } - - if (!ret) { - result->failed = true; - /* Conservatively set must_stop to true. Per CDRIVER-3305 we - * shouldn't stop for unordered bulk writes, but also need to check - * if the server stream was invalidated per CDRIVER-3306. */ - result->must_stop = true; - } - - /* Result merge needs to know the absolute index for a document - * so it can rewrite the error message which contains the relative - * document index per batch - */ - _mongoc_write_result_merge (result, command, &reply, index_offset); - index_offset += document_count; - document_count = 0; - bson_destroy (&reply); - } - /* While we have more documents to write */ - } while (payload_total_offset < command->payload.len && !result->must_stop); - - bson_destroy (&cmd); - mongoc_cmd_parts_cleanup (&parts); - - if (retry_server_stream) { - mongoc_server_stream_cleanup (retry_server_stream); - } - - if (ret) { - /* if a retry succeeded, clear the initial error */ - memset (&result->error, 0, sizeof (bson_error_t)); - } - - EXIT; -} - - -void -_append_array_from_command (mongoc_write_command_t *command, bson_t *bson) -{ - bson_t ar; - bson_reader_t *reader; - char str[16]; - uint32_t i = 0; - const char *key; - bool eof; - const bson_t *current; - - - reader = - bson_reader_new_from_data (command->payload.data, command->payload.len); - - bson_append_array_begin (bson, - gCommandFields[command->type], - gCommandFieldLens[command->type], - &ar); - - while ((current = bson_reader_read (reader, &eof))) { - bson_uint32_to_string (i, &key, str, sizeof str); - BSON_APPEND_DOCUMENT (&ar, key, current); - i++; - } - - bson_append_array_end (bson, &ar); - bson_reader_destroy (reader); -} - -/* Assemble the base @cmd with all of the command options. - * @parts is always initialized, even on error. - * This is called twice in _mongoc_write_opquery. - * Once with no payload documents, to determine the total size. And once with - * payload documents, to send the final command. */ -static bool -_assemble_cmd (bson_t *cmd, - mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const mongoc_write_concern_t *write_concern, - mongoc_cmd_parts_t *parts, - bson_error_t *error) -{ - bool ret; - bson_iter_t iter; - - mongoc_cmd_parts_init (parts, client, database, MONGOC_QUERY_NONE, cmd); - parts->is_write_command = true; - parts->assembled.operation_id = command->operation_id; - - ret = mongoc_cmd_parts_set_write_concern ( - parts, write_concern, server_stream->sd->max_wire_version, error); - if (ret) { - BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts)); - ret = mongoc_cmd_parts_append_opts ( - parts, &iter, server_stream->sd->max_wire_version, error); - } - if (ret) { - ret = mongoc_cmd_parts_assemble (parts, server_stream, error); - } - return ret; -} - -static void -_mongoc_write_opquery (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - const mongoc_write_concern_t *write_concern, - uint32_t offset, - mongoc_write_result_t *result, - bson_error_t *error) -{ - mongoc_cmd_parts_t parts; - const char *key; - uint32_t len = 0; - bson_t ar; - bson_t cmd; - char str[16]; - bool has_more; - bool ret = false; - uint32_t i; - int32_t max_bson_obj_size; - int32_t max_write_batch_size; - uint32_t overhead; - uint32_t key_len; - int data_offset = 0; - bson_reader_t *reader; - const bson_t *bson; - bool eof; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (database); - BSON_ASSERT (server_stream); - BSON_ASSERT (collection); - - bson_init (&cmd); - max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); - max_write_batch_size = - mongoc_server_stream_max_write_batch_size (server_stream); - -again: - has_more = false; - i = 0; - - _mongoc_write_command_init (&cmd, command, collection); - /* If any part of assembling failed, return with failure. */ - if (!_assemble_cmd (&cmd, - command, - client, - server_stream, - database, - write_concern, - &parts, - error)) { - result->failed = true; - bson_destroy (&cmd); - mongoc_cmd_parts_cleanup (&parts); - EXIT; - } - - /* Use the assembled command to compute the overhead, since it may be a new - * BSON document with options applied. If no options were applied, then - * parts.assembled.command points to cmd. The constant 2 is due to 1 byte to - * specify array type and 1 byte for field name's null terminator. */ - overhead = - parts.assembled.command->len + 2 + gCommandFieldLens[command->type]; - /* Toss out the assembled command, we'll assemble again after adding all of - * the payload documents. */ - mongoc_cmd_parts_cleanup (&parts); - - reader = bson_reader_new_from_data (command->payload.data + data_offset, - command->payload.len - data_offset); - - bson_append_array_begin (&cmd, - gCommandFields[command->type], - gCommandFieldLens[command->type], - &ar); - - while ((bson = bson_reader_read (reader, &eof))) { - key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str); - len = bson->len; - /* 1 byte to specify document type, 1 byte for key's null terminator */ - if (_mongoc_write_command_will_overflow (overhead, - key_len + len + 2 + ar.len, - i, - max_bson_obj_size, - max_write_batch_size)) { - has_more = true; - break; - } - BSON_APPEND_DOCUMENT (&ar, key, bson); - data_offset += len; - i++; - } - - bson_append_array_end (&cmd, &ar); - - if (!i) { - _mongoc_write_command_too_large_error (error, i, len, max_bson_obj_size); - result->failed = true; - result->must_stop = true; - ret = false; - if (bson) { - data_offset += len; - } - } else { - bson_t reply; - - ret = _assemble_cmd (&cmd, - command, - client, - server_stream, - database, - write_concern, - &parts, - error); - if (ret) { - ret = mongoc_cluster_run_command_monitored ( - &client->cluster, &parts.assembled, &reply, error); - } else { - bson_init (&reply); - } - - if (!ret) { - result->failed = true; - if (bson_empty (&reply)) { - /* assembling failed, or a network error running the command */ - result->must_stop = true; - } - } - - _mongoc_write_result_merge (result, command, &reply, offset); - offset += i; - bson_destroy (&reply); - mongoc_cmd_parts_cleanup (&parts); - } - bson_reader_destroy (reader); - - if (has_more && (ret || !command->flags.ordered) && !result->must_stop) { - bson_reinit (&cmd); - GOTO (again); - } - - bson_destroy (&cmd); - EXIT; -} - - -void -_mongoc_write_command_execute ( - mongoc_write_command_t *command, /* IN */ - mongoc_client_t *client, /* IN */ - mongoc_server_stream_t *server_stream, /* IN */ - const char *database, /* IN */ - const char *collection, /* IN */ - const mongoc_write_concern_t *write_concern, /* IN */ - uint32_t offset, /* IN */ - mongoc_client_session_t *cs, /* IN */ - mongoc_write_result_t *result) /* OUT */ -{ - mongoc_crud_opts_t crud = {0}; - - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (server_stream); - BSON_ASSERT (database); - BSON_ASSERT (collection); - BSON_ASSERT (result); - - if (!write_concern) { - write_concern = client->write_concern; - } - - if (!mongoc_write_concern_is_valid (write_concern)) { - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "The write concern is invalid."); - result->failed = true; - EXIT; - } - - crud.client_session = cs; - crud.writeConcern = (mongoc_write_concern_t *) write_concern; - - _mongoc_write_command_execute_idl (command, - client, - server_stream, - database, - collection, - offset, - &crud, - result); - EXIT; -} - -void -_mongoc_write_command_execute_idl (mongoc_write_command_t *command, - mongoc_client_t *client, - mongoc_server_stream_t *server_stream, - const char *database, - const char *collection, - uint32_t offset, - const mongoc_crud_opts_t *crud, - mongoc_write_result_t *result) -{ - ENTRY; - - BSON_ASSERT (command); - BSON_ASSERT (client); - BSON_ASSERT (server_stream); - BSON_ASSERT (database); - BSON_ASSERT (collection); - BSON_ASSERT (result); - - if (command->flags.has_collation) { - if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) { - result->failed = true; - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set collation for unacknowledged writes"); - EXIT; - } - - if (server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) { - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - result->failed = true; - EXIT; - } - } - - if (command->flags.has_array_filters) { - if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) { - result->failed = true; - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot use array filters with unacknowledged writes"); - EXIT; - } - - if (server_stream->sd->max_wire_version < WIRE_VERSION_ARRAY_FILTERS) { - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support array filters"); - result->failed = true; - EXIT; - } - } - - if (command->flags.bypass_document_validation) { - if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) { - result->failed = true; - bson_set_error ( - &result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set bypassDocumentValidation for unacknowledged writes"); - EXIT; - } - } - - if (crud->client_session && - !mongoc_write_concern_is_acknowledged (crud->writeConcern)) { - result->failed = true; - bson_set_error (&result->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot use client session with unacknowledged writes"); - EXIT; - } - - if (command->payload.len == 0) { - _empty_error (command, &result->error); - EXIT; - } - - if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) { - _mongoc_write_opmsg (command, - client, - server_stream, - database, - collection, - crud->writeConcern, - offset, - crud->client_session, - result, - &result->error); - } else { - if (mongoc_write_concern_is_acknowledged (crud->writeConcern)) { - _mongoc_write_opquery (command, - client, - server_stream, - database, - collection, - crud->writeConcern, - offset, - result, - &result->error); - } else { - gLegacyWriteOps[command->type](command, - client, - server_stream, - database, - collection, - offset, - result, - &result->error); - } - } - - EXIT; -} - - -void -_mongoc_write_command_destroy (mongoc_write_command_t *command) -{ - ENTRY; - - if (command) { - bson_destroy (&command->cmd_opts); - _mongoc_buffer_destroy (&command->payload); - } - - EXIT; -} - - -void -_mongoc_write_result_init (mongoc_write_result_t *result) /* IN */ -{ - ENTRY; - - BSON_ASSERT (result); - - memset (result, 0, sizeof *result); - - bson_init (&result->upserted); - bson_init (&result->writeConcernErrors); - bson_init (&result->writeErrors); - bson_init (&result->errorLabels); - - EXIT; -} - - -void -_mongoc_write_result_destroy (mongoc_write_result_t *result) -{ - ENTRY; - - BSON_ASSERT (result); - - bson_destroy (&result->upserted); - bson_destroy (&result->writeConcernErrors); - bson_destroy (&result->writeErrors); - bson_destroy (&result->errorLabels); - - EXIT; -} - - -void -_mongoc_write_result_append_upsert (mongoc_write_result_t *result, - int32_t idx, - const bson_value_t *value) -{ - bson_t child; - const char *keyptr = NULL; - char key[12]; - int len; - - BSON_ASSERT (result); - BSON_ASSERT (value); - - len = (int) bson_uint32_to_string ( - result->upsert_append_count, &keyptr, key, sizeof key); - - bson_append_document_begin (&result->upserted, keyptr, len, &child); - BSON_APPEND_INT32 (&child, "index", idx); - BSON_APPEND_VALUE (&child, "_id", value); - bson_append_document_end (&result->upserted, &child); - - result->upsert_append_count++; -} - - -int32_t -_mongoc_write_result_merge_arrays (uint32_t offset, - mongoc_write_result_t *result, /* IN */ - bson_t *dest, /* IN */ - bson_iter_t *iter) /* IN */ -{ - const bson_value_t *value; - bson_iter_t ar; - bson_iter_t citer; - int32_t idx; - int32_t count = 0; - int32_t aridx; - bson_t child; - const char *keyptr = NULL; - char key[12]; - int len; - - ENTRY; - - BSON_ASSERT (result); - BSON_ASSERT (dest); - BSON_ASSERT (iter); - BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (iter)); - - aridx = bson_count_keys (dest); - - if (bson_iter_recurse (iter, &ar)) { - while (bson_iter_next (&ar)) { - if (BSON_ITER_HOLDS_DOCUMENT (&ar) && - bson_iter_recurse (&ar, &citer)) { - len = - (int) bson_uint32_to_string (aridx++, &keyptr, key, sizeof key); - bson_append_document_begin (dest, keyptr, len, &child); - while (bson_iter_next (&citer)) { - if (BSON_ITER_IS_KEY (&citer, "index")) { - idx = bson_iter_int32 (&citer) + offset; - BSON_APPEND_INT32 (&child, "index", idx); - } else { - value = bson_iter_value (&citer); - BSON_APPEND_VALUE (&child, bson_iter_key (&citer), value); - } - } - bson_append_document_end (dest, &child); - count++; - } - } - } - - RETURN (count); -} - - -void -_mongoc_write_result_merge (mongoc_write_result_t *result, /* IN */ - mongoc_write_command_t *command, /* IN */ - const bson_t *reply, /* IN */ - uint32_t offset) -{ - int32_t server_index = 0; - const bson_value_t *value; - bson_iter_t iter; - bson_iter_t citer; - bson_iter_t ar; - int32_t n_upserted = 0; - int32_t affected = 0; - - ENTRY; - - BSON_ASSERT (result); - BSON_ASSERT (reply); - - if (bson_iter_init_find (&iter, reply, "n") && - BSON_ITER_HOLDS_INT32 (&iter)) { - affected = bson_iter_int32 (&iter); - } - - if (bson_iter_init_find (&iter, reply, "writeErrors") && - BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &citer) && - bson_iter_next (&citer)) { - result->failed = true; - } - - switch (command->type) { - case MONGOC_WRITE_COMMAND_INSERT: - result->nInserted += affected; - break; - case MONGOC_WRITE_COMMAND_DELETE: - result->nRemoved += affected; - break; - case MONGOC_WRITE_COMMAND_UPDATE: - - /* server returns each upserted _id with its index into this batch - * look for "upserted": [{"index": 4, "_id": ObjectId()}, ...] */ - if (bson_iter_init_find (&iter, reply, "upserted")) { - if (BSON_ITER_HOLDS_ARRAY (&iter) && - (bson_iter_recurse (&iter, &ar))) { - while (bson_iter_next (&ar)) { - if (BSON_ITER_HOLDS_DOCUMENT (&ar) && - bson_iter_recurse (&ar, &citer) && - bson_iter_find (&citer, "index") && - BSON_ITER_HOLDS_INT32 (&citer)) { - server_index = bson_iter_int32 (&citer); - - if (bson_iter_recurse (&ar, &citer) && - bson_iter_find (&citer, "_id")) { - value = bson_iter_value (&citer); - _mongoc_write_result_append_upsert ( - result, offset + server_index, value); - n_upserted++; - } - } - } - } - result->nUpserted += n_upserted; - /* - * XXX: The following addition to nMatched needs some checking. - * I'm highly skeptical of it. - */ - result->nMatched += BSON_MAX (0, (affected - n_upserted)); - } else { - result->nMatched += affected; - } - if (bson_iter_init_find (&iter, reply, "nModified") && - BSON_ITER_HOLDS_INT32 (&iter)) { - result->nModified += bson_iter_int32 (&iter); - } - break; - default: - BSON_ASSERT (false); - break; - } - - if (bson_iter_init_find (&iter, reply, "writeErrors") && - BSON_ITER_HOLDS_ARRAY (&iter)) { - _mongoc_write_result_merge_arrays ( - offset, result, &result->writeErrors, &iter); - } - - if (bson_iter_init_find (&iter, reply, "writeConcernError") && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - uint32_t len; - const uint8_t *data; - bson_t write_concern_error; - char str[16]; - const char *key; - - /* writeConcernError is a subdocument in the server response - * append it to the result->writeConcernErrors array */ - bson_iter_document (&iter, &len, &data); - BSON_ASSERT (bson_init_static (&write_concern_error, data, len)); - - bson_uint32_to_string ( - result->n_writeConcernErrors, &key, str, sizeof str); - - if (!bson_append_document ( - &result->writeConcernErrors, key, -1, &write_concern_error)) { - MONGOC_ERROR ("Error adding \"%s\" to writeConcernErrors.\n", key); - } - - result->n_writeConcernErrors++; - } - - /* inefficient if there are ever large numbers: for each label in each err, - * we linear-search result->errorLabels to see if it's included yet */ - _mongoc_bson_array_copy_labels_to (reply, &result->errorLabels); - - EXIT; -} - - -/* - * If error is not set, set code from first document in array like - * [{"code": 64, "errmsg": "duplicate"}, ...]. Format the error message - * from all errors in array. - */ -static void -_set_error_from_response (bson_t *bson_array, - mongoc_error_domain_t domain, - const char *error_type, - bson_error_t *error /* OUT */) -{ - bson_iter_t array_iter; - bson_iter_t doc_iter; - bson_string_t *compound_err; - const char *errmsg = NULL; - int32_t code = 0; - uint32_t n_keys, i; - - compound_err = bson_string_new (NULL); - n_keys = bson_count_keys (bson_array); - if (n_keys > 1) { - bson_string_append_printf ( - compound_err, "Multiple %s errors: ", error_type); - } - - if (!bson_empty0 (bson_array) && bson_iter_init (&array_iter, bson_array)) { - /* get first code and all error messages */ - i = 0; - - while (bson_iter_next (&array_iter)) { - if (BSON_ITER_HOLDS_DOCUMENT (&array_iter) && - bson_iter_recurse (&array_iter, &doc_iter)) { - /* parse doc, which is like {"code": 64, "errmsg": "duplicate"} */ - while (bson_iter_next (&doc_iter)) { - /* use the first error code we find */ - if (BSON_ITER_IS_KEY (&doc_iter, "code") && code == 0) { - code = bson_iter_int32 (&doc_iter); - } else if (BSON_ITER_IS_KEY (&doc_iter, "errmsg")) { - errmsg = bson_iter_utf8 (&doc_iter, NULL); - - /* build message like 'Multiple write errors: "foo", "bar"' */ - if (n_keys > 1) { - bson_string_append_printf (compound_err, "\"%s\"", errmsg); - if (i < n_keys - 1) { - bson_string_append (compound_err, ", "); - } - } else { - /* single error message */ - bson_string_append (compound_err, errmsg); - } - } - } - - i++; - } - } - - if (code && compound_err->len) { - bson_set_error ( - error, domain, (uint32_t) code, "%s", compound_err->str); - } - } - - bson_string_free (compound_err, true); -} - - -/* complete a write result, including only certain fields */ -bool -_mongoc_write_result_complete ( - mongoc_write_result_t *result, /* IN */ - int32_t error_api_version, /* IN */ - const mongoc_write_concern_t *wc, /* IN */ - mongoc_error_domain_t err_domain_override, /* IN */ - bson_t *bson, /* OUT */ - bson_error_t *error, /* OUT */ - ...) -{ - mongoc_error_domain_t domain; - va_list args; - const char *field; - int n_args; - bson_iter_t iter; - bson_iter_t child; - - ENTRY; - - BSON_ASSERT (result); - - if (error_api_version >= MONGOC_ERROR_API_VERSION_2) { - domain = MONGOC_ERROR_SERVER; - } else if (err_domain_override) { - domain = err_domain_override; - } else if (result->error.domain) { - domain = (mongoc_error_domain_t) result->error.domain; - } else { - domain = MONGOC_ERROR_COLLECTION; - } - - /* produce either old fields like nModified from the deprecated Bulk API Spec - * or new fields like modifiedCount from the CRUD Spec, which we partly obey - */ - if (bson && mongoc_write_concern_is_acknowledged (wc)) { - n_args = 0; - va_start (args, error); - while ((field = va_arg (args, const char *))) { - n_args++; - - if (!strcmp (field, "nInserted")) { - BSON_APPEND_INT32 (bson, field, result->nInserted); - } else if (!strcmp (field, "insertedCount")) { - BSON_APPEND_INT32 (bson, field, result->nInserted); - } else if (!strcmp (field, "nMatched")) { - BSON_APPEND_INT32 (bson, field, result->nMatched); - } else if (!strcmp (field, "matchedCount")) { - BSON_APPEND_INT32 (bson, field, result->nMatched); - } else if (!strcmp (field, "nModified")) { - BSON_APPEND_INT32 (bson, field, result->nModified); - } else if (!strcmp (field, "modifiedCount")) { - BSON_APPEND_INT32 (bson, field, result->nModified); - } else if (!strcmp (field, "nRemoved")) { - BSON_APPEND_INT32 (bson, field, result->nRemoved); - } else if (!strcmp (field, "deletedCount")) { - BSON_APPEND_INT32 (bson, field, result->nRemoved); - } else if (!strcmp (field, "nUpserted")) { - BSON_APPEND_INT32 (bson, field, result->nUpserted); - } else if (!strcmp (field, "upsertedCount")) { - BSON_APPEND_INT32 (bson, field, result->nUpserted); - } else if (!strcmp (field, "upserted") && - !bson_empty0 (&result->upserted)) { - BSON_APPEND_ARRAY (bson, field, &result->upserted); - } else if (!strcmp (field, "upsertedId") && - !bson_empty0 (&result->upserted) && - bson_iter_init_find (&iter, &result->upserted, "0") && - bson_iter_recurse (&iter, &child) && - bson_iter_find (&child, "_id")) { - /* "upsertedId", singular, for update_one() */ - BSON_APPEND_VALUE (bson, "upsertedId", bson_iter_value (&child)); - } - } - - va_end (args); - - /* default: a standard result includes all Bulk API fields */ - if (!n_args) { - BSON_APPEND_INT32 (bson, "nInserted", result->nInserted); - BSON_APPEND_INT32 (bson, "nMatched", result->nMatched); - BSON_APPEND_INT32 (bson, "nModified", result->nModified); - BSON_APPEND_INT32 (bson, "nRemoved", result->nRemoved); - BSON_APPEND_INT32 (bson, "nUpserted", result->nUpserted); - if (!bson_empty0 (&result->upserted)) { - BSON_APPEND_ARRAY (bson, "upserted", &result->upserted); - } - } - - /* always append errors if there are any */ - if (!n_args || !bson_empty (&result->writeErrors)) { - BSON_APPEND_ARRAY (bson, "writeErrors", &result->writeErrors); - } - - if (result->n_writeConcernErrors) { - BSON_APPEND_ARRAY ( - bson, "writeConcernErrors", &result->writeConcernErrors); - } - } - - /* set bson_error_t from first write error or write concern error */ - _set_error_from_response ( - &result->writeErrors, domain, "write", &result->error); - - if (!result->error.code) { - _set_error_from_response (&result->writeConcernErrors, - MONGOC_ERROR_WRITE_CONCERN, - "write concern", - &result->error); - } - - if (bson && !bson_empty (&result->errorLabels)) { - BSON_APPEND_ARRAY (bson, "errorLabels", &result->errorLabels); - } - - if (error) { - memcpy (error, &result->error, sizeof *error); - } - - RETURN (!result->failed && result->error.code == 0); -} - - -/*-------------------------------------------------------------------------- - * - * _mongoc_write_error_get_type -- - * - * Checks if the error or reply from a write command is considered - * retryable according to the retryable writes spec. Checks both - * for a client error (a network exception) and a server error in - * the reply. @cmd_ret and @cmd_err come from the result of a - * write_command function. - * - * - * Return: - * A mongoc_write_error_type_t indicating the type of error (if any). - * - *-------------------------------------------------------------------------- - */ -mongoc_write_err_type_t -_mongoc_write_error_get_type (bool cmd_ret, - const bson_error_t *cmd_err, - const bson_t *reply) -{ - bson_error_t error; - - /* check for a client error. */ - if (!cmd_ret && cmd_err->domain == MONGOC_ERROR_STREAM) { - /* Retryable writes spec: "considered retryable if [...] any network - * exception (e.g. socket timeout or error) */ - return MONGOC_WRITE_ERR_RETRY; - } - - /* check for a server error. */ - if (_mongoc_cmd_check_ok_no_wce ( - reply, MONGOC_ERROR_API_VERSION_2, &error)) { - return MONGOC_WRITE_ERR_NONE; - } - - switch (error.code) { - case 11600: /* InterruptedAtShutdown */ - case 11602: /* InterruptedDueToReplStateChange */ - case 10107: /* NotMaster */ - case 13435: /* NotMasterNoSlaveOk */ - case 13436: /* NotMasterOrSecondary */ - case 189: /* PrimarySteppedDown */ - case 91: /* ShutdownInProgress */ - case 7: /* HostNotFound */ - case 6: /* HostUnreachable */ - case 89: /* NetworkTimeout */ - case 9001: /* SocketException */ - return MONGOC_WRITE_ERR_RETRY; - case 64: /* WriteConcernFailed */ - return MONGOC_WRITE_ERR_WRITE_CONCERN; - default: - if (strstr (error.message, "not master") || - strstr (error.message, "node is recovering")) { - return MONGOC_WRITE_ERR_RETRY; - } - return MONGOC_WRITE_ERR_OTHER; - } -} - -/* Returns true and modifies reply and cmd_err. */ -bool -_mongoc_write_error_update_if_unsupported_storage_engine (bool cmd_ret, - bson_error_t *cmd_err, - bson_t *reply) -{ - bson_error_t server_error; - - if (cmd_ret) { - return false; - } - - if (_mongoc_cmd_check_ok_no_wce ( - reply, MONGOC_ERROR_API_VERSION_2, &server_error)) { - return false; - } - - if (server_error.code == 20 && - strstr (server_error.message, "Transaction numbers") == - server_error.message) { - const char *replacement = "This MongoDB deployment does not support " - "retryable writes. Please add " - "retryWrites=false to your connection string."; - - strcpy (cmd_err->message, replacement); - - if (reply) { - bson_t *new_reply = bson_new (); - bson_copy_to_excluding_noinit (reply, new_reply, "errmsg", NULL); - BSON_APPEND_UTF8 (new_reply, "errmsg", replacement); - bson_destroy (reply); - bson_steal (reply, new_reply); - } - return true; - } - return false; -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern-private.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern-private.h deleted file mode 100644 index b1b15c537e0dc45e99f61ab7e5e45b0dcff67364..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern-private.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_WRITE_CONCERN_PRIVATE_H -#define MONGOC_WRITE_CONCERN_PRIVATE_H - -#include <bson/bson.h> - - -BSON_BEGIN_DECLS - - -#define MONGOC_WRITE_CONCERN_FSYNC_DEFAULT -1 -#define MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT -1 - - -struct _mongoc_write_concern_t { - int8_t fsync_; /* deprecated */ - int8_t journal; - int32_t w; - int64_t wtimeout; - char *wtag; - bool frozen; - bson_t compiled; - bool is_default; -}; - - -mongoc_write_concern_t * -_mongoc_write_concern_new_from_iter (const bson_iter_t *iter, - bson_error_t *error); -const bson_t * -_mongoc_write_concern_get_bson (mongoc_write_concern_t *write_concern); -bool -_mongoc_parse_wc_err (const bson_t *doc, bson_error_t *error); - -BSON_END_DECLS - - -#endif /* MONGOC_WRITE_CONCERN_PRIVATE_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern.c b/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern.c deleted file mode 100644 index b93d62cf8ed35e1b60da33f522b9e4c7b93d03e1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-error.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-write-concern-private.h" - - -static void -_mongoc_write_concern_freeze (mongoc_write_concern_t *write_concern); - - -/** - * mongoc_write_concern_new: - * - * Create a new mongoc_write_concern_t. - * - * Returns: A newly allocated mongoc_write_concern_t. This should be freed - * with mongoc_write_concern_destroy(). - */ -mongoc_write_concern_t * -mongoc_write_concern_new (void) -{ - mongoc_write_concern_t *write_concern; - - write_concern = - (mongoc_write_concern_t *) bson_malloc0 (sizeof *write_concern); - write_concern->w = MONGOC_WRITE_CONCERN_W_DEFAULT; - write_concern->fsync_ = MONGOC_WRITE_CONCERN_FSYNC_DEFAULT; - write_concern->journal = MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT; - write_concern->is_default = true; - - bson_init (&write_concern->compiled); - - return write_concern; -} - - -mongoc_write_concern_t * -mongoc_write_concern_copy (const mongoc_write_concern_t *write_concern) -{ - mongoc_write_concern_t *ret = NULL; - - if (write_concern) { - ret = mongoc_write_concern_new (); - ret->fsync_ = write_concern->fsync_; - ret->journal = write_concern->journal; - ret->w = write_concern->w; - ret->wtimeout = write_concern->wtimeout; - ret->frozen = false; - ret->wtag = bson_strdup (write_concern->wtag); - ret->is_default = write_concern->is_default; - } - - return ret; -} - - -/** - * mongoc_write_concern_destroy: - * @write_concern: A mongoc_write_concern_t. - * - * Releases a mongoc_write_concern_t and all associated memory. - */ -void -mongoc_write_concern_destroy (mongoc_write_concern_t *write_concern) -{ - if (write_concern) { - bson_destroy (&write_concern->compiled); - bson_free (write_concern->wtag); - bson_free (write_concern); - } -} - - -bool -mongoc_write_concern_get_fsync (const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (write_concern); - return (write_concern->fsync_ == true); -} - - -/** - * mongoc_write_concern_set_fsync: - * @write_concern: A mongoc_write_concern_t. - * @fsync_: If the write concern requires fsync() by the server. - * - * Set if fsync() should be called on the server before acknowledging a - * write request. - */ -void -mongoc_write_concern_set_fsync (mongoc_write_concern_t *write_concern, - bool fsync_) -{ - BSON_ASSERT (write_concern); - - write_concern->fsync_ = !!fsync_; - write_concern->is_default = false; - write_concern->frozen = false; -} - - -bool -mongoc_write_concern_get_journal (const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (write_concern); - return (write_concern->journal == true); -} - - -bool -mongoc_write_concern_journal_is_set ( - const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (write_concern); - return (write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT); -} - - -/** - * mongoc_write_concern_set_journal: - * @write_concern: A mongoc_write_concern_t. - * @journal: If the write should be journaled. - * - * Set if the write request should be journaled before acknowledging the - * write request. - */ -void -mongoc_write_concern_set_journal (mongoc_write_concern_t *write_concern, - bool journal) -{ - BSON_ASSERT (write_concern); - - write_concern->journal = !!journal; - write_concern->is_default = false; - write_concern->frozen = false; -} - - -int32_t -mongoc_write_concern_get_w (const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (write_concern); - return write_concern->w; -} - - -/** - * mongoc_write_concern_set_w: - * @w: The number of nodes for write or MONGOC_WRITE_CONCERN_W_MAJORITY - * for "majority". - * - * Sets the number of nodes that must acknowledge the write request before - * acknowledging the write request to the client. - * - * You may specify @w as MONGOC_WRITE_CONCERN_W_MAJORITY to request that - * a "majority" of nodes acknowledge the request. - */ -void -mongoc_write_concern_set_w (mongoc_write_concern_t *write_concern, int32_t w) -{ - BSON_ASSERT (write_concern); - BSON_ASSERT (w >= -3); - - write_concern->w = w; - if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) { - write_concern->is_default = false; - } - write_concern->frozen = false; -} - - -int32_t -mongoc_write_concern_get_wtimeout (const mongoc_write_concern_t *write_concern) -{ - return (int32_t) mongoc_write_concern_get_wtimeout_int64 (write_concern); -} - - -int64_t -mongoc_write_concern_get_wtimeout_int64 ( - const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (write_concern); - return write_concern->wtimeout; -} - - -void -mongoc_write_concern_set_wtimeout (mongoc_write_concern_t *write_concern, - int32_t wtimeout_msec) -{ - mongoc_write_concern_set_wtimeout_int64 (write_concern, - (int64_t) wtimeout_msec); -} - - -void -mongoc_write_concern_set_wtimeout_int64 (mongoc_write_concern_t *write_concern, - int64_t wtimeout_msec) -{ - BSON_ASSERT (write_concern); - - if (wtimeout_msec < 0) { - return; - } - - write_concern->wtimeout = wtimeout_msec; - write_concern->is_default = false; - write_concern->frozen = false; -} - - -bool -mongoc_write_concern_get_wmajority (const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (write_concern); - return (write_concern->w == MONGOC_WRITE_CONCERN_W_MAJORITY); -} - - -/** - * mongoc_write_concern_set_wmajority: - * @write_concern: A mongoc_write_concern_t. - * @wtimeout_msec: Number of milliseconds before timeout. - * - * Sets the "w" of a write concern to "majority". It is suggested that - * you provide a reasonable @wtimeout_msec to wait before considering the - * write request failed. A @wtimeout_msec value of 0 indicates no write timeout. - * - * The @wtimeout_msec parameter must be positive or zero. Negative values will - * be ignored. - */ -void -mongoc_write_concern_set_wmajority (mongoc_write_concern_t *write_concern, - int32_t wtimeout_msec) -{ - BSON_ASSERT (write_concern); - - write_concern->w = MONGOC_WRITE_CONCERN_W_MAJORITY; - write_concern->is_default = false; - write_concern->frozen = false; - - if (wtimeout_msec >= 0) { - write_concern->wtimeout = wtimeout_msec; - } -} - - -const char * -mongoc_write_concern_get_wtag (const mongoc_write_concern_t *write_concern) -{ - BSON_ASSERT (write_concern); - - if (write_concern->w == MONGOC_WRITE_CONCERN_W_TAG) { - return write_concern->wtag; - } - - return NULL; -} - - -void -mongoc_write_concern_set_wtag (mongoc_write_concern_t *write_concern, - const char *wtag) -{ - BSON_ASSERT (write_concern); - - bson_free (write_concern->wtag); - write_concern->wtag = bson_strdup (wtag); - write_concern->w = MONGOC_WRITE_CONCERN_W_TAG; - write_concern->is_default = false; - write_concern->frozen = false; -} - -/** - * mongoc_write_concern_get_bson: - * @write_concern: A mongoc_write_concern_t. - * - * This is an internal function. - * - * Returns: A bson_t representing the write concern, which is owned by the - * mongoc_write_concern_t instance and should not be modified or freed. - */ -const bson_t * -_mongoc_write_concern_get_bson (mongoc_write_concern_t *write_concern) -{ - if (!write_concern->frozen) { - _mongoc_write_concern_freeze (write_concern); - } - - return &write_concern->compiled; -} - -/** - * mongoc_write_concern_is_default: - * @write_concern: A mongoc_write_concern_t. - * - * Returns is_default, which is true when write_concern has not been modified. - * - */ -bool -mongoc_write_concern_is_default (const mongoc_write_concern_t *write_concern) -{ - return !write_concern || write_concern->is_default; -} - - -/** - * mongoc_write_concern_freeze: - * @write_concern: A mongoc_write_concern_t. - * - * This is an internal function. - * - * Encodes the write concern into a bson_t, which may then be returned by - * _mongoc_write_concern_get_bson(). - */ -static void -_mongoc_write_concern_freeze (mongoc_write_concern_t *write_concern) -{ - bson_t *compiled; - - BSON_ASSERT (write_concern); - - compiled = &write_concern->compiled; - - write_concern->frozen = true; - - bson_reinit (compiled); - - if (write_concern->w == MONGOC_WRITE_CONCERN_W_TAG) { - BSON_ASSERT (write_concern->wtag); - BSON_APPEND_UTF8 (compiled, "w", write_concern->wtag); - } else if (write_concern->w == MONGOC_WRITE_CONCERN_W_MAJORITY) { - BSON_APPEND_UTF8 (compiled, "w", "majority"); - } else if (write_concern->w == MONGOC_WRITE_CONCERN_W_DEFAULT) { - /* Do Nothing */ - } else { - BSON_APPEND_INT32 (compiled, "w", write_concern->w); - } - - if (write_concern->fsync_ != MONGOC_WRITE_CONCERN_FSYNC_DEFAULT) { - bson_append_bool (compiled, "fsync", 5, !!write_concern->fsync_); - } - - if (write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT) { - bson_append_bool (compiled, "j", 1, !!write_concern->journal); - } - - if (write_concern->wtimeout) { - bson_append_int64 (compiled, "wtimeout", 8, write_concern->wtimeout); - } -} - - -/** - * mongoc_write_concern_is_acknowledged: - * @concern: (in): A mongoc_write_concern_t. - * - * Checks to see if @write_concern requests that a getlasterror command is to - * be delivered to the MongoDB server. - * - * Returns: true if a getlasterror command should be sent. - */ -bool -mongoc_write_concern_is_acknowledged ( - const mongoc_write_concern_t *write_concern) -{ - if (write_concern) { - return (((write_concern->w != MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED) && - (write_concern->w != MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED)) || - write_concern->fsync_ == true || - mongoc_write_concern_get_journal (write_concern)); - } - return true; -} - - -/** - * mongoc_write_concern_is_valid: - * @write_concern: (in): A mongoc_write_concern_t. - * - * Checks to see if @write_concern is valid and does not contain conflicting - * options. - * - * Returns: true if the write concern is valid; otherwise false. - */ -bool -mongoc_write_concern_is_valid (const mongoc_write_concern_t *write_concern) -{ - if (!write_concern) { - return false; - } - - /* Journal or fsync should require acknowledgement. */ - if ((write_concern->fsync_ == true || - mongoc_write_concern_get_journal (write_concern)) && - (write_concern->w == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || - write_concern->w == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED)) { - return false; - } - - if (write_concern->wtimeout < 0) { - return false; - } - - return true; -} - - -static bool -_mongoc_write_concern_validate (const mongoc_write_concern_t *write_concern, - bson_error_t *error) -{ - if (write_concern && !mongoc_write_concern_is_valid (write_concern)) { - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - return false; - } - return true; -} - - -/** - * _mongoc_parse_wc_err: - * @doc: (in): A bson document. - * @error: (out): A bson_error_t. - * - * Parses a document, usually a server reply, - * looking for a writeConcernError. Returns true if - * there is a writeConcernError, false otherwise. - */ -bool -_mongoc_parse_wc_err (const bson_t *doc, bson_error_t *error) -{ - bson_iter_t iter; - bson_iter_t inner; - - if (bson_iter_init_find (&iter, doc, "writeConcernError") && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - const char *errmsg = NULL; - int32_t code = 0; - BSON_ASSERT (bson_iter_recurse (&iter, &inner)); - while (bson_iter_next (&inner)) { - if (BSON_ITER_IS_KEY (&inner, "code")) { - code = bson_iter_int32 (&inner); - } else if (BSON_ITER_IS_KEY (&inner, "errmsg")) { - errmsg = bson_iter_utf8 (&inner, NULL); - } - } - bson_set_error (error, - MONGOC_ERROR_WRITE_CONCERN, - code, - "Write Concern error: %s", - errmsg); - return true; - } - return false; -} - - -/** - * mongoc_write_concern_append: - * @write_concern: (in): A mongoc_write_concern_t. - * @command: (out): A pointer to a bson document. - * - * Appends a write_concern document to a command, to send to - * a server. - * - * Returns true on success, false on failure. - * - */ -bool -mongoc_write_concern_append (mongoc_write_concern_t *write_concern, - bson_t *command) -{ - if (!mongoc_write_concern_is_valid (write_concern)) { - MONGOC_ERROR ("Invalid writeConcern passed into " - "mongoc_write_concern_append."); - return false; - } - if (!bson_append_document (command, - "writeConcern", - 12, - _mongoc_write_concern_get_bson (write_concern))) { - MONGOC_ERROR ("Could not append writeConcern to command."); - return false; - } - return true; -} - -/** - * _mongoc_write_concern_new_from_iter: - * - * Create a new mongoc_write_concern_t from an iterator positioned on - * a "writeConcern" document. - * - * Returns: A newly allocated mongoc_write_concern_t. This should be freed - * with mongoc_write_concern_destroy(). - */ -mongoc_write_concern_t * -_mongoc_write_concern_new_from_iter (const bson_iter_t *iter, - bson_error_t *error) -{ - bson_iter_t inner; - mongoc_write_concern_t *write_concern; - int32_t w; - - BSON_ASSERT (iter); - - write_concern = mongoc_write_concern_new (); - if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { - goto fail; - } - - BSON_ASSERT (bson_iter_recurse (iter, &inner)); - while (bson_iter_next (&inner)) { - if (BSON_ITER_IS_KEY (&inner, "w")) { - if (BSON_ITER_HOLDS_INT32 (&inner)) { - w = bson_iter_int32 (&inner); - if (w < MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED) { - goto fail; - } - - mongoc_write_concern_set_w (write_concern, w); - } else if (BSON_ITER_HOLDS_UTF8 (&inner)) { - if (!strcmp (bson_iter_utf8 (&inner, NULL), "majority")) { - /* mongoc_write_concern_set_wmajority() only assigns wtimeout if - * it is >= 0. Since we set wtimeout below, pass -1 here. */ - mongoc_write_concern_set_wmajority (write_concern, -1); - } else { - mongoc_write_concern_set_wtag (write_concern, - bson_iter_utf8 (&inner, NULL)); - } - } else { - /* wrong type for "w" */ - goto fail; - } - } else if (BSON_ITER_IS_KEY (&inner, "fsync")) { - if (!BSON_ITER_HOLDS_BOOL (&inner)) { - goto fail; - } - BEGIN_IGNORE_DEPRECATIONS; - mongoc_write_concern_set_fsync (write_concern, - bson_iter_bool (&inner)); - END_IGNORE_DEPRECATIONS; - } else if (BSON_ITER_IS_KEY (&inner, "j")) { - if (!BSON_ITER_HOLDS_BOOL (&inner)) { - goto fail; - } - mongoc_write_concern_set_journal (write_concern, - bson_iter_bool (&inner)); - } else if (BSON_ITER_IS_KEY (&inner, "wtimeout")) { - if (!BSON_ITER_HOLDS_INT (&inner) || bson_iter_as_int64 (&inner) < 0) { - goto fail; - } - mongoc_write_concern_set_wtimeout_int64 (write_concern, - bson_iter_as_int64 (&inner)); - } - } - - if (!_mongoc_write_concern_validate (write_concern, error)) { - mongoc_write_concern_destroy (write_concern); - return NULL; - } - - return write_concern; - -fail: - bson_set_error (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - mongoc_write_concern_destroy (write_concern); - return NULL; -} diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern.h b/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern.h deleted file mode 100644 index 8132ba1dce1fab1618887728d0de067721486fc5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc-write-concern.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2013 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 "mongoc/mongoc-prelude.h" - -#ifndef MONGOC_WRITE_CONCERN_H -#define MONGOC_WRITE_CONCERN_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-macros.h" - -BSON_BEGIN_DECLS - - -#define MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED 0 -#define MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED -1 /* deprecated */ -#define MONGOC_WRITE_CONCERN_W_DEFAULT -2 -#define MONGOC_WRITE_CONCERN_W_MAJORITY -3 -#define MONGOC_WRITE_CONCERN_W_TAG -4 - - -typedef struct _mongoc_write_concern_t mongoc_write_concern_t; - - -MONGOC_EXPORT (mongoc_write_concern_t *) -mongoc_write_concern_new (void); -MONGOC_EXPORT (mongoc_write_concern_t *) -mongoc_write_concern_copy (const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (void) -mongoc_write_concern_destroy (mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (bool) -mongoc_write_concern_get_fsync (const mongoc_write_concern_t *write_concern) - BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (void) -mongoc_write_concern_set_fsync (mongoc_write_concern_t *write_concern, - bool fsync_) BSON_GNUC_DEPRECATED; -MONGOC_EXPORT (bool) -mongoc_write_concern_get_journal (const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (bool) -mongoc_write_concern_journal_is_set ( - const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (void) -mongoc_write_concern_set_journal (mongoc_write_concern_t *write_concern, - bool journal); -MONGOC_EXPORT (int32_t) -mongoc_write_concern_get_w (const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (void) -mongoc_write_concern_set_w (mongoc_write_concern_t *write_concern, int32_t w); -MONGOC_EXPORT (const char *) -mongoc_write_concern_get_wtag (const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (void) -mongoc_write_concern_set_wtag (mongoc_write_concern_t *write_concern, - const char *tag); -MONGOC_EXPORT (int32_t) -mongoc_write_concern_get_wtimeout (const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (int64_t) -mongoc_write_concern_get_wtimeout_int64 ( - const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (void) -mongoc_write_concern_set_wtimeout (mongoc_write_concern_t *write_concern, - int32_t wtimeout_msec); -MONGOC_EXPORT (void) -mongoc_write_concern_set_wtimeout_int64 (mongoc_write_concern_t *write_concern, - int64_t wtimeout_msec); -MONGOC_EXPORT (bool) -mongoc_write_concern_get_wmajority ( - const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (void) -mongoc_write_concern_set_wmajority (mongoc_write_concern_t *write_concern, - int32_t wtimeout_msec); -MONGOC_EXPORT (bool) -mongoc_write_concern_is_acknowledged ( - const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (bool) -mongoc_write_concern_is_valid (const mongoc_write_concern_t *write_concern); -MONGOC_EXPORT (bool) -mongoc_write_concern_append (mongoc_write_concern_t *write_concern, - bson_t *doc); -MONGOC_EXPORT (bool) -mongoc_write_concern_is_default (const mongoc_write_concern_t *write_concern); - -BSON_END_DECLS - - -#endif /* MONGOC_WRITE_CONCERN_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/mongoc.h b/lib/mongoc/libmongoc/src/mongoc/mongoc.h deleted file mode 100644 index 6ff0dcaa3342a1e21a0214d51f461011f31f150d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/mongoc.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013 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 MONGOC_H -#define MONGOC_H - - -#include <bson/bson.h> - -#define MONGOC_INSIDE -#include "mongoc/mongoc-macros.h" -#include "mongoc/mongoc-apm.h" -#include "mongoc/mongoc-bulk-operation.h" -#include "mongoc/mongoc-change-stream.h" -#include "mongoc/mongoc-client.h" -#include "mongoc/mongoc-client-pool.h" -#include "mongoc/mongoc-client-side-encryption.h" -#include "mongoc/mongoc-collection.h" -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-cursor.h" -#include "mongoc/mongoc-database.h" -#include "mongoc/mongoc-index.h" -#include "mongoc/mongoc-error.h" -#include "mongoc/mongoc-flags.h" -#include "mongoc/mongoc-gridfs.h" -#include "mongoc/mongoc-gridfs-bucket.h" -#include "mongoc/mongoc-gridfs-file.h" -#include "mongoc/mongoc-gridfs-file-list.h" -#include "mongoc/mongoc-gridfs-file-page.h" -#include "mongoc/mongoc-host-list.h" -#include "mongoc/mongoc-init.h" -#include "mongoc/mongoc-matcher.h" -#include "mongoc/mongoc-handshake.h" -#include "mongoc/mongoc-opcode.h" -#include "mongoc/mongoc-log.h" -#include "mongoc/mongoc-socket.h" -#include "mongoc/mongoc-client-session.h" -#include "mongoc/mongoc-stream.h" -#include "mongoc/mongoc-stream-buffered.h" -#include "mongoc/mongoc-stream-file.h" -#include "mongoc/mongoc-stream-gridfs.h" -#include "mongoc/mongoc-stream-socket.h" -#include "mongoc/mongoc-uri.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-version.h" -#include "mongoc/mongoc-version-functions.h" -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-rand.h" -#include "mongoc/mongoc-stream-tls.h" -#include "mongoc/mongoc-ssl.h" -#endif -#undef MONGOC_INSIDE - - -#endif /* MONGOC_H */ diff --git a/lib/mongoc/libmongoc/src/mongoc/op-compressed.def b/lib/mongoc/libmongoc/src/mongoc/op-compressed.def deleted file mode 100644 index 59f5e377553e0330818ff7eefa1d601098436b59..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-compressed.def +++ /dev/null @@ -1,11 +0,0 @@ -RPC( - compressed, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(original_opcode) - INT32_FIELD(uncompressed_size) - UINT8_FIELD(compressor_id) - RAW_BUFFER_FIELD(compressed_message) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-delete.def b/lib/mongoc/libmongoc/src/mongoc/op-delete.def deleted file mode 100644 index ee69d4675cc94b9493ff9dc6613872c3c7c30c3d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-delete.def +++ /dev/null @@ -1,11 +0,0 @@ -RPC( - delete, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(zero) - CSTRING_FIELD(collection) - ENUM_FIELD(flags) - BSON_FIELD(selector) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-get-more.def b/lib/mongoc/libmongoc/src/mongoc/op-get-more.def deleted file mode 100644 index 3d7da748430806fb3a79fe4a7b7754fffd73a628..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-get-more.def +++ /dev/null @@ -1,11 +0,0 @@ -RPC( - get_more, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(zero) - CSTRING_FIELD(collection) - INT32_FIELD(n_return) - INT64_FIELD(cursor_id) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-header.def b/lib/mongoc/libmongoc/src/mongoc/op-header.def deleted file mode 100644 index 093bd4b35f1719e27e5c5f4a0590f8f065aaebfa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-header.def +++ /dev/null @@ -1,7 +0,0 @@ -RPC( - header, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-insert.def b/lib/mongoc/libmongoc/src/mongoc/op-insert.def deleted file mode 100644 index 290ddce45bd3977a4c9cdac5dcbc82c6ebdf41ee..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-insert.def +++ /dev/null @@ -1,10 +0,0 @@ -RPC( - insert, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - CSTRING_FIELD(collection) - IOVEC_ARRAY_FIELD(documents) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-kill-cursors.def b/lib/mongoc/libmongoc/src/mongoc/op-kill-cursors.def deleted file mode 100644 index 1c3758e268eb6eb45bf775b525aed6fbf0b13b44..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-kill-cursors.def +++ /dev/null @@ -1,9 +0,0 @@ -RPC( - kill_cursors, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(zero) - INT64_ARRAY_FIELD(n_cursors, cursors) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-msg.def b/lib/mongoc/libmongoc/src/mongoc/op-msg.def deleted file mode 100644 index 2550bf6d842bfb99c2242df663bd4ad0f105ce6c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-msg.def +++ /dev/null @@ -1,9 +0,0 @@ -RPC( - msg, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - SECTION_ARRAY_FIELD(sections) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-query.def b/lib/mongoc/libmongoc/src/mongoc/op-query.def deleted file mode 100644 index 7a014743fe0e4ed30dc3607967431afc7daf7f2e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-query.def +++ /dev/null @@ -1,13 +0,0 @@ -RPC( - query, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - CSTRING_FIELD(collection) - INT32_FIELD(skip) - INT32_FIELD(n_return) - BSON_FIELD(query) - BSON_OPTIONAL(fields, BSON_FIELD(fields)) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-reply-header.def b/lib/mongoc/libmongoc/src/mongoc/op-reply-header.def deleted file mode 100644 index f272362fe7d66586ca1d8a81a4a52e2036c7dacf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-reply-header.def +++ /dev/null @@ -1,11 +0,0 @@ -RPC( - reply_header, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - INT64_FIELD(cursor_id) - INT32_FIELD(start_from) - INT32_FIELD(n_returned) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-reply.def b/lib/mongoc/libmongoc/src/mongoc/op-reply.def deleted file mode 100644 index c4cf8f0c42ac84319d06f65cac67ef4e70cc9c33..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-reply.def +++ /dev/null @@ -1,12 +0,0 @@ -RPC( - reply, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - ENUM_FIELD(flags) - INT64_FIELD(cursor_id) - INT32_FIELD(start_from) - INT32_FIELD(n_returned) - BSON_ARRAY_FIELD(documents) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/op-update.def b/lib/mongoc/libmongoc/src/mongoc/op-update.def deleted file mode 100644 index 2b1d2d79d923a5eb389251893b250b127cac3c8d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/op-update.def +++ /dev/null @@ -1,12 +0,0 @@ -RPC( - update, - INT32_FIELD(msg_len) - INT32_FIELD(request_id) - INT32_FIELD(response_to) - INT32_FIELD(opcode) - INT32_FIELD(zero) - CSTRING_FIELD(collection) - ENUM_FIELD(flags) - BSON_FIELD(selector) - BSON_FIELD(update) -) diff --git a/lib/mongoc/libmongoc/src/mongoc/utlist.h b/lib/mongoc/libmongoc/src/mongoc/utlist.h deleted file mode 100644 index 57bea0c25323ac8cc6bff333926a24e1a0b88ab9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/src/mongoc/utlist.h +++ /dev/null @@ -1,841 +0,0 @@ -/* -Copyright (c) 2007-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "mongoc/mongoc-prelude.h" - -#ifndef UTLIST_H -#define UTLIST_H - -#define UTLIST_VERSION 1.9.9 - -/* - * This file contains macros to manipulate singly and doubly-linked lists. - * - * 1. LL_ macros: singly-linked lists. - * 2. DL_ macros: doubly-linked lists. - * 3. CDL_ macros: circular doubly-linked lists. - * - * To use singly-linked lists, your structure must have a "next" pointer. - * To use doubly-linked lists, your structure must "prev" and "next" pointers. - * Either way, the pointer to the head of the list must be initialized to NULL. - * - * ----------------.EXAMPLE ------------------------- - * struct item { - * int id; - * struct item *prev, *next; - * } - * - * struct item *list = NULL: - * - * int main() { - * struct item *item; - * ... allocate and populate item ... - * DL_APPEND(list, item); - * } - * -------------------------------------------------- - * - * For doubly-linked lists, the append and delete macros are O(1) - * For singly-linked lists, append and delete are O(n) but prepend is O(1) - * The sort macro is O(n log(n)) for all types of single/double/circular lists. - */ - -/* These macros use decltype or the earlier __typeof GNU extension. - As decltype is only available in newer compilers (VS2010 or gcc 4.3+ - when compiling c++ code), this code uses whatever method is needed - or, for VS2008 where neither is available, uses casting workarounds. */ -#ifdef _MSC_VER /* MS compiler */ -#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ -#define LDECLTYPE(x) decltype (x) -#else /* VS2008 or older (or VS2010 in C mode) */ -#define NO_DECLTYPE -#define LDECLTYPE(x) char * -#endif -#elif defined(__ICCARM__) -#define NO_DECLTYPE -#define LDECLTYPE(x) char * -#else /* GNU, Sun and other compilers */ -#define LDECLTYPE(x) __typeof(x) -#endif - -/* for VS2008 we use some workarounds to get around the lack of decltype, - * namely, we always reassign our tmp variable to the list head if we need - * to dereference its prev/next pointers, and save/restore the real head.*/ -#ifdef NO_DECLTYPE -#define _SV(elt, list) \ - _tmp = (char *) (list); \ - { \ - char **_alias = (char **) &(list); \ - *_alias = (elt); \ - } -#define _NEXT(elt, list, next) ((char *) ((list)->next)) -#define _NEXTASGN(elt, list, to, next) \ - { \ - char **_alias = (char **) &((list)->next); \ - *_alias = (char *) (to); \ - } -/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ -#define _PREVASGN(elt, list, to, prev) \ - { \ - char **_alias = (char **) &((list)->prev); \ - *_alias = (char *) (to); \ - } -#define _RS(list) \ - { \ - char **_alias = (char **) &(list); \ - *_alias = _tmp; \ - } -#define _CASTASGN(a, b) \ - { \ - char **_alias = (char **) &(a); \ - *_alias = (char *) (b); \ - } -#else -#define _SV(elt, list) -#define _NEXT(elt, list, next) ((elt)->next) -#define _NEXTASGN(elt, list, to, next) ((elt)->next) = (to) -/* #define _PREV(elt,list,prev) ((elt)->prev) */ -#define _PREVASGN(elt, list, to, prev) ((elt)->prev) = (to) -#define _RS(list) -#define _CASTASGN(a, b) (a) = (b) -#endif - -/****************************************************************************** - * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * - * Unwieldy variable names used here to avoid shadowing passed-in variables. * - *****************************************************************************/ -#define LL_SORT(list, cmp) LL_SORT2 (list, cmp, next) - -#define LL_SORT2(list, cmp, next) \ - do { \ - LDECLTYPE (list) _ls_p; \ - LDECLTYPE (list) _ls_q; \ - LDECLTYPE (list) _ls_e; \ - LDECLTYPE (list) _ls_tail; \ - int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ - if (list) { \ - _ls_insize = 1; \ - _ls_looping = 1; \ - while (_ls_looping) { \ - _CASTASGN (_ls_p, list); \ - list = NULL; \ - _ls_tail = NULL; \ - _ls_nmerges = 0; \ - while (_ls_p) { \ - _ls_nmerges++; \ - _ls_q = _ls_p; \ - _ls_psize = 0; \ - for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ - _ls_psize++; \ - _SV (_ls_q, list); \ - _ls_q = _NEXT (_ls_q, list, next); \ - _RS (list); \ - if (!_ls_q) \ - break; \ - } \ - _ls_qsize = _ls_insize; \ - while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ - if (_ls_psize == 0) { \ - _ls_e = _ls_q; \ - _SV (_ls_q, list); \ - _ls_q = _NEXT (_ls_q, list, next); \ - _RS (list); \ - _ls_qsize--; \ - } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; \ - _SV (_ls_p, list); \ - _ls_p = _NEXT (_ls_p, list, next); \ - _RS (list); \ - _ls_psize--; \ - } else if (cmp (_ls_p, _ls_q) <= 0) { \ - _ls_e = _ls_p; \ - _SV (_ls_p, list); \ - _ls_p = _NEXT (_ls_p, list, next); \ - _RS (list); \ - _ls_psize--; \ - } else { \ - _ls_e = _ls_q; \ - _SV (_ls_q, list); \ - _ls_q = _NEXT (_ls_q, list, next); \ - _RS (list); \ - _ls_qsize--; \ - } \ - if (_ls_tail) { \ - _SV (_ls_tail, list); \ - _NEXTASGN (_ls_tail, list, _ls_e, next); \ - _RS (list); \ - } else { \ - _CASTASGN (list, _ls_e); \ - } \ - _ls_tail = _ls_e; \ - } \ - _ls_p = _ls_q; \ - } \ - if (_ls_tail) { \ - _SV (_ls_tail, list); \ - _NEXTASGN (_ls_tail, list, NULL, next); \ - _RS (list); \ - } \ - if (_ls_nmerges <= 1) { \ - _ls_looping = 0; \ - } \ - _ls_insize *= 2; \ - } \ - } \ - } while (0) - - -#define DL_SORT(list, cmp) DL_SORT2 (list, cmp, prev, next) - -#define DL_SORT2(list, cmp, prev, next) \ - do { \ - LDECLTYPE (list) _ls_p; \ - LDECLTYPE (list) _ls_q; \ - LDECLTYPE (list) _ls_e; \ - LDECLTYPE (list) _ls_tail; \ - int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ - if (list) { \ - _ls_insize = 1; \ - _ls_looping = 1; \ - while (_ls_looping) { \ - _CASTASGN (_ls_p, list); \ - list = NULL; \ - _ls_tail = NULL; \ - _ls_nmerges = 0; \ - while (_ls_p) { \ - _ls_nmerges++; \ - _ls_q = _ls_p; \ - _ls_psize = 0; \ - for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ - _ls_psize++; \ - _SV (_ls_q, list); \ - _ls_q = _NEXT (_ls_q, list, next); \ - _RS (list); \ - if (!_ls_q) \ - break; \ - } \ - _ls_qsize = _ls_insize; \ - while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ - if (_ls_psize == 0) { \ - _ls_e = _ls_q; \ - _SV (_ls_q, list); \ - _ls_q = _NEXT (_ls_q, list, next); \ - _RS (list); \ - _ls_qsize--; \ - } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; \ - _SV (_ls_p, list); \ - _ls_p = _NEXT (_ls_p, list, next); \ - _RS (list); \ - _ls_psize--; \ - } else if (cmp (_ls_p, _ls_q) <= 0) { \ - _ls_e = _ls_p; \ - _SV (_ls_p, list); \ - _ls_p = _NEXT (_ls_p, list, next); \ - _RS (list); \ - _ls_psize--; \ - } else { \ - _ls_e = _ls_q; \ - _SV (_ls_q, list); \ - _ls_q = _NEXT (_ls_q, list, next); \ - _RS (list); \ - _ls_qsize--; \ - } \ - if (_ls_tail) { \ - _SV (_ls_tail, list); \ - _NEXTASGN (_ls_tail, list, _ls_e, next); \ - _RS (list); \ - } else { \ - _CASTASGN (list, _ls_e); \ - } \ - _SV (_ls_e, list); \ - _PREVASGN (_ls_e, list, _ls_tail, prev); \ - _RS (list); \ - _ls_tail = _ls_e; \ - } \ - _ls_p = _ls_q; \ - } \ - _CASTASGN (list->prev, _ls_tail); \ - _SV (_ls_tail, list); \ - _NEXTASGN (_ls_tail, list, NULL, next); \ - _RS (list); \ - if (_ls_nmerges <= 1) { \ - _ls_looping = 0; \ - } \ - _ls_insize *= 2; \ - } \ - } \ - } while (0) - -#define CDL_SORT(list, cmp) CDL_SORT2 (list, cmp, prev, next) - -#define CDL_SORT2(list, cmp, prev, next) \ - do { \ - LDECLTYPE (list) _ls_p; \ - LDECLTYPE (list) _ls_q; \ - LDECLTYPE (list) _ls_e; \ - LDECLTYPE (list) _ls_tail; \ - LDECLTYPE (list) _ls_oldhead; \ - LDECLTYPE (list) _tmp; \ - int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ - if (list) { \ - _ls_insize = 1; \ - _ls_looping = 1; \ - while (_ls_looping) { \ - _CASTASGN (_ls_p, list); \ - _CASTASGN (_ls_oldhead, list); \ - list = NULL; \ - _ls_tail = NULL; \ - _ls_nmerges = 0; \ - while (_ls_p) { \ - _ls_nmerges++; \ - _ls_q = _ls_p; \ - _ls_psize = 0; \ - for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ - _ls_psize++; \ - _SV (_ls_q, list); \ - if (_NEXT (_ls_q, list, next) == _ls_oldhead) { \ - _ls_q = NULL; \ - } else { \ - _ls_q = _NEXT (_ls_q, list, next); \ - } \ - _RS (list); \ - if (!_ls_q) \ - break; \ - } \ - _ls_qsize = _ls_insize; \ - while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ - if (_ls_psize == 0) { \ - _ls_e = _ls_q; \ - _SV (_ls_q, list); \ - _ls_q = _NEXT (_ls_q, list, next); \ - _RS (list); \ - _ls_qsize--; \ - if (_ls_q == _ls_oldhead) { \ - _ls_q = NULL; \ - } \ - } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; \ - _SV (_ls_p, list); \ - _ls_p = _NEXT (_ls_p, list, next); \ - _RS (list); \ - _ls_psize--; \ - if (_ls_p == _ls_oldhead) { \ - _ls_p = NULL; \ - } \ - } else if (cmp (_ls_p, _ls_q) <= 0) { \ - _ls_e = _ls_p; \ - _SV (_ls_p, list); \ - _ls_p = _NEXT (_ls_p, list, next); \ - _RS (list); \ - _ls_psize--; \ - if (_ls_p == _ls_oldhead) { \ - _ls_p = NULL; \ - } \ - } else { \ - _ls_e = _ls_q; \ - _SV (_ls_q, list); \ - _ls_q = _NEXT (_ls_q, list, next); \ - _RS (list); \ - _ls_qsize--; \ - if (_ls_q == _ls_oldhead) { \ - _ls_q = NULL; \ - } \ - } \ - if (_ls_tail) { \ - _SV (_ls_tail, list); \ - _NEXTASGN (_ls_tail, list, _ls_e, next); \ - _RS (list); \ - } else { \ - _CASTASGN (list, _ls_e); \ - } \ - _SV (_ls_e, list); \ - _PREVASGN (_ls_e, list, _ls_tail, prev); \ - _RS (list); \ - _ls_tail = _ls_e; \ - } \ - _ls_p = _ls_q; \ - } \ - _CASTASGN (list->prev, _ls_tail); \ - _CASTASGN (_tmp, list); \ - _SV (_ls_tail, list); \ - _NEXTASGN (_ls_tail, list, _tmp, next); \ - _RS (list); \ - if (_ls_nmerges <= 1) { \ - _ls_looping = 0; \ - } \ - _ls_insize *= 2; \ - } \ - } \ - } while (0) - -/****************************************************************************** - * singly linked list macros (non-circular) * - *****************************************************************************/ -#define LL_PREPEND(head, add) LL_PREPEND2 (head, add, next) - -#define LL_PREPEND2(head, add, next) \ - do { \ - (add)->next = head; \ - head = add; \ - } while (0) - -#define LL_CONCAT(head1, head2) LL_CONCAT2 (head1, head2, next) - -#define LL_CONCAT2(head1, head2, next) \ - do { \ - LDECLTYPE (head1) _tmp; \ - if (head1) { \ - _tmp = head1; \ - while (_tmp->next) { \ - _tmp = _tmp->next; \ - } \ - _tmp->next = (head2); \ - } else { \ - (head1) = (head2); \ - } \ - } while (0) - -#define LL_APPEND(head, add) LL_APPEND2 (head, add, next) - -#define LL_APPEND2(head, add, next) \ - do { \ - LDECLTYPE (head) _tmp; \ - (add)->next = NULL; \ - if (head) { \ - _tmp = head; \ - while (_tmp->next) { \ - _tmp = _tmp->next; \ - } \ - _tmp->next = (add); \ - } else { \ - (head) = (add); \ - } \ - } while (0) - -#define LL_DELETE(head, del) LL_DELETE2 (head, del, next) - -#define LL_DELETE2(head, del, next) \ - do { \ - LDECLTYPE (head) _tmp; \ - if ((head) == (del)) { \ - (head) = (head)->next; \ - } else { \ - _tmp = head; \ - while (_tmp->next && (_tmp->next != (del))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = ((del)->next); \ - } \ - } \ - } while (0) - -/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ -#define LL_APPEND_VS2008(head, add) LL_APPEND2_VS2008 (head, add, next) - -#define LL_APPEND2_VS2008(head, add, next) \ - do { \ - if (head) { \ - (add)->next = head; /* use add->next as a temp variable */ \ - while ((add)->next->next) { \ - (add)->next = (add)->next->next; \ - } \ - (add)->next->next = (add); \ - } else { \ - (head) = (add); \ - } \ - (add)->next = NULL; \ - } while (0) - -#define LL_DELETE_VS2008(head, del) LL_DELETE2_VS2008 (head, del, next) - -#define LL_DELETE2_VS2008(head, del, next) \ - do { \ - if ((head) == (del)) { \ - (head) = (head)->next; \ - } else { \ - char *_tmp = (char *) (head); \ - while ((head)->next && ((head)->next != (del))) { \ - head = (head)->next; \ - } \ - if ((head)->next) { \ - (head)->next = ((del)->next); \ - } \ - { \ - char **_head_alias = (char **) &(head); \ - *_head_alias = _tmp; \ - } \ - } \ - } while (0) -#ifdef NO_DECLTYPE -#undef LL_APPEND -#define LL_APPEND LL_APPEND_VS2008 -#undef LL_DELETE -#define LL_DELETE LL_DELETE_VS2008 -#undef LL_DELETE2 -#define LL_DELETE2 LL_DELETE2_VS2008 -#undef LL_APPEND2 -#define LL_APPEND2 LL_APPEND2_VS2008 -#undef LL_CONCAT /* no LL_CONCAT_VS2008 */ -#undef DL_CONCAT /* no DL_CONCAT_VS2008 */ -#endif -/* end VS2008 replacements */ - -#define LL_COUNT(head, el, counter) LL_COUNT2 (head, el, counter, next) - -#define LL_COUNT2(head, el, counter, next) \ - { \ - counter = 0; \ - LL_FOREACH2 (head, el, next) \ - { \ - ++counter; \ - } \ - } - -#define LL_FOREACH(head, el) LL_FOREACH2 (head, el, next) - -#define LL_FOREACH2(head, el, next) for (el = head; el; el = (el)->next) - -#define LL_FOREACH_SAFE(head, el, tmp) LL_FOREACH_SAFE2 (head, el, tmp, next) - -#define LL_FOREACH_SAFE2(head, el, tmp, next) \ - for ((el) = (head); (el) && (tmp = (el)->next, 1); (el) = tmp) - -#define LL_SEARCH_SCALAR(head, out, field, val) \ - LL_SEARCH_SCALAR2 (head, out, field, val, next) - -#define LL_SEARCH_SCALAR2(head, out, field, val, next) \ - do { \ - LL_FOREACH2 (head, out, next) \ - { \ - if ((out)->field == (val)) \ - break; \ - } \ - } while (0) - -#define LL_SEARCH(head, out, elt, cmp) LL_SEARCH2 (head, out, elt, cmp, next) - -#define LL_SEARCH2(head, out, elt, cmp, next) \ - do { \ - LL_FOREACH2 (head, out, next) \ - { \ - if ((cmp (out, elt)) == 0) \ - break; \ - } \ - } while (0) - -#define LL_REPLACE_ELEM(head, el, add) \ - do { \ - LDECLTYPE (head) _tmp; \ - BSON_ASSERT (head != NULL); \ - BSON_ASSERT (el != NULL); \ - BSON_ASSERT (add != NULL); \ - (add)->next = (el)->next; \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - _tmp = head; \ - while (_tmp->next && (_tmp->next != (el))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = (add); \ - } \ - } \ - } while (0) - -#define LL_PREPEND_ELEM(head, el, add) \ - do { \ - LDECLTYPE (head) _tmp; \ - BSON_ASSERT (head != NULL); \ - BSON_ASSERT (el != NULL); \ - BSON_ASSERT (add != NULL); \ - (add)->next = (el); \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - _tmp = head; \ - while (_tmp->next && (_tmp->next != (el))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = (add); \ - } \ - } \ - } while (0) - - -/****************************************************************************** - * doubly linked list macros (non-circular) * - *****************************************************************************/ -#define DL_PREPEND(head, add) DL_PREPEND2 (head, add, prev, next) - -#define DL_PREPEND2(head, add, prev, next) \ - do { \ - (add)->next = head; \ - if (head) { \ - (add)->prev = (head)->prev; \ - (head)->prev = (add); \ - } else { \ - (add)->prev = (add); \ - } \ - (head) = (add); \ - } while (0) - -#define DL_APPEND(head, add) DL_APPEND2 (head, add, prev, next) - -#define DL_APPEND2(head, add, prev, next) \ - do { \ - if (head) { \ - (add)->prev = (head)->prev; \ - (head)->prev->next = (add); \ - (head)->prev = (add); \ - (add)->next = NULL; \ - } else { \ - (head) = (add); \ - (head)->prev = (head); \ - (head)->next = NULL; \ - } \ - } while (0) - -#define DL_CONCAT(head1, head2) DL_CONCAT2 (head1, head2, prev, next) - -#define DL_CONCAT2(head1, head2, prev, next) \ - do { \ - LDECLTYPE (head1) _tmp; \ - if (head2) { \ - if (head1) { \ - _tmp = (head2)->prev; \ - (head2)->prev = (head1)->prev; \ - (head1)->prev->next = (head2); \ - (head1)->prev = _tmp; \ - } else { \ - (head1) = (head2); \ - } \ - } \ - } while (0) - -#define DL_DELETE(head, del) DL_DELETE2 (head, del, prev, next) - -#define DL_DELETE2(head, del, prev, next) \ - do { \ - BSON_ASSERT ((del)->prev != NULL); \ - if ((del)->prev == (del)) { \ - (head) = NULL; \ - } else if ((del) == (head)) { \ - (del)->next->prev = (del)->prev; \ - (head) = (del)->next; \ - } else { \ - (del)->prev->next = (del)->next; \ - if ((del)->next) { \ - (del)->next->prev = (del)->prev; \ - } else { \ - (head)->prev = (del)->prev; \ - } \ - } \ - } while (0) - -#define DL_COUNT(head, el, counter) DL_COUNT2 (head, el, counter, next) - -#define DL_COUNT2(head, el, counter, next) \ - { \ - counter = 0; \ - DL_FOREACH2 (head, el, next) \ - { \ - ++counter; \ - } \ - } - -#define DL_FOREACH(head, el) DL_FOREACH2 (head, el, next) - -#define DL_FOREACH2(head, el, next) for (el = head; el; el = (el)->next) - -/* this version is safe for deleting the elements during iteration */ -#define DL_FOREACH_SAFE(head, el, tmp) DL_FOREACH_SAFE2 (head, el, tmp, next) - -#define DL_FOREACH_SAFE2(head, el, tmp, next) \ - for ((el) = (head); (el) && (tmp = (el)->next, 1); (el) = tmp) - -/* these are identical to their singly-linked list counterparts */ -#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR -#define DL_SEARCH LL_SEARCH -#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 -#define DL_SEARCH2 LL_SEARCH2 - -#define DL_REPLACE_ELEM(head, el, add) \ - do { \ - BSON_ASSERT (head != NULL); \ - BSON_ASSERT (el != NULL); \ - BSON_ASSERT (add != NULL); \ - if ((head) == (el)) { \ - (head) = (add); \ - (add)->next = (el)->next; \ - if ((el)->next == NULL) { \ - (add)->prev = (add); \ - } else { \ - (add)->prev = (el)->prev; \ - (add)->next->prev = (add); \ - } \ - } else { \ - (add)->next = (el)->next; \ - (add)->prev = (el)->prev; \ - (add)->prev->next = (add); \ - if ((el)->next == NULL) { \ - (head)->prev = (add); \ - } else { \ - (add)->next->prev = (add); \ - } \ - } \ - } while (0) - -#define DL_PREPEND_ELEM(head, el, add) \ - do { \ - BSON_ASSERT (head != NULL); \ - BSON_ASSERT (el != NULL); \ - BSON_ASSERT (add != NULL); \ - (add)->next = (el); \ - (add)->prev = (el)->prev; \ - (el)->prev = (add); \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - (add)->prev->next = (add); \ - } \ - } while (0) - - -/****************************************************************************** - * circular doubly linked list macros * - *****************************************************************************/ -#define CDL_PREPEND(head, add) CDL_PREPEND2 (head, add, prev, next) - -#define CDL_PREPEND2(head, add, prev, next) \ - do { \ - if (head) { \ - (add)->prev = (head)->prev; \ - (add)->next = (head); \ - (head)->prev = (add); \ - (add)->prev->next = (add); \ - } else { \ - (add)->prev = (add); \ - (add)->next = (add); \ - } \ - (head) = (add); \ - } while (0) - -#define CDL_DELETE(head, del) CDL_DELETE2 (head, del, prev, next) - -#define CDL_DELETE2(head, del, prev, next) \ - do { \ - if (((head) == (del)) && ((head)->next == (head))) { \ - (head) = 0L; \ - } else { \ - (del)->next->prev = (del)->prev; \ - (del)->prev->next = (del)->next; \ - if ((del) == (head)) \ - (head) = (del)->next; \ - } \ - } while (0) - -#define CDL_COUNT(head, el, counter) CDL_COUNT2 (head, el, counter, next) - -#define CDL_COUNT2(head, el, counter, next) \ - { \ - counter = 0; \ - CDL_FOREACH2 (head, el, next) \ - { \ - ++counter; \ - } \ - } - -#define CDL_FOREACH(head, el) CDL_FOREACH2 (head, el, next) - -#define CDL_FOREACH2(head, el, next) \ - for (el = head; el; el = ((el)->next == head ? 0L : (el)->next)) - -#define CDL_FOREACH_SAFE(head, el, tmp1, tmp2) \ - CDL_FOREACH_SAFE2 (head, el, tmp1, tmp2, prev, next) - -#define CDL_FOREACH_SAFE2(head, el, tmp1, tmp2, prev, next) \ - for ((el) = (head), ((tmp1) = (head) ? ((head)->prev) : NULL); \ - (el) && ((tmp2) = (el)->next, 1); \ - ((el) = (((el) == (tmp1)) ? 0L : (tmp2)))) - -#define CDL_SEARCH_SCALAR(head, out, field, val) \ - CDL_SEARCH_SCALAR2 (head, out, field, val, next) - -#define CDL_SEARCH_SCALAR2(head, out, field, val, next) \ - do { \ - CDL_FOREACH2 (head, out, next) \ - { \ - if ((out)->field == (val)) \ - break; \ - } \ - } while (0) - -#define CDL_SEARCH(head, out, elt, cmp) CDL_SEARCH2 (head, out, elt, cmp, next) - -#define CDL_SEARCH2(head, out, elt, cmp, next) \ - do { \ - CDL_FOREACH2 (head, out, next) \ - { \ - if ((cmp (out, elt)) == 0) \ - break; \ - } \ - } while (0) - -#define CDL_REPLACE_ELEM(head, el, add) \ - do { \ - BSON_ASSERT (head != NULL); \ - BSON_ASSERT (el != NULL); \ - BSON_ASSERT (add != NULL); \ - if ((el)->next == (el)) { \ - (add)->next = (add); \ - (add)->prev = (add); \ - (head) = (add); \ - } else { \ - (add)->next = (el)->next; \ - (add)->prev = (el)->prev; \ - (add)->next->prev = (add); \ - (add)->prev->next = (add); \ - if ((head) == (el)) { \ - (head) = (add); \ - } \ - } \ - } while (0) - -#define CDL_PREPEND_ELEM(head, el, add) \ - do { \ - BSON_ASSERT (head != NULL); \ - BSON_ASSERT (el != NULL); \ - BSON_ASSERT (add != NULL); \ - (add)->next = (el); \ - (add)->prev = (el)->prev; \ - (el)->prev = (add); \ - (add)->prev->next = (add); \ - if ((head) == (el)) { \ - (head) = (add); \ - } \ - } while (0) - -#endif /* UTLIST_H */ diff --git a/lib/mongoc/libmongoc/tests/.gitignore b/lib/mongoc/libmongoc/tests/.gitignore deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/lib/mongoc/libmongoc/tests/CMakeLists.txt b/lib/mongoc/libmongoc/tests/CMakeLists.txt deleted file mode 100644 index bf2080d370a6f8fe365a68f3e6a12b5f5aa71f89..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -file (GLOB_RECURSE src_libmongoc_tests_DIST_cs - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.c -) -file (GLOB_RECURSE src_libmongoc_tests_DIST_hs - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.h -) -file (GLOB_RECURSE src_libmongoc_tests_DIST_zeros - RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - *.0 -) -file (GLOB_RECURSE src_libmongoc_tests_DIST_pems - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.pem -) -file (GLOB_RECURSE src_libmongoc_tests_DIST_dats - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.dat -) -file (GLOB_RECURSE src_libmongoc_tests_DIST_txts - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.txt -) -file (GLOB_RECURSE src_libmongoc_tests_DIST_jsons - RELATIVE - ${CMAKE_CURRENT_SOURCE_DIR} - *.json -) - -set_dist_list (src_libmongoc_tests_DIST - CMakeLists.txt - ${src_libmongoc_tests_DIST_cs} - ${src_libmongoc_tests_DIST_hs} - ${src_libmongoc_tests_DIST_zeros} - ${src_libmongoc_tests_DIST_pems} - ${src_libmongoc_tests_DIST_dats} - ${src_libmongoc_tests_DIST_txts} - ${src_libmongoc_tests_DIST_jsons} -) diff --git a/lib/mongoc/libmongoc/tests/TestSuite.c b/lib/mongoc/libmongoc/tests/TestSuite.c deleted file mode 100644 index 16c243033abc94de310b1e4d7e8969d4eb50f481..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/TestSuite.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * Copyright 2014 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 <bson/bson.h> -#include <mongoc/mongoc.h> - -#include <fcntl.h> -#include <stdarg.h> - -#include "mongoc/mongoc-thread-private.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <mongoc/mongoc-util-private.h> -#if !defined(_WIN32) -#include <sys/types.h> -#include <inttypes.h> -#include <sys/utsname.h> -#include <sys/wait.h> -#include <unistd.h> -#include <sys/time.h> - -#else -#include <windows.h> -#endif - -#include "test-libmongoc.h" -#include "TestSuite.h" - - -static bson_once_t once = BSON_ONCE_INIT; -static bson_mutex_t gTestMutex; -static TestSuite *gTestSuite; - - -#define TEST_NOFORK (1 << 1) -#define TEST_HELPTEXT (1 << 2) -#define TEST_DEBUGOUTPUT (1 << 3) -#define TEST_TRACE (1 << 4) -#define TEST_VALGRIND (1 << 5) -#define TEST_LISTTESTS (1 << 6) - -MONGOC_PRINTF_FORMAT (1, 2) -static void -test_msg (const char *format, ...) -{ - va_list ap; - - va_start (ap, format); - vprintf (format, ap); - printf ("\n"); - fflush (stdout); - va_end (ap); -} - - -void -test_error (const char *format, ...) -{ - va_list ap; - - va_start (ap, format); - vfprintf (stderr, format, ap); - fprintf (stderr, "\n"); - fflush (stderr); - va_end (ap); - abort (); -} - -static void -TestSuite_SeedRand (TestSuite *suite, /* IN */ - Test *test) /* IN */ -{ -#ifndef BSON_OS_WIN32 - int fd = open ("/dev/urandom", O_RDONLY); - int n_read; - unsigned seed; - if (fd != -1) { - n_read = read (fd, &seed, 4); - BSON_ASSERT (n_read == 4); - close (fd); - test->seed = seed; - return; - } else { - test->seed = (unsigned) time (NULL) * (unsigned) getpid (); - } -#else - test->seed = (unsigned) time (NULL); -#endif -} - - -static BSON_ONCE_FUN (_test_suite_ensure_mutex_once) -{ - bson_mutex_init (&gTestMutex); - - BSON_ONCE_RETURN; -} - - -void -TestSuite_Init (TestSuite *suite, const char *name, int argc, char **argv) -{ - const char *filename; - int i; - char *mock_server_log; - - memset (suite, 0, sizeof *suite); - - suite->name = bson_strdup (name); - suite->flags = 0; - suite->prgname = bson_strdup (argv[0]); - suite->silent = false; - - for (i = 1; i < argc; i++) { - if (0 == strcmp ("-d", argv[i])) { - suite->flags |= TEST_DEBUGOUTPUT; - } else if ((0 == strcmp ("-f", argv[i])) || - (0 == strcmp ("--no-fork", argv[i]))) { - suite->flags |= TEST_NOFORK; - } else if ((0 == strcmp ("-t", argv[i])) || - (0 == strcmp ("--trace", argv[i]))) { -#ifdef MONGOC_TRACE - suite->flags |= TEST_TRACE; -#else - test_error ("-t requires mongoc compiled with -DENABLE_TRACING=ON."); -#endif - } else if (0 == strcmp ("-F", argv[i])) { - if (argc - 1 == i) { - test_error ("-F requires a filename argument."); - } - filename = argv[++i]; - if (0 != strcmp ("-", filename)) { -#ifdef _WIN32 - if (0 != fopen_s (&suite->outfile, filename, "w")) { - suite->outfile = NULL; - } -#else - suite->outfile = fopen (filename, "w"); -#endif - if (!suite->outfile) { - test_error ("Failed to open log file: %s", filename); - } - } - } else if ((0 == strcmp ("-h", argv[i])) || - (0 == strcmp ("--help", argv[i]))) { - suite->flags |= TEST_HELPTEXT; - } else if (0 == strcmp ("--list-tests", argv[i])) { - suite->flags |= TEST_LISTTESTS; - } else if ((0 == strcmp ("-s", argv[i])) || - (0 == strcmp ("--silent", argv[i]))) { - suite->silent = true; - } else if (0 == strcmp ("-l", argv[i])) { - if (argc - 1 == i) { - test_error ("-l requires an argument."); - } - suite->testname = bson_strdup (argv[++i]); - } else { - test_error ("Unknown option: %s\n" - "Try using the --help option.", - argv[i]); - } - } - - if (test_framework_getenv_bool ("MONGOC_TEST_VALGRIND")) { - suite->flags |= TEST_VALGRIND; - } - - mock_server_log = test_framework_getenv ("MONGOC_TEST_SERVER_LOG"); - if (mock_server_log) { - if (!strcmp (mock_server_log, "stdout")) { - suite->mock_server_log = stdout; - } else if (!strcmp (mock_server_log, "stderr")) { - suite->mock_server_log = stderr; - } else if (!strcmp (mock_server_log, "json")) { - suite->mock_server_log_buf = bson_string_new (NULL); - } else { - test_error ("Unrecognized option: MONGOC_TEST_SERVER_LOG=%s", - mock_server_log); - abort (); - } - - bson_free (mock_server_log); - } - - if (suite->silent) { - if (suite->outfile) { - test_error ("Cannot combine -F with --silent"); - abort (); - } - - suite->flags &= ~(TEST_DEBUGOUTPUT); - } - - bson_once (&once, &_test_suite_ensure_mutex_once); - bson_mutex_lock (&gTestMutex); - gTestSuite = suite; - bson_mutex_unlock (&gTestMutex); -} - - -int -TestSuite_CheckLive (void) -{ - return test_framework_getenv_bool ("MONGOC_TEST_SKIP_LIVE") ? 0 : 1; -} - -static int -TestSuite_CheckDummy (void) -{ - return 1; -} - -int -TestSuite_CheckMockServerAllowed (void) -{ - if (test_framework_getenv_bool ("MONGOC_TEST_SKIP_MOCK")) { - return 0; - } - return 1; -} - -static void -TestSuite_AddHelper (void *cb_) -{ - TestFunc cb = (TestFunc) cb_; - - cb (); -} - -void -TestSuite_Add (TestSuite *suite, /* IN */ - const char *name, /* IN */ - TestFunc func) /* IN */ -{ - TestSuite_AddFull (suite, - name, - TestSuite_AddHelper, - NULL, - (void *) func, - TestSuite_CheckDummy); -} - - -void -TestSuite_AddLive (TestSuite *suite, /* IN */ - const char *name, /* IN */ - TestFunc func) /* IN */ -{ - TestSuite_AddFull (suite, - name, - TestSuite_AddHelper, - NULL, - (void *) 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) { - fprintf (stderr, - "Too many check funcs for %s, increase MAX_TEST_CHECK_FUNCS " - "to more than %d\n", - name, - MAX_TEST_CHECK_FUNCS); - abort (); - } -} - - -Test * -_V_TestSuite_AddFull (TestSuite *suite, - const char *name, - TestFuncWC func, - TestFuncDtor dtor, - void *ctx, - va_list ap) -{ - CheckFunc check; - Test *test; - Test *iter; - - test = (Test *) calloc (1, sizeof *test); - test->name = bson_strdup (name); - test->func = func; - test->num_checks = 0; - - while ((check = va_arg (ap, CheckFunc))) { - _TestSuite_AddCheck (test, check, name); - } - - 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; -} - - -void -_TestSuite_AddMockServerTest (TestSuite *suite, - const char *name, - TestFunc func, - ...) -{ - Test *test; - va_list ap; - - va_start (ap, func); - test = _V_TestSuite_AddFull (suite, name, (TestFuncWC) func, NULL, NULL, ap); - va_end (ap); - - _TestSuite_AddCheck (test, TestSuite_CheckMockServerAllowed, name); -} - - -void -TestSuite_AddWC (TestSuite *suite, /* IN */ - const char *name, /* IN */ - TestFuncWC func, /* IN */ - TestFuncDtor dtor, /* IN */ - void *ctx) /* IN */ -{ - TestSuite_AddFull (suite, name, func, dtor, ctx, TestSuite_CheckDummy); -} - - -void -_TestSuite_AddFull (TestSuite *suite, /* IN */ - const char *name, /* IN */ - TestFuncWC func, /* IN */ - TestFuncDtor dtor, /* IN */ - void *ctx, - ...) /* IN */ -{ - va_list ap; - - va_start (ap, ctx); - _V_TestSuite_AddFull (suite, name, func, dtor, ctx, ap); - va_end (ap); -} - - -#if defined(_WIN32) -static void -_print_getlasterror_win (const char *msg) -{ - LPTSTR err_msg; - - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError (), - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - &err_msg, - 0, - NULL); - - test_error ("%s: %s", msg, err_msg); - - LocalFree (err_msg); -} - - -static int -TestSuite_RunFuncInChild (TestSuite *suite, /* IN */ - Test *test) /* IN */ -{ - STARTUPINFO si; - PROCESS_INFORMATION pi; - char *cmdline; - DWORD exit_code = -1; - - ZeroMemory (&si, sizeof (si)); - si.cb = sizeof (si); - ZeroMemory (&pi, sizeof (pi)); - - cmdline = bson_strdup_printf ( - "%s --silent --no-fork -l %s", suite->prgname, test->name); - - if (!CreateProcess (NULL, - cmdline, - NULL, /* Process handle not inheritable */ - NULL, /* Thread handle not inheritable */ - FALSE, /* Set handle inheritance to FALSE */ - 0, /* No creation flags */ - NULL, /* Use parent's environment block */ - NULL, /* Use parent's starting directory */ - &si, - &pi)) { - test_error ("CreateProcess failed (%d).", GetLastError ()); - bson_free (cmdline); - - return -1; - } - - if (WaitForSingleObject (pi.hProcess, INFINITE) != WAIT_OBJECT_0) { - _print_getlasterror_win ("Couldn't await process"); - goto done; - } - - if (!GetExitCodeProcess (pi.hProcess, &exit_code)) { - _print_getlasterror_win ("Couldn't get exit code"); - goto done; - } - -done: - CloseHandle (pi.hProcess); - CloseHandle (pi.hThread); - bson_free (cmdline); - - return exit_code; -} -#else /* Unix */ -static int -TestSuite_RunFuncInChild (TestSuite *suite, /* IN */ - Test *test) /* IN */ -{ - pid_t child; - int exit_code = -1; - int fd; - int pipefd[2]; - const char *envp[] = {"MONGOC_TEST_SERVER_LOG=stdout", NULL}; - char buf[4096]; - ssize_t nread; - - if (suite->outfile) { - fflush (suite->outfile); - } - - if (suite->mock_server_log_buf) { - if (pipe (pipefd) == -1) { - perror ("pipe"); - exit (-1); - } - } - - if (-1 == (child = fork ())) { - return -1; - } - - if (!child) { - if (suite->outfile) { - fclose (suite->outfile); - suite->outfile = NULL; - } - - if (suite->mock_server_log_buf) { - /* tell mock server to log to stdout, and read its output */ - 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); - } 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); - } - - exit (-1); - } - - if (suite->mock_server_log_buf) { - close (pipefd[1]); - while ((nread = read (pipefd[0], buf, sizeof (buf) - 1)) > 0) { - buf[nread] = '\0'; - bson_string_append (suite->mock_server_log_buf, buf); - } - } - - if (-1 == waitpid (child, &exit_code, 0)) { - perror ("waitpid()"); - } - - return exit_code; -} -#endif - - -/* replace " with \", newline with \n, tab with four spaces */ -static void -_append_json_escaped (bson_string_t *buf, const char *s) -{ - char *escaped = bson_utf8_escape_for_json (s, -1); - bson_string_append (buf, escaped); - bson_free (escaped); -} - - -/* returns 1 on failure, 0 on success */ -static int -TestSuite_RunTest (TestSuite *suite, /* IN */ - Test *test, /* IN */ - int *count) /* INOUT */ -{ - int64_t t1, t2, t3; - char name[MAX_TEST_NAME_LENGTH]; - bson_string_t *buf; - bson_string_t *mock_server_log_buf; - size_t i; - int status = 0; - - bson_snprintf (name, sizeof name, "%s%s", suite->name, test->name); - - buf = bson_string_new (NULL); - - if (suite->flags & TEST_DEBUGOUTPUT) { - test_msg ("Begin %s, seed %u", name, test->seed); - } - - for (i = 0; i < test->num_checks; i++) { - if (!test->checks[i]()) { - if (!suite->silent) { - bson_string_append_printf ( - buf, - " { \"status\": \"skip\", \"test_file\": \"%s\" }%s", - test->name, - ((*count) == 1) ? "" : ","); - test_msg ("%s", buf->str); - if (suite->outfile) { - fprintf (suite->outfile, "%s", buf->str); - fflush (suite->outfile); - } - } - - goto done; - } - } - - t1 = bson_get_monotonic_time (); - - - if (suite->flags & TEST_NOFORK) { -#ifdef MONGOC_TRACE - if (suite->flags & TEST_TRACE) { - mongoc_log_set_handler (mongoc_log_default_handler, NULL); - mongoc_log_trace_enable (); - } else { - mongoc_log_trace_disable (); - } -#endif - - srand (test->seed); - test->func (test->ctx); - } else { - status = TestSuite_RunFuncInChild (suite, test); - } - - capture_logs (false); - - if (suite->silent) { - goto done; - } - - t2 = bson_get_monotonic_time (); - t3 = t2 - t1; - /* CDRIVER-2567: check that bson_get_monotonic_time does not wrap. */ - BSON_ASSERT (t3 >= 0); - - bson_string_append_printf (buf, - " { \"status\": \"%s\", " - "\"test_file\": \"%s\", " - "\"seed\": \"%u\", " - "\"start\": %u.%06u, " - "\"end\": %u.%06u, " - "\"elapsed\": %u.%06u ", - (status == 0) ? "pass" : "fail", - name, - test->seed, - (unsigned) t1 / (1000 * 1000), - (unsigned) t1 % (1000 * 1000), - (unsigned) t2 / (1000 * 1000), - (unsigned) t2 % (1000 * 1000), - (unsigned) t3 / (1000 * 1000), - (unsigned) t3 % (1000 * 1000)); - - mock_server_log_buf = suite->mock_server_log_buf; - - if (mock_server_log_buf && mock_server_log_buf->len) { - bson_string_append (buf, ", \"log_raw\": \""); - _append_json_escaped (buf, mock_server_log_buf->str); - bson_string_append (buf, "\""); - - bson_string_truncate (mock_server_log_buf, 0); - } - - bson_string_append_printf (buf, " }"); - - if (*count > 1) { - bson_string_append_printf (buf, ","); - } - - test_msg ("%s", buf->str); - if (suite->outfile) { - fprintf (suite->outfile, "%s", buf->str); - fflush (suite->outfile); - } - -done: - bson_string_free (buf, true); - - return status ? 1 : 0; -} - - -static void -TestSuite_PrintHelp (TestSuite *suite) /* IN */ -{ - printf ("usage: %s [OPTIONS]\n" - "\n" - "Options:\n" - " -h, --help Show this help menu.\n" - " --list-tests Print list of available tests.\n" - " -f, --no-fork Do not spawn a process per test (abort on first " - "error).\n" - " -l NAME Run test by name, e.g. \"/Client/command\" or " - "\"/Client/*\".\n" - " -s, --silent Suppress all output.\n" - " -F FILENAME Write test results (JSON) to FILENAME.\n" - " -d Print debug output (useful if a test hangs).\n" - " -t, --trace Enable mongoc tracing (useful to debug tests).\n" - "\n", - suite->prgname); -} - - -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); - } - - printf ("\n"); -} - - -static void -TestSuite_PrintJsonSystemHeader (FILE *stream) -{ -#ifdef _WIN32 -#define INFO_BUFFER_SIZE 32767 - - SYSTEM_INFO si; - DWORD version = 0; - DWORD major_version = 0; - DWORD minor_version = 0; - DWORD build = 0; - - GetSystemInfo (&si); - version = GetVersion (); - - major_version = (DWORD) (LOBYTE (LOWORD (version))); - minor_version = (DWORD) (HIBYTE (LOWORD (version))); - - if (version < 0x80000000) { - build = (DWORD) (HIWORD (version)); - } - - fprintf (stream, - " \"host\": {\n" - " \"sysname\": \"Windows\",\n" - " \"release\": \"%ld.%ld (%ld)\",\n" - " \"machine\": \"%ld\",\n" - " \"memory\": {\n" - " \"pagesize\": %ld,\n" - " \"npages\": %d\n" - " }\n" - " },\n", - major_version, - minor_version, - build, - si.dwProcessorType, - si.dwPageSize, - 0); -#else - struct utsname u; - uint64_t pagesize; - uint64_t npages = 0; - - if (uname (&u) == -1) { - perror ("uname()"); - return; - } - - pagesize = sysconf (_SC_PAGE_SIZE); - -#if defined(_SC_PHYS_PAGES) - npages = sysconf (_SC_PHYS_PAGES); -#endif - fprintf (stream, - " \"host\": {\n" - " \"sysname\": \"%s\",\n" - " \"release\": \"%s\",\n" - " \"machine\": \"%s\",\n" - " \"memory\": {\n" - " \"pagesize\": %" PRIu64 ",\n" - " \"npages\": %" PRIu64 "\n" - " }\n" - " },\n", - u.sysname, - u.release, - u.machine, - pagesize, - npages); -#endif -} - -char * -egetenv (const char *name) -{ - return getenv (name) ? getenv (name) : ""; -} -static void -TestSuite_PrintJsonHeader (TestSuite *suite, /* IN */ - FILE *stream) /* IN */ -{ - char *hostname = test_framework_get_host (); - char *udspath = test_framework_get_unix_domain_socket_path_escaped (); - int port = test_framework_get_port (); - bool ssl = test_framework_get_ssl (); - - ASSERT (suite); - - fprintf (stream, "{\n"); - TestSuite_PrintJsonSystemHeader (stream); - fprintf (stream, - " \"auth\": { \"user\": \"%s\", \"pass\": \"%s\" }, \n" - " \"addr\": { \"host\": \"%s\", \"port\": %d, \"uri\": \"%s\" },\n" - " \"gssapi\": { \"host\": \"%s\", \"user\": \"%s\" }, \n" - " \"uds\": \"%s\", \n" - " \"compressors\": \"%s\", \n" - " \"SSL\": {\n" - " \"enabled\": %s,\n" - " \"weak_cert_validation\": %s,\n" - " \"pem_file\": \"%s\",\n" - " \"pem_pwd\": \"%s\",\n" - " \"ca_file\": \"%s\",\n" - " \"ca_dir\": \"%s\",\n" - " \"crl_file\": \"%s\"\n" - " },\n" - " \"framework\": {\n" - " \"monitoringVerbose\": %s,\n" - " \"mockServerLog\": \"%s\",\n" - " \"futureTimeoutMS\": %" PRIu64 ",\n" - " \"majorityReadConcern\": %s,\n" - " \"skipLiveTests\": %s,\n" - " \"IPv6\": %s\n" - " },\n" - " \"options\": {\n" - " \"fork\": %s,\n" - " \"tracing\": %s\n" - " },\n" - " \"results\": [\n", - egetenv ("MONGOC_TEST_USER"), - egetenv ("MONGOC_TEST_PASSWORD"), - hostname, - port, - egetenv ("MONGOC_TEST_URI"), - egetenv ("MONGOC_TEST_GSSAPI_HOST"), - egetenv ("MONGOC_TEST_GSSAPI_USER"), - udspath, - egetenv ("MONGOC_TEST_COMPRESSORS"), - ssl ? "true" : "false", - test_framework_getenv_bool ("MONGOC_TEST_SSL_WEAK_CERT_VALIDATION") - ? "true" - : "false", - egetenv ("MONGOC_TEST_SSL_PEM_FILE"), - egetenv ("MONGOC_TEST_SSL_PEM_PWD"), - egetenv ("MONGOC_TEST_SSL_CA_FILE"), - egetenv ("MONGOC_TEST_SSL_CA_DIR"), - egetenv ("MONGOC_TEST_SSL_CRL_FILE"), - getenv ("MONGOC_TEST_MONITORING_VERBOSE") ? "true" : "false", - egetenv ("MONGOC_TEST_SERVER_LOG"), - get_future_timeout_ms (), - test_framework_getenv_bool ("MONGOC_ENABLE_MAJORITY_READ_CONCERN") - ? "true" - : "false", - test_framework_getenv_bool ("MONGOC_TEST_SKIP_LIVE") ? "true" - : "false", - test_framework_getenv_bool ("MONGOC_CHECK_IPV6") ? "true" : "false", - (suite->flags & TEST_NOFORK) ? "false" : "true", - (suite->flags & TEST_TRACE) ? "true" : "false"); - - bson_free (hostname); - bson_free (udspath); - - fflush (stream); -} - - -static void -TestSuite_PrintJsonFooter (FILE *stream) /* IN */ -{ - fprintf (stream, " ]\n}\n"); - fflush (stream); -} - - -static int -TestSuite_RunSerial (TestSuite *suite) /* IN */ -{ - Test *test; - int count = 0; - int status = 0; - - for (test = suite->tests; test; test = test->next) { - count++; - } - - for (test = suite->tests; test; test = test->next) { - status += TestSuite_RunTest (suite, test, &count); - count--; - } - - if (suite->silent) { - return status; - } - - TestSuite_PrintJsonFooter (stdout); - if (suite->outfile) { - TestSuite_PrintJsonFooter (suite->outfile); - } - - return status; -} - - -static bool -TestSuite_TestMatchesName (const TestSuite *suite, - const Test *test, - const char *testname) -{ - char name[128]; - bool star = strlen (testname) && testname[strlen (testname) - 1] == '*'; - - bson_snprintf (name, sizeof name, "%s%s", suite->name, test->name); - - if (star) { - /* e.g. testname is "/Client*" and name is "/Client/authenticate" */ - return (0 == strncmp (name, testname, strlen (testname) - 1)); - } else { - return (0 == strcmp (name, testname)); - } -} - - -static int -TestSuite_RunNamed (TestSuite *suite, /* IN */ - const char *testname) /* IN */ -{ - Test *test; - int count = 0; - int status = 0; - - ASSERT (suite); - ASSERT (testname); - - /* initialize "count" so we can omit comma after last test output */ - for (test = suite->tests; test; test = test->next) { - if (TestSuite_TestMatchesName (suite, test, testname)) { - count++; - } - } - - for (test = suite->tests; test; test = test->next) { - if (TestSuite_TestMatchesName (suite, test, testname)) { - status += TestSuite_RunTest (suite, test, &count); - count--; - } - } - - if (suite->silent) { - return status; - } - - TestSuite_PrintJsonFooter (stdout); - if (suite->outfile) { - TestSuite_PrintJsonFooter (suite->outfile); - } - - return status; -} - - -int -TestSuite_Run (TestSuite *suite) /* IN */ -{ - int failures = 0; - - if (suite->flags & TEST_HELPTEXT) { - TestSuite_PrintHelp (suite); - } - - if (suite->flags & TEST_LISTTESTS) { - TestSuite_PrintTests (suite); - } - - if ((suite->flags & TEST_HELPTEXT) || (suite->flags & TEST_LISTTESTS)) { - return 0; - } - - if (!suite->silent) { - TestSuite_PrintJsonHeader (suite, stdout); - if (suite->outfile) { - TestSuite_PrintJsonHeader (suite, suite->outfile); - } - } - - if (suite->tests) { - if (suite->testname) { - failures += TestSuite_RunNamed (suite, suite->testname); - } else { - failures += TestSuite_RunSerial (suite); - } - } else if (!suite->silent) { - TestSuite_PrintJsonFooter (stdout); - if (suite->outfile) { - TestSuite_PrintJsonFooter (suite->outfile); - } - } - - 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); - } - free (test->name); - free (test); - } - - if (suite->outfile) { - fclose (suite->outfile); - } - - if (suite->mock_server_log_buf) { - bson_string_free (suite->mock_server_log_buf, true); - } - - free (suite->name); - free (suite->prgname); - free (suite->testname); -} - - -int -test_suite_debug_output (void) -{ - int ret; - - bson_mutex_lock (&gTestMutex); - ret = gTestSuite->flags & TEST_DEBUGOUTPUT; - bson_mutex_unlock (&gTestMutex); - - return ret; -} - - -int -test_suite_valgrind (void) -{ - int ret; - - bson_mutex_lock (&gTestMutex); - ret = gTestSuite->flags & TEST_VALGRIND; - bson_mutex_unlock (&gTestMutex); - - return ret; -} - - -MONGOC_PRINTF_FORMAT (1, 2) -void -test_suite_mock_server_log (const char *msg, ...) -{ - va_list ap; - char *formatted_msg; - - bson_mutex_lock (&gTestMutex); - - if (gTestSuite->mock_server_log || gTestSuite->mock_server_log_buf) { - va_start (ap, msg); - formatted_msg = bson_strdupv_printf (msg, ap); - va_end (ap); - - if (gTestSuite->mock_server_log_buf) { - bson_string_append_printf ( - gTestSuite->mock_server_log_buf, "%s\n", formatted_msg); - } else { - fprintf (gTestSuite->mock_server_log, "%s\n", formatted_msg); - fflush (gTestSuite->mock_server_log); - } - - bson_free (formatted_msg); - } - - bson_mutex_unlock (&gTestMutex); -} diff --git a/lib/mongoc/libmongoc/tests/TestSuite.h b/lib/mongoc/libmongoc/tests/TestSuite.h deleted file mode 100644 index e5f3213b3c08c1bf31d4ab423bd719f1c564fec8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/TestSuite.h +++ /dev/null @@ -1,717 +0,0 @@ -/* - * Copyright 2014 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 TEST_SUITE_H -#define TEST_SUITE_H - - -#include <bson/bson.h> -#include <stdio.h> -#include <math.h> -#include <stdlib.h> - -#include "mongoc/mongoc-util-private.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OS_RELEASE_FILE_DIR -#define OS_RELEASE_FILE_DIR "src/libmongoc/tests/release_files" -#endif - - -#ifndef BINARY_DIR -#define BINARY_DIR "src/libmongoc/tests/binary" -#endif - -#ifndef BSON_BINARY_DIR -#define BSON_BINARY_DIR "src/libbson/tests/binary" -#endif - -#ifndef JSON_DIR -#define JSON_DIR "src/libmongoc/tests/json" -#endif - -#ifndef BSON_JSON_DIR -#define BSON_JSON_DIR "src/libbson/tests/json" -#endif - -#ifndef CERT_TEST_DIR -#define CERT_TEST_DIR "src/libmongoc/tests/x509gen" -#endif - - -#ifdef BSON_OS_WIN32 -#include <stdarg.h> -#include <share.h> -static __inline int -bson_open (const char *filename, int flags, ...) -{ - int fd = -1; - - if (_sopen_s ( - &fd, filename, flags | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE) == - NO_ERROR) { - return fd; - } - - return -1; -} -#define bson_close _close -#define bson_read(f, b, c) ((ssize_t) _read ((f), (b), (int) (c))) -#define bson_write _write -#else -#define bson_open open -#define bson_read read -#define bson_close close -#define bson_write write -#endif - - -#define CERT_CA CERT_TEST_DIR "/ca.pem" -#define CERT_CRL CERT_TEST_DIR "/crl.pem" -#define CERT_SERVER CERT_TEST_DIR "/server.pem" /* 127.0.0.1 & localhost */ -#define CERT_CLIENT CERT_TEST_DIR "/client.pem" -#define CERT_ALTNAME \ - CERT_TEST_DIR "/altname.pem" /* alternative.mongodb.org \ - */ -#define CERT_WILD CERT_TEST_DIR "/wild.pem" /* *.mongodb.org */ -#define CERT_COMMONNAME \ - CERT_TEST_DIR "/commonName.pem" /* 127.0.0.1 & localhost */ -#define CERT_EXPIRED CERT_TEST_DIR "/expired.pem" /* 127.0.0.1 & localhost */ -#define CERT_PASSWORD "qwerty" -#define CERT_PASSWORD_PROTECTED CERT_TEST_DIR "/password_protected.pem" - - -void -test_error (const char *format, ...) BSON_GNUC_PRINTF (1, 2); - - -#define bson_eq_bson(bson, expected) \ - do { \ - char *bson_json, *expected_json; \ - const uint8_t *bson_data = bson_get_data ((bson)); \ - const uint8_t *expected_data = bson_get_data ((expected)); \ - int unequal; \ - unsigned o; \ - int off = -1; \ - unequal = ((expected)->len != (bson)->len) || \ - memcmp (bson_get_data ((expected)), \ - bson_get_data ((bson)), \ - (expected)->len); \ - if (unequal) { \ - bson_json = bson_as_canonical_extended_json (bson, NULL); \ - expected_json = bson_as_canonical_extended_json ((expected), NULL); \ - for (o = 0; o < (bson)->len && o < (expected)->len; o++) { \ - if (bson_data[o] != expected_data[o]) { \ - off = o; \ - break; \ - } \ - } \ - if (off == -1) { \ - off = BSON_MAX ((expected)->len, (bson)->len) - 1; \ - } \ - fprintf (stderr, \ - "bson objects unequal (byte %u):\n(%s)\n(%s)\n", \ - off, \ - bson_json, \ - expected_json); \ - { \ - int fd1 = bson_open ("failure.bad.bson", O_RDWR | O_CREAT, 0640); \ - int fd2 = \ - bson_open ("failure.expected.bson", O_RDWR | O_CREAT, 0640); \ - BSON_ASSERT (fd1 != -1); \ - BSON_ASSERT (fd2 != -1); \ - BSON_ASSERT ((bson)->len == \ - bson_write (fd1, bson_data, (bson)->len)); \ - BSON_ASSERT ((expected)->len == \ - bson_write (fd2, expected_data, (expected)->len)); \ - bson_close (fd1); \ - bson_close (fd2); \ - } \ - BSON_ASSERT (0); \ - } \ - } while (0) - - -#ifdef ASSERT -#undef ASSERT -#endif -#define ASSERT BSON_ASSERT - - -#ifdef ASSERT_OR_PRINT -#undef ASSERT_OR_PRINT -#endif - -#define ASSERT_OR_PRINT(_statement, _err) \ - do { \ - if (!(_statement)) { \ - fprintf (stderr, \ - "FAIL:%s:%d %s()\n %s\n %s\n\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - #_statement, \ - _err.message); \ - fflush (stderr); \ - abort (); \ - } \ - } while (0) - -#define ASSERT_CURSOR_NEXT(_cursor, _doc) \ - do { \ - bson_error_t _err; \ - if (!mongoc_cursor_next ((_cursor), (_doc))) { \ - if (mongoc_cursor_error ((_cursor), &_err)) { \ - fprintf (stderr, \ - "FAIL:%s:%d %s()\n %s\n\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - _err.message); \ - } else { \ - fprintf (stderr, \ - "FAIL:%s:%d %s()\n %s\n\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - "empty cursor"); \ - } \ - fflush (stderr); \ - abort (); \ - } \ - } while (0) - - -#define ASSERT_CURSOR_DONE(_cursor) \ - do { \ - bson_error_t _err; \ - const bson_t *_doc; \ - if (mongoc_cursor_next ((_cursor), &_doc)) { \ - fprintf (stderr, \ - "FAIL:%s:%d %s()\n %s\n\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - "non-empty cursor"); \ - fflush (stderr); \ - abort (); \ - } \ - if (mongoc_cursor_error ((_cursor), &_err)) { \ - fprintf (stderr, \ - "FAIL:%s:%d %s()\n %s\n\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - _err.message); \ - fflush (stderr); \ - abort (); \ - } \ - } while (0) - - -#define ASSERT_CMPINT_HELPER(a, eq, b, fmt, type) \ - do { \ - /* evaluate once */ \ - type _a = a; \ - type _b = b; \ - if (!((_a) eq (_b))) { \ - fprintf (stderr, \ - "FAIL\n\nAssert Failure: %" fmt " %s %" fmt "\n" \ - "%s:%d %s()\n", \ - _a, \ - #eq, \ - _b, \ - __FILE__, \ - __LINE__, \ - BSON_FUNC); \ - abort (); \ - } \ - } while (0) - - -#define ASSERT_CMPINT(a, eq, b) ASSERT_CMPINT_HELPER (a, eq, b, "d", int) -#define ASSERT_CMPUINT(a, eq, b) \ - ASSERT_CMPINT_HELPER (a, eq, b, "u", unsigned int) -#define ASSERT_CMPLONG(a, eq, b) ASSERT_CMPINT_HELPER (a, eq, b, "ld", long) -#define ASSERT_CMPULONG(a, eq, b) \ - ASSERT_CMPINT_HELPER (a, eq, b, "lu", unsigned long) -#define ASSERT_CMPINT32(a, eq, b) \ - ASSERT_CMPINT_HELPER (a, eq, b, PRId32, int32_t) -#define ASSERT_CMPINT64(a, eq, b) \ - ASSERT_CMPINT_HELPER (a, eq, b, PRId64, int64_t) -#define ASSERT_CMPUINT16(a, eq, b) \ - ASSERT_CMPINT_HELPER (a, eq, b, "hu", uint16_t) -#define ASSERT_CMPUINT32(a, eq, b) \ - ASSERT_CMPINT_HELPER (a, eq, b, PRIu32, uint32_t) -#define ASSERT_CMPUINT64(a, eq, b) \ - ASSERT_CMPINT_HELPER (a, eq, b, PRIu64, uint64_t) -#define ASSERT_CMPSIZE_T(a, eq, b) ASSERT_CMPINT_HELPER (a, eq, b, "zd", size_t) -#define ASSERT_CMPSSIZE_T(a, eq, b) \ - ASSERT_CMPINT_HELPER (a, eq, b, "zx", ssize_t) -#define ASSERT_CMPDOUBLE(a, eq, b) ASSERT_CMPINT_HELPER (a, eq, b, "f", double) -#define ASSERT_CMPVOID(a, eq, b) ASSERT_CMPINT_HELPER (a, eq, b, "p", void *) - -#define ASSERT_MEMCMP(a, b, n) \ - do { \ - if (0 != memcmp (a, b, n)) { \ - fprintf (stderr, \ - "Failed comparing %d bytes: \"%.*s\" != \"%.*s\"", \ - n, \ - n, \ - (char *) a, \ - n, \ - (char *) b); \ - abort (); \ - } \ - } while (0) - - -#ifdef ASSERT_ALMOST_EQUAL -#undef ASSERT_ALMOST_EQUAL -#endif -#define ASSERT_ALMOST_EQUAL(a, b) \ - do { \ - /* evaluate once */ \ - int64_t _a = (a); \ - int64_t _b = (b); \ - if (!(_a > (_b * 2) / 3 && (_a < (_b * 3) / 2))) { \ - fprintf (stderr, \ - "FAIL\n\nAssert Failure: %" PRId64 \ - " not within 50%% of %" PRId64 "\n" \ - "%s:%d %s()\n", \ - _a, \ - _b, \ - __FILE__, \ - __LINE__, \ - BSON_FUNC); \ - abort (); \ - } \ - } while (0) - -#ifdef ASSERT_EQUAL_DOUBLE -#undef ASSERT_EQUAL_DOUBLE -#endif -#define ASSERT_EQUAL_DOUBLE(a, b) \ - do { \ - double _a = fabs ((double) a); \ - double _b = fabs ((double) b); \ - if (!(_a > (_b * 4) / 5 && (_a < (_b * 6) / 5))) { \ - fprintf (stderr, \ - "FAIL\n\nAssert Failure: %f not within 20%% of %f\n" \ - "%s:%d %s()\n", \ - (double) a, \ - (double) b, \ - __FILE__, \ - __LINE__, \ - BSON_FUNC); \ - abort (); \ - } \ - } while (0) - - -#define ASSERT_CMPSTR(a, b) \ - do { \ - /* evaluate once */ \ - const char *_a = a; \ - const char *_b = b; \ - if (((_a) != (_b)) && !!strcmp ((_a), (_b))) { \ - fprintf ( \ - stderr, "FAIL\n\nAssert Failure: \"%s\" != \"%s\"\n", _a, _b); \ - abort (); \ - } \ - } while (0) - -#define ASSERT_CMPJSON(_a, _b) \ - do { \ - size_t i = 0; \ - char *__a = (char *) (_a); \ - char *__b = (char *) (_b); \ - char *__aa = bson_malloc0 (strlen (__a) + 1); \ - char *__bb = bson_malloc0 (strlen (__b) + 1); \ - char *f = __a; \ - do { \ - while (isspace (*__a)) \ - __a++; \ - __aa[i++] = *__a++; \ - } while (*__a); \ - i = 0; \ - do { \ - while (isspace (*__b)) \ - __b++; \ - __bb[i++] = *__b++; \ - } while (*__b); \ - if (!!strcmp ((__aa), (__bb))) { \ - fprintf (stderr, \ - "FAIL\n\nAssert Failure: \"%s\" != \"%s\"\n" \ - "%s:%d %s()\n", \ - __aa, \ - __bb, \ - __FILE__, \ - __LINE__, \ - BSON_FUNC); \ - abort (); \ - } \ - bson_free (__aa); \ - bson_free (__bb); \ - bson_free (f); \ - } while (0) - -#define ASSERT_CMPOID(a, b) \ - do { \ - if (bson_oid_compare ((a), (b))) { \ - char oid_a[25]; \ - char oid_b[25]; \ - bson_oid_to_string ((a), oid_a); \ - bson_oid_to_string ((b), oid_b); \ - fprintf (stderr, \ - "FAIL\n\nAssert Failure: " \ - "ObjectId(\"%s\") != ObjectId(\"%s\")\n", \ - oid_a, \ - oid_b); \ - abort (); \ - } \ - } while (0) - - -#define ASSERT_CONTAINS(a, b) \ - do { \ - char *_a_lower = bson_strdup (a); \ - char *_b_lower = bson_strdup (b); \ - mongoc_lowercase (_a_lower, _a_lower); \ - mongoc_lowercase (_b_lower, _b_lower); \ - if (NULL == strstr ((_a_lower), (_b_lower))) { \ - fprintf (stderr, \ - "%s:%d %s(): [%s] does not contain [%s]\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - a, \ - b); \ - abort (); \ - } \ - bson_free (_a_lower); \ - bson_free (_b_lower); \ - } while (0) - -#define ASSERT_STARTSWITH(a, b) \ - do { \ - /* evaluate once */ \ - const char *_a = a; \ - const char *_b = b; \ - if ((_a) != strstr ((_a), (_b))) { \ - fprintf (stderr, \ - "%s:%d %s(): : [%s] does not start with [%s]\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - _a, \ - _b); \ - abort (); \ - } \ - } while (0) - -#define ASSERT_ERROR_CONTAINS(error, _domain, _code, _message) \ - do { \ - if (error.domain != _domain) { \ - fprintf (stderr, \ - "%s:%d %s(): error domain %d doesn't match expected %d\n" \ - "error: \"%s\"", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - error.domain, \ - _domain, \ - error.message); \ - abort (); \ - }; \ - if (error.code != _code) { \ - fprintf (stderr, \ - "%s:%d %s(): error code %d doesn't match expected %d\n" \ - "error: \"%s\"", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - error.code, \ - _code, \ - error.message); \ - abort (); \ - }; \ - ASSERT_CONTAINS (error.message, _message); \ - } while (0); - -#define ASSERT_CAPTURED_LOG(_info, _level, _msg) \ - do { \ - if (!has_captured_log (_level, _msg)) { \ - fprintf (stderr, \ - "%s:%d %s(): testing %s didn't log \"%s\"\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - _info, \ - _msg); \ - print_captured_logs ("\t"); \ - abort (); \ - } \ - } while (0); - -#define ASSERT_NO_CAPTURED_LOGS(_info) \ - do { \ - if (has_captured_logs ()) { \ - fprintf (stderr, \ - "%s:%d %s(): testing %s shouldn't have logged:\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - _info); \ - print_captured_logs ("\t"); \ - abort (); \ - } \ - } while (0); - -#define ASSERT_HAS_FIELD(_bson, _field) \ - do { \ - if (!bson_has_field ((_bson), (_field))) { \ - fprintf (stderr, \ - "FAIL\n\nAssert Failure: No field \"%s\" in \"%s\"\n", \ - (_field), \ - bson_as_canonical_extended_json (_bson, NULL)); \ - abort (); \ - } \ - } while (0) - -#define ASSERT_HAS_NOT_FIELD(_bson, _field) \ - do { \ - if (bson_has_field ((_bson), (_field))) { \ - fprintf ( \ - stderr, \ - "FAIL\n\nAssert Failure: Unexpected field \"%s\" in \"%s\"\n", \ - (_field), \ - bson_as_canonical_extended_json (_bson, NULL)); \ - abort (); \ - } \ - } while (0) - -/* don't check durations when testing with valgrind */ -#define ASSERT_CMPTIME(actual, maxduration) \ - do { \ - if (!test_suite_valgrind ()) { \ - ASSERT_CMPINT (actual, <, maxduration); \ - } \ - } while (0) - -/* don't check durations when testing with valgrind */ -#define ASSERT_WITHIN_TIME_INTERVAL(actual, minduration, maxduration) \ - do { \ - if (!test_suite_valgrind ()) { \ - ASSERT_CMPINT (actual, >=, minduration); \ - ASSERT_CMPINT (actual, <, maxduration); \ - } \ - } while (0) - -#ifdef _WIN32 -#define gettestpid _getpid -#else -#define gettestpid getpid -#endif - -#define ASSERT_OR_PRINT_ERRNO(_statement, _errcode) \ - do { \ - if (!(_statement)) { \ - fprintf ( \ - stderr, \ - "FAIL:%s:%d %s()\n %s\n Failed with error code: %d (%s)\n\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - #_statement, \ - _errcode, \ - strerror (_errcode)); \ - fflush (stderr); \ - abort (); \ - } \ - } while (0) - -#define ASSERT_COUNT(n, collection) \ - do { \ - int count = (int) mongoc_collection_count_documents ( \ - collection, tmp_bson ("{}"), NULL, NULL, NULL, NULL); \ - if ((n) != count) { \ - fprintf (stderr, \ - "FAIL\n\nAssert Failure: count of %s is %d, not %d\n" \ - "%s:%d %s()\n", \ - mongoc_collection_get_name (collection), \ - count, \ - n, \ - __FILE__, \ - __LINE__, \ - BSON_FUNC); \ - abort (); \ - } \ - } while (0) - -#define ASSERT_CURSOR_COUNT(_n, _cursor) \ - do { \ - int _count = 0; \ - const bson_t *_doc; \ - while (mongoc_cursor_next (_cursor, &_doc)) { \ - _count++; \ - } \ - if ((_n) != _count) { \ - fprintf (stderr, \ - "FAIL\n\nAssert Failure: cursor count is %d, not %d\n" \ - "%s:%d %s()\n", \ - _count, \ - _n, \ - __FILE__, \ - __LINE__, \ - BSON_FUNC); \ - abort (); \ - } \ - } while (0) - -#define WAIT_UNTIL(_pred) \ - do { \ - int64_t _start = bson_get_monotonic_time (); \ - while (!(_pred)) { \ - if (bson_get_monotonic_time () - _start > 10 * 1000 * 1000) { \ - fprintf (stderr, \ - "Predicate \"%s\" timed out\n" \ - " %s:%d %s()\n", \ - #_pred, \ - __FILE__, \ - __LINE__, \ - BSON_FUNC); \ - abort (); \ - } \ - _mongoc_usleep (10 * 1000); \ - } \ - } while (0) - -#define ASSERT_WITH_MSG(_statement, ...) \ - do { \ - if (!(_statement)) { \ - fprintf (stderr, \ - "FAIL:%s:%d %s()\n %s\n\n", \ - __FILE__, \ - __LINE__, \ - BSON_FUNC, \ - #_statement); \ - fprintf (stderr, __VA_ARGS__); \ - fflush (stderr); \ - abort (); \ - } \ - } while (0) - -#define MAX_TEST_NAME_LENGTH 500 -#define MAX_TEST_CHECK_FUNCS 10 - - -typedef void (*TestFunc) (void); -typedef void (*TestFuncWC) (void *); -typedef void (*TestFuncDtor) (void *); -typedef int (*CheckFunc) (void); -typedef struct _Test Test; -typedef struct _TestSuite TestSuite; - - -struct _Test { - Test *next; - char *name; - TestFuncWC func; - TestFuncDtor dtor; - void *ctx; - int exit_code; - unsigned seed; - CheckFunc checks[MAX_TEST_CHECK_FUNCS]; - size_t num_checks; -}; - - -struct _TestSuite { - char *prgname; - char *name; - char *testname; - Test *tests; - FILE *outfile; - int flags; - int silent; - bson_string_t *mock_server_log_buf; - FILE *mock_server_log; -}; - - -void -TestSuite_Init (TestSuite *suite, const char *name, int argc, char **argv); -void -TestSuite_Add (TestSuite *suite, const char *name, TestFunc func); -int -TestSuite_CheckLive (void); -void -TestSuite_AddLive (TestSuite *suite, const char *name, TestFunc func); -int -TestSuite_CheckMockServerAllowed (void); -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); -Test * -_V_TestSuite_AddFull (TestSuite *suite, - const char *name, - TestFuncWC func, - TestFuncDtor dtor, - void *ctx, - va_list ap); -void -_TestSuite_AddFull (TestSuite *suite, - const char *name, - TestFuncWC func, - TestFuncDtor dtor, - void *ctx, - ...); -#define TestSuite_AddFull(_suite, _name, _func, _dtor, _ctx, ...) \ - _TestSuite_AddFull (_suite, _name, _func, _dtor, _ctx, __VA_ARGS__, NULL) -int -TestSuite_Run (TestSuite *suite); -void -TestSuite_Destroy (TestSuite *suite); - -int -test_suite_debug_output (void); -int -test_suite_valgrind (void); -void -test_suite_mock_server_log (const char *msg, ...); - -#ifdef __cplusplus -} -#endif - - -#endif /* TEST_SUITE_H */ diff --git a/lib/mongoc/libmongoc/tests/binary/delete1.dat b/lib/mongoc/libmongoc/tests/binary/delete1.dat deleted file mode 100644 index 83fcc33c303fb9b0cd92df7a5e5a2b7134f11ff6..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/delete1.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/empty.dat b/lib/mongoc/libmongoc/tests/binary/empty.dat deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/lib/mongoc/libmongoc/tests/binary/get_more1.dat b/lib/mongoc/libmongoc/tests/binary/get_more1.dat deleted file mode 100644 index 506750a53665392340a0a900a7222e6cce47195c..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/get_more1.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/gridfs-large.dat b/lib/mongoc/libmongoc/tests/binary/gridfs-large.dat deleted file mode 100644 index 541d1e3face8472221581d1b20f8347f620b43e2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/binary/gridfs-large.dat +++ /dev/null @@ -1,945 +0,0 @@ -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. diff --git a/lib/mongoc/libmongoc/tests/binary/gridfs.dat b/lib/mongoc/libmongoc/tests/binary/gridfs.dat deleted file mode 100644 index c80106fe6db38f33a4d9b0d4b418e92c17ff3b51..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/binary/gridfs.dat +++ /dev/null @@ -1,9 +0,0 @@ -Bacon ipsum dolor sit amet capicola meatloaf prosciutto, pork swine biltong hamburger brisket pancetta venison fatback tenderloin pastrami frankfurter jowl. Short ribs ball tip rump doner t-bone. Shank flank short loin biltong pig. T-bone swine capicola, pork loin pork chop ribeye cow salami brisket shank meatloaf turducken. Venison short ribs beef, meatloaf salami spare ribs jerky biltong frankfurter bresaola boudin jowl pork loin meatball short loin. Chicken cow tri-tip bacon jerky prosciutto t-bone pork chop pork beef. Strip steak ball tip tail, rump swine pork prosciutto short ribs drumstick venison pork belly beef ribs ribeye. - -Kevin swine turducken leberkas pastrami filet mignon shoulder brisket. Short loin kevin jerky, t-bone salami turducken ball tip doner boudin fatback turkey pork loin. Pork chop andouille leberkas short loin drumstick bresaola t-bone tenderloin rump shoulder jowl shank beef. Hamburger pork loin pancetta jowl sausage, short ribs flank. - -Hamburger frankfurter beef fatback spare ribs ribeye. Kielbasa chicken kevin bresaola corned beef tail cow pork chop fatback. Brisket pork chop meatloaf, corned beef flank sausage shank turkey kielbasa kevin. Shoulder shankle salami, filet mignon bacon tenderloin prosciutto kevin flank drumstick ribeye pig. Cow jerky ball tip drumstick sirloin pig pork beef ribs prosciutto leberkas. Ball tip t-bone ham, pig ham hock chuck meatloaf tail boudin turducken. - -Frankfurter chuck beef corned beef bresaola cow pancetta capicola turkey andouille. Pork ribeye frankfurter pastrami, chuck turkey meatball. Pig t-bone bacon drumstick ham hock capicola pork loin bresaola meatball kevin tri-tip. Biltong beef ribs jowl short ribs drumstick flank, strip steak t-bone sausage capicola pork loin frankfurter corned beef. Doner pork drumstick salami biltong. Pastrami cow ribeye beef drumstick salami, biltong beef ribs flank turducken pork belly meatball spare ribs swine. - -Flank leberkas doner, pork shank ham hock drumstick pork loin corned beef. Turducken shankle sirloin boudin venison ball tip pancetta. Tenderloin shank ham swine, fatback pastrami ground round kevin beef ribs ham hock turducken spare ribs leberkas meatball. Spare ribs andouille brisket beef ribs tail, bresaola swine. Strip steak bresaola sausage t-bone kevin chicken beef swine corned beef ball tip ham hock jerky kielbasa chuck. Tail venison salami pancetta beef, frankfurter bresaola beef ribs turkey ham ham hock turducken meatball rump jerky. diff --git a/lib/mongoc/libmongoc/tests/binary/insert1.dat b/lib/mongoc/libmongoc/tests/binary/insert1.dat deleted file mode 100644 index 1beac44192240ff670171be947f7ad533120f4b6..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/insert1.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/kill_cursors1.dat b/lib/mongoc/libmongoc/tests/binary/kill_cursors1.dat deleted file mode 100644 index f1de925f304f6e5d961616e3b1654e630c557fcc..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/kill_cursors1.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/msg1.dat b/lib/mongoc/libmongoc/tests/binary/msg1.dat deleted file mode 100644 index f543db9fcd29b30aa699e82ac0031d10fd59ca10..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/msg1.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/query1.dat b/lib/mongoc/libmongoc/tests/binary/query1.dat deleted file mode 100644 index b4ed389d56431b33c243b8f7016a492c49e43c74..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/query1.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/query2.dat b/lib/mongoc/libmongoc/tests/binary/query2.dat deleted file mode 100644 index 7f14bb831b610e43f9d4f07d9f26ae7226417e32..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/query2.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/reply1.dat b/lib/mongoc/libmongoc/tests/binary/reply1.dat deleted file mode 100644 index 9f3ca21d468430ff329c3455219cb6e38742ff5e..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/reply1.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/reply2.dat b/lib/mongoc/libmongoc/tests/binary/reply2.dat deleted file mode 100644 index 91907275ed084128b22f2064c686164f39e70cce..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/reply2.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/binary/update1.dat b/lib/mongoc/libmongoc/tests/binary/update1.dat deleted file mode 100644 index cd5e2c9503f3eb7672ab1296efbb305ccd1690de..0000000000000000000000000000000000000000 Binary files a/lib/mongoc/libmongoc/tests/binary/update1.dat and /dev/null differ diff --git a/lib/mongoc/libmongoc/tests/debug-stream.c b/lib/mongoc/libmongoc/tests/debug-stream.c deleted file mode 100644 index 5c0a394f4c8cb178d43603948947751657b4bc1f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/debug-stream.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2015 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 DEBUG_STREAM_H -#define DEBUG_STREAM_H - -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-client-private.h> - -#include "test-libmongoc.h" - - -#define MONGOC_STREAM_DEBUG 7 -typedef struct _mongoc_stream_debug_t { - mongoc_stream_t vtable; - mongoc_stream_t *wrapped; - debug_stream_stats_t *stats; -} mongoc_stream_debug_t; - - -static int -_mongoc_stream_debug_close (mongoc_stream_t *stream) -{ - return mongoc_stream_close (((mongoc_stream_debug_t *) stream)->wrapped); -} - - -static void -_mongoc_stream_debug_destroy (mongoc_stream_t *stream) -{ - mongoc_stream_debug_t *debug_stream = (mongoc_stream_debug_t *) stream; - - debug_stream->stats->n_destroyed++; - - mongoc_stream_destroy (debug_stream->wrapped); - bson_free (debug_stream); -} - - -static void -_mongoc_stream_debug_failed (mongoc_stream_t *stream) -{ - mongoc_stream_debug_t *debug_stream = (mongoc_stream_debug_t *) stream; - - debug_stream->stats->n_failed++; - - mongoc_stream_failed (debug_stream->wrapped); - bson_free (debug_stream); -} - - -static int -_mongoc_stream_debug_setsockopt (mongoc_stream_t *stream, - int level, - int optname, - void *optval, - mongoc_socklen_t optlen) -{ - return mongoc_stream_setsockopt (((mongoc_stream_debug_t *) stream)->wrapped, - level, - optname, - optval, - optlen); -} - - -static int -_mongoc_stream_debug_flush (mongoc_stream_t *stream) -{ - return mongoc_stream_flush (((mongoc_stream_debug_t *) stream)->wrapped); -} - - -static ssize_t -_mongoc_stream_debug_readv (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - size_t min_bytes, - int32_t timeout_msec) -{ - return mongoc_stream_readv (((mongoc_stream_debug_t *) stream)->wrapped, - iov, - iovcnt, - min_bytes, - timeout_msec); -} - - -static ssize_t -_mongoc_stream_debug_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - return mongoc_stream_writev ( - ((mongoc_stream_debug_t *) stream)->wrapped, iov, iovcnt, timeout_msec); -} - - -static bool -_mongoc_stream_debug_check_closed (mongoc_stream_t *stream) -{ - return mongoc_stream_check_closed ( - ((mongoc_stream_debug_t *) stream)->wrapped); -} - - -static bool -_mongoc_stream_debug_timed_out (mongoc_stream_t *stream) -{ - return mongoc_stream_timed_out (((mongoc_stream_debug_t *) stream)->wrapped); -} - - -static bool -_mongoc_stream_debug_should_retry (mongoc_stream_t *stream) -{ - return mongoc_stream_should_retry ( - ((mongoc_stream_debug_t *) stream)->wrapped); -} - - -static mongoc_stream_t * -_mongoc_stream_debug_get_base_stream (mongoc_stream_t *stream) -{ - mongoc_stream_t *wrapped = ((mongoc_stream_debug_t *) stream)->wrapped; - - /* "wrapped" is typically a mongoc_stream_buffered_t, get the real - * base stream */ - if (wrapped->get_base_stream) { - return wrapped->get_base_stream (wrapped); - } - - return wrapped; -} - - -mongoc_stream_t * -debug_stream_new (mongoc_stream_t *stream, debug_stream_stats_t *stats) -{ - mongoc_stream_debug_t *debug_stream; - - if (!stream) { - return NULL; - } - - debug_stream = (mongoc_stream_debug_t *) bson_malloc0 (sizeof *debug_stream); - - debug_stream->vtable.type = MONGOC_STREAM_DEBUG; - debug_stream->vtable.close = _mongoc_stream_debug_close; - debug_stream->vtable.destroy = _mongoc_stream_debug_destroy; - debug_stream->vtable.failed = _mongoc_stream_debug_failed; - debug_stream->vtable.flush = _mongoc_stream_debug_flush; - debug_stream->vtable.readv = _mongoc_stream_debug_readv; - debug_stream->vtable.writev = _mongoc_stream_debug_writev; - debug_stream->vtable.setsockopt = _mongoc_stream_debug_setsockopt; - debug_stream->vtable.check_closed = _mongoc_stream_debug_check_closed; - debug_stream->vtable.timed_out = _mongoc_stream_debug_timed_out; - debug_stream->vtable.should_retry = _mongoc_stream_debug_should_retry; - debug_stream->vtable.get_base_stream = _mongoc_stream_debug_get_base_stream; - - debug_stream->wrapped = stream; - debug_stream->stats = stats; - - return (mongoc_stream_t *) debug_stream; -} - - -mongoc_stream_t * -debug_stream_initiator (const mongoc_uri_t *uri, - const mongoc_host_list_t *host, - void *user_data, - bson_error_t *error) -{ - debug_stream_stats_t *stats; - mongoc_stream_t *default_stream; - - stats = (debug_stream_stats_t *) user_data; - - default_stream = - mongoc_client_default_stream_initiator (uri, host, stats->client, error); - - return debug_stream_new (default_stream, stats); -} - - -void -test_framework_set_debug_stream (mongoc_client_t *client, - debug_stream_stats_t *stats) -{ - stats->client = client; - mongoc_client_set_stream_initiator (client, debug_stream_initiator, stats); -} - -#endif /* DEBUG_STREAM_H */ diff --git a/lib/mongoc/libmongoc/tests/json-test-monitoring.c b/lib/mongoc/libmongoc/tests/json-test-monitoring.c deleted file mode 100644 index fcbe541a6c4da8f091ceeefd420bdfdf56ce9abd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json-test-monitoring.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright 2018-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 "mongoc/mongoc-config.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-server-description-private.h" -#include "mongoc/mongoc-topology-description-private.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-util-private.h" - -#include "TestSuite.h" -#include "test-conveniences.h" - -#include "json-test.h" -#include "json-test-operations.h" -#include "test-libmongoc.h" - -#ifdef _MSC_VER -#include <io.h> -#else -#include <dirent.h> -#endif - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - -static bool -ends_with (const char *s, const char *suffix) -{ - size_t s_len; - size_t suffix_len; - - if (!s) { - return false; - } - - s_len = strlen (s); - suffix_len = strlen (suffix); - return s_len >= suffix_len && !strcmp (s + s_len - suffix_len, suffix); -} - -/* test that an event's "host" field is set to a reasonable value */ -static void -assert_host_in_uri (const mongoc_host_list_t *host, const mongoc_uri_t *uri) -{ - const mongoc_host_list_t *hosts; - - hosts = mongoc_uri_get_hosts (uri); - while (hosts) { - if (_mongoc_host_list_equal (hosts, host)) { - return; - } - - hosts = hosts->next; - } - - fprintf (stderr, - "Host \"%s\" not in \"%s\"", - host->host_and_port, - mongoc_uri_get_string (uri)); - fflush (stderr); - abort (); -} - - -static void -started_cb (const mongoc_apm_command_started_t *event) -{ - json_test_ctx_t *ctx = - (json_test_ctx_t *) mongoc_apm_command_started_get_context (event); - char *cmd_json; - bson_t *events = &ctx->events; - char str[16]; - const char *key; - bson_t *new_event; - - if (ctx->verbose) { - cmd_json = bson_as_canonical_extended_json (event->command, NULL); - printf ("%s\n", cmd_json); - fflush (stdout); - bson_free (cmd_json); - } - - BSON_ASSERT (mongoc_apm_command_started_get_request_id (event) > 0); - BSON_ASSERT (mongoc_apm_command_started_get_server_id (event) > 0); - /* check that event->host is sane */ - assert_host_in_uri (event->host, ctx->test_framework_uri); - new_event = BCON_NEW ("command_started_event", - "{", - "command", - BCON_DOCUMENT (event->command), - "command_name", - BCON_UTF8 (event->command_name), - "database_name", - BCON_UTF8 (event->database_name), - "operation_id", - BCON_INT64 (event->operation_id), - "}"); - - bson_uint32_to_string (ctx->n_events, &key, str, sizeof str); - BSON_APPEND_DOCUMENT (events, key, new_event); - - ctx->n_events++; - - bson_destroy (new_event); -} - - -static void -succeeded_cb (const mongoc_apm_command_succeeded_t *event) -{ - json_test_ctx_t *ctx = - (json_test_ctx_t *) mongoc_apm_command_succeeded_get_context (event); - char *reply_json; - char str[16]; - const char *key; - bson_t *new_event; - - if (ctx->verbose) { - reply_json = bson_as_canonical_extended_json (event->reply, NULL); - printf ("\t\t<-- %s\n", reply_json); - fflush (stdout); - bson_free (reply_json); - } - - BSON_ASSERT (mongoc_apm_command_succeeded_get_request_id (event) > 0); - BSON_ASSERT (mongoc_apm_command_succeeded_get_server_id (event) > 0); - assert_host_in_uri (event->host, ctx->test_framework_uri); - new_event = BCON_NEW ("command_succeeded_event", - "{", - "reply", - BCON_DOCUMENT (event->reply), - "command_name", - BCON_UTF8 (event->command_name), - "operation_id", - BCON_INT64 (event->operation_id), - "}"); - - bson_uint32_to_string (ctx->n_events, &key, str, sizeof str); - BSON_APPEND_DOCUMENT (&ctx->events, key, new_event); - - ctx->n_events++; - - bson_destroy (new_event); -} - - -static void -failed_cb (const mongoc_apm_command_failed_t *event) -{ - json_test_ctx_t *ctx = - (json_test_ctx_t *) mongoc_apm_command_failed_get_context (event); - bson_t reply = BSON_INITIALIZER; - char str[16]; - const char *key; - bson_t *new_event; - - if (ctx->verbose) { - printf ( - "\t\t<-- %s FAILED: %s\n", event->command_name, event->error->message); - fflush (stdout); - } - - BSON_ASSERT (mongoc_apm_command_failed_get_request_id (event) > 0); - BSON_ASSERT (mongoc_apm_command_failed_get_server_id (event) > 0); - assert_host_in_uri (event->host, ctx->test_framework_uri); - - new_event = BCON_NEW ("command_failed_event", - "{", - "command_name", - BCON_UTF8 (event->command_name), - "operation_id", - BCON_INT64 (event->operation_id), - "}"); - - bson_uint32_to_string (ctx->n_events, &key, str, sizeof str); - BSON_APPEND_DOCUMENT (&ctx->events, key, new_event); - - ctx->n_events++; - - bson_destroy (new_event); - bson_destroy (&reply); -} - - -void -set_apm_callbacks (json_test_ctx_t *ctx, mongoc_client_t *client) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, started_cb); - - if (!ctx->config->command_started_events_only) { - mongoc_apm_set_command_succeeded_cb (callbacks, succeeded_cb); - mongoc_apm_set_command_failed_cb (callbacks, failed_cb); - } - - mongoc_client_set_apm_callbacks (client, callbacks, ctx); - mongoc_apm_callbacks_destroy (callbacks); -} - - -static bool -lsids_match (const bson_t *a, const bson_t *b) -{ - return match_bson (a, b, false); -} - - -typedef struct { - char *command_name; - int64_t cursor_id; - bson_t lsids[2]; -} apm_match_visitor_ctx_t; - - -void -apm_match_visitor_ctx_reset (apm_match_visitor_ctx_t *ctx) -{ - bson_free (ctx->command_name); - ctx->command_name = NULL; -} - - -static match_action_t -apm_match_visitor (match_ctx_t *ctx, - bson_iter_t *pattern_iter, - bson_iter_t *doc_iter) -{ - const char *key = bson_iter_key (pattern_iter); - apm_match_visitor_ctx_t *visitor_ctx = - (apm_match_visitor_ctx_t *) ctx->visitor_ctx; - -#define SHOULD_EXIST \ - do { \ - if (!doc_iter) { \ - match_err (ctx, "expected %s", key); \ - return MATCH_ACTION_ABORT; \ - } \ - } while (0) -#define IS_COMMAND(cmd) (ends_with (ctx->path, "command") && !strcmp (key, cmd)) - - if (ends_with (ctx->path, "command") && !visitor_ctx->command_name && - doc_iter) { - visitor_ctx->command_name = bson_strdup (bson_iter_key (doc_iter)); - } - - if (IS_COMMAND ("find") || IS_COMMAND ("aggregate")) { - /* New query. Next server reply or getMore will set cursor_id. */ - visitor_ctx->cursor_id = 0; - } else if (!strcmp (key, "id") && ends_with (ctx->path, "cursor")) { - visitor_ctx->cursor_id = bson_iter_as_int64 (doc_iter); - } else if (!strcmp (key, "errmsg")) { - /* "errmsg values of "" MUST assert that the value is not empty" */ - const char *errmsg = bson_iter_utf8 (pattern_iter, NULL); - - if (strcmp (errmsg, "") == 0) { - if (!doc_iter || bson_iter_type (doc_iter) != BSON_TYPE_UTF8 || - strlen (bson_iter_utf8 (doc_iter, NULL)) == 0) { - match_err (ctx, "expected non-empty 'errmsg'"); - return MATCH_ACTION_ABORT; - } - return MATCH_ACTION_SKIP; - } - } else if (IS_COMMAND ("getMore")) { - /* "When encountering a cursor or getMore value of "42" in a test, the - * driver MUST assert that the values are equal to each other and - * greater than zero." - */ - SHOULD_EXIST; - if (visitor_ctx->cursor_id == 0) { - /* A cursor id may not have been set in the visitor context if the spec - * test only checked command started events. Set the cursor_id now, so - * it can at least verify subsequent getMores use with the same id. */ - visitor_ctx->cursor_id = bson_iter_as_int64 (doc_iter); - } else if (visitor_ctx->cursor_id != bson_iter_as_int64 (doc_iter)) { - match_err (ctx, - "cursor requested in getMore (%" PRId64 - ") does not match previously seen (%" PRId64 ")", - bson_iter_as_int64 (doc_iter), - visitor_ctx->cursor_id); - return MATCH_ACTION_ABORT; - } - } else if (!strcmp (key, "lsid")) { - const char *session_name = bson_iter_utf8 (pattern_iter, NULL); - bson_t lsid; - bool fail = false; - - SHOULD_EXIST; - bson_iter_bson (doc_iter, &lsid); - - /* Transactions tests: "Each command-started event in "expectations" - * includes an lsid with the value "session0" or "session1". Tests MUST - * assert that the command's actual lsid matches the id of the correct - * ClientSession named session0 or session1." */ - if (!strcmp (session_name, "session0") && - !lsids_match (&visitor_ctx->lsids[0], &lsid)) { - fail = true; - } - - if (!strcmp (session_name, "session1") && - !lsids_match (&visitor_ctx->lsids[1], &lsid)) { - fail = true; - } - - if (fail) { - char *str = bson_as_json (&lsid, NULL); - match_err ( - ctx, "expected %s, but used session: %s", session_name, str); - bson_free (str); - return MATCH_ACTION_ABORT; - } else { - return MATCH_ACTION_SKIP; - } - } else if (strstr (ctx->path, "updates.")) { - /* tests expect "multi: false" and "upsert: false" explicitly; - * we don't send them. fix when path is like "updates.0", "updates.1", ... - */ - - if (!strcmp (key, "multi") && !bson_iter_bool (pattern_iter)) { - return MATCH_ACTION_SKIP; - } - if (!strcmp (key, "upsert") && !bson_iter_bool (pattern_iter)) { - return MATCH_ACTION_SKIP; - } - } else if (visitor_ctx->command_name && - !strcmp (visitor_ctx->command_name, "findAndModify") && - !strcmp (key, "new")) { - /* transaction tests expect "new: false" explicitly; we don't send it */ - return MATCH_ACTION_SKIP; - } - - return MATCH_ACTION_CONTINUE; -} - - -/* - *----------------------------------------------------------------------- - * - * check_json_apm_events -- - * - * Compare actual APM events with expected sequence. The two docs - * are each like: - * - * [ - * { - * "command_started_event": { - * "command": { ... }, - * "command_name": "count", - * "database_name": "command-monitoring-tests", - * "operation_id": 123 - * } - * }, - * { - * "command_failed_event": { - * "command_name": "count", - * "operation_id": 123 - * } - * } - * ] - * - * If @allow_subset is true, then expectations is allowed to be - * a subset of events. - * - *----------------------------------------------------------------------- - */ -void -check_json_apm_events (json_test_ctx_t *ctx, const bson_t *expectations) -{ - bson_iter_t expectations_iter, actual_iter; - bool allow_subset; - match_ctx_t match_ctx = {{0}}; - apm_match_visitor_ctx_t apm_match_visitor_ctx = {0}; - int i; - - for (i = 0; i < 2; i++) { - bson_copy_to (&ctx->lsids[i], &apm_match_visitor_ctx.lsids[i]); - } - - /* Old mongod returns a double for "count", newer returns int32. - * Ignore this and other insignificant type differences. */ - match_ctx.strict_numeric_types = false; - match_ctx.retain_dots_in_keys = true; - match_ctx.allow_placeholders = true; - match_ctx.visitor_fn = apm_match_visitor; - match_ctx.visitor_ctx = (void *) &apm_match_visitor_ctx; - - allow_subset = ctx->config->command_monitoring_allow_subset; - - BSON_ASSERT (bson_iter_init (&expectations_iter, expectations)); - BSON_ASSERT (bson_iter_init (&actual_iter, &ctx->events)); - - /* Compare the captured actual events against the expectations. */ - while (bson_iter_next (&expectations_iter)) { - bson_t expectation, actual; - bool matched = false; - - bson_iter_bson (&expectations_iter, &expectation); - /* match against the current actual event, and possibly skip actual events - * if we allow subset matching. */ - while (bson_iter_next (&actual_iter)) { - bson_iter_bson (&actual_iter, &actual); - matched = match_bson_with_ctx (&actual, &expectation, &match_ctx); - apm_match_visitor_ctx_reset (&apm_match_visitor_ctx); - bson_destroy (&actual); - - if (matched) { - break; - } - - if (allow_subset) { - /* if we allow matching only a subset of actual events, skip - * non-matching ones */ - continue; - } else { - test_error ("could not match APM event\n" - "\texpected: %s\n\n" - "\tactual : %s\n\n" - "\terror : %s\n\n", - bson_as_canonical_extended_json (&expectation, NULL), - bson_as_canonical_extended_json (&actual, NULL), - match_ctx.errmsg); - } - } - - if (!matched) { - test_error ("expectation unmatched\n" - "\texpected: %s\n\n", - bson_as_canonical_extended_json (&expectation, NULL)); - } - - bson_destroy (&expectation); - } - - /* If we do not allow matching against a subset of actual events, check if - * there are extra "actual" events */ - if (!allow_subset && bson_iter_next (&actual_iter)) { - bson_t extra; - - bson_iter_bson (&actual_iter, &extra); - test_error ("extra actual event was not found in expectations: %s\n", - bson_as_canonical_extended_json (&extra, NULL)); - } - - for (i = 0; i < 2; i++) { - bson_destroy (&apm_match_visitor_ctx.lsids[i]); - } -} - - -/* Test that apm_match_visitor verifies the cursor id requested in a getMore - * is the same cursor id returned in a find reply. */ -void -test_apm_matching (void) -{ - apm_match_visitor_ctx_t match_visitor_ctx = {0}; - match_ctx_t match_ctx = {{0}}; - - const char *e1 = "{" - " 'command_succeeded_event': {" - " 'command_name': 'find'," - " 'reply': {'cursor': { 'id': 123 }}" - " }" - "}"; - - const char *e2 = "{" - " 'command_started_event': {" - " 'command_name': 'getMore'," - " 'command': {'getMore': 124}" - " }" - "}"; - - match_ctx.visitor_fn = apm_match_visitor; - match_ctx.visitor_ctx = (void *) &match_visitor_ctx; - - BSON_ASSERT (match_bson_with_ctx (tmp_bson (e1), tmp_bson (e1), &match_ctx)); - BSON_ASSERT ( - !match_bson_with_ctx (tmp_bson (e2), tmp_bson (e2), &match_ctx)); - ASSERT_CONTAINS (match_ctx.errmsg, "cursor requested in getMore"); - apm_match_visitor_ctx_reset (&match_visitor_ctx); -} - - -void -test_apm_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/apm_test_matching", test_apm_matching); -} diff --git a/lib/mongoc/libmongoc/tests/json-test-monitoring.h b/lib/mongoc/libmongoc/tests/json-test-monitoring.h deleted file mode 100644 index c495adf198d740d0cdfbcaac3c50cfbde6077085..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json-test-monitoring.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2018-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 JSON_TEST_MONITORING_H -#define JSON_TEST_MONITORING_H - -#include "TestSuite.h" - -#include <bson/bson.h> -#include <mongoc/mongoc.h> - -#include "test-conveniences.h" -#include "json-test-operations.h" - -typedef void (*json_test_events_check_cb_t) (const bson_t *events); - -void -set_apm_callbacks (json_test_ctx_t *ctx, mongoc_client_t *client); - -void -check_json_apm_events (json_test_ctx_t *ctx, const bson_t *expectations); - -#endif diff --git a/lib/mongoc/libmongoc/tests/json-test-operations.c b/lib/mongoc/libmongoc/tests/json-test-operations.c deleted file mode 100644 index 4547bc70ae6c38b532796e8a258192df7e15f27f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json-test-operations.c +++ /dev/null @@ -1,2031 +0,0 @@ -/* - * Copyright 2018-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 "bson/bson.h" - -#include "mongoc/mongoc-change-stream-private.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-config.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-server-description-private.h" -#include "mongoc/mongoc-topology-description-private.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-util-private.h" - -#include "json-test-operations.h" -#include "json-test.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "TestSuite.h" - - -mongoc_client_session_t * -session_from_name (json_test_ctx_t *ctx, const char *session_name) -{ - BSON_ASSERT (session_name); - - if (!strcmp (session_name, "session0")) { - return ctx->sessions[0]; - } else if (!strcmp (session_name, "session1")) { - return ctx->sessions[1]; - } else { - MONGOC_ERROR ("Unrecognized session name: %s", session_name); - abort (); - } -} - - -void -json_test_ctx_init (json_test_ctx_t *ctx, - const bson_t *test, - mongoc_client_t *client, - mongoc_database_t *db, - mongoc_collection_t *collection, - const json_test_config_t *config) -{ - char *session_name; - char *session_opts_path; - int i; - bson_error_t error; - - ctx->client = client; - ctx->db = db; - ctx->collection = collection; - ctx->change_stream = NULL; - ctx->config = config; - ctx->n_events = 0; - bson_init (&ctx->events); - - ctx->test_framework_uri = mongoc_uri_copy (client->uri); - ctx->acknowledged = true; - ctx->verbose = test_framework_getenv_bool ("MONGOC_TEST_MONITORING_VERBOSE"); - bson_init (&ctx->lsids[0]); - bson_init (&ctx->lsids[1]); - ctx->sessions[0] = NULL; - ctx->sessions[1] = NULL; - ctx->has_sessions = test_framework_session_timeout_minutes () > -1 && - test_framework_skip_if_no_crypto (); - - /* transactions tests require two sessions named session1 and session2, - * retryable writes use one explicit session or none */ - if (ctx->has_sessions) { - for (i = 0; i < 2; i++) { - session_name = bson_strdup_printf ("session%d", i); - session_opts_path = bson_strdup_printf ("sessionOptions.session%d", i); - if (bson_has_field (test, session_opts_path)) { - ctx->sessions[i] = - bson_lookup_session (test, session_opts_path, client); - } else { - ctx->sessions[i] = - mongoc_client_start_session (client, NULL, &error); - } - - ASSERT_OR_PRINT (ctx->sessions[i], error); - bson_concat (&ctx->lsids[i], - mongoc_client_session_get_lsid (ctx->sessions[i])); - - bson_free (session_name); - bson_free (session_opts_path); - } - } -} - - -void -json_test_ctx_end_sessions (json_test_ctx_t *ctx) -{ - int i; - - if (ctx->has_sessions) { - for (i = 0; i < 2; i++) { - if (ctx->sessions[i]) { - mongoc_client_session_destroy (ctx->sessions[i]); - ctx->sessions[i] = NULL; - } - } - } -} - - -void -json_test_ctx_cleanup (json_test_ctx_t *ctx) -{ - json_test_ctx_end_sessions (ctx); - mongoc_change_stream_destroy (ctx->change_stream); - bson_destroy (&ctx->lsids[0]); - bson_destroy (&ctx->lsids[1]); - bson_destroy (&ctx->events); - mongoc_uri_destroy (ctx->test_framework_uri); -} - - -static void -append_session (mongoc_client_session_t *session, bson_t *opts) -{ - if (session) { - bool r; - bson_error_t error; - - r = mongoc_client_session_append (session, opts, &error); - ASSERT_OR_PRINT (r, error); - } -} - -static char * -value_to_str (const bson_value_t *value) -{ - bson_t doc; - - if (value->value_type == BSON_TYPE_DOCUMENT || - value->value_type == BSON_TYPE_ARRAY) { - bson_init_from_value (&doc, value); - return bson_as_json (&doc, NULL); - } else { - return bson_strdup_printf ("%" PRId64, bson_value_as_int64 (value)); - } -} - - -static void -convert_bulk_write_result (const bson_t *doc, bson_t *r) -{ - bson_iter_t iter; - - ASSERT (bson_iter_init (&iter, doc)); - - /* tests expect "insertedCount" etc. from the CRUD Spec for bulk write, - * we return "nInserted" etc. from the old Bulk API Spec */ - while (bson_iter_next (&iter)) { - if (BSON_ITER_IS_KEY (&iter, "insertedCount")) { - BSON_APPEND_VALUE (r, "nInserted", bson_iter_value (&iter)); - } else if (BSON_ITER_IS_KEY (&iter, "deletedCount")) { - BSON_APPEND_VALUE (r, "nRemoved", bson_iter_value (&iter)); - } else if (BSON_ITER_IS_KEY (&iter, "matchedCount")) { - BSON_APPEND_VALUE (r, "nMatched", bson_iter_value (&iter)); - } else if (BSON_ITER_IS_KEY (&iter, "modifiedCount")) { - BSON_APPEND_VALUE (r, "nModified", bson_iter_value (&iter)); - } else if (BSON_ITER_IS_KEY (&iter, "upsertedCount")) { - BSON_APPEND_VALUE (r, "nUpserted", bson_iter_value (&iter)); - } else if (BSON_ITER_IS_KEY (&iter, "upsertedIds")) { - bson_t upserted; - bson_iter_t inner; - uint32_t i = 0; - - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - - /* include the "upserted" field if upsertedIds isn't empty */ - ASSERT (bson_iter_recurse (&iter, &inner)); - while (bson_iter_next (&inner)) { - i++; - } - - if (i) { - i = 0; - ASSERT (bson_iter_recurse (&iter, &inner)); - BSON_APPEND_ARRAY_BEGIN (r, "upserted", &upserted); - - while (bson_iter_next (&inner)) { - bson_t upsert; - const char *keyptr = NULL; - char key[12]; - int64_t index; - - bson_uint32_to_string (i++, &keyptr, key, sizeof key); - index = bson_ascii_strtoll (bson_iter_key (&inner), NULL, 10); - - BSON_APPEND_DOCUMENT_BEGIN (&upserted, keyptr, &upsert); - BSON_APPEND_INT32 (&upsert, "index", (int32_t) index); - BSON_APPEND_VALUE (&upsert, "_id", bson_iter_value (&inner)); - bson_append_document_end (&upserted, &upsert); - } - - bson_append_array_end (r, &upserted); - } - } else if (BSON_ITER_IS_KEY (&iter, "insertedIds")) { - /* tests expect insertedIds, but they're optional and we omit them */ - } else { - BSON_APPEND_VALUE (r, bson_iter_key (&iter), bson_iter_value (&iter)); - } - } -} - - -/* convert from spec result in JSON test to a libmongoc result */ -static void -convert_spec_result (const char *op_name, - const bson_value_t *spec_result, - bson_value_t *converted) -{ - bson_t doc; - bson_t r; - bson_iter_t iter; - - if (spec_result->value_type != BSON_TYPE_DOCUMENT && - spec_result->value_type != BSON_TYPE_ARRAY) { - bson_value_copy (spec_result, converted); - return; - } - - bson_init (&r); - bson_init_from_value (&doc, spec_result); - ASSERT (bson_iter_init (&iter, &doc)); - - if (!strcmp (op_name, "bulkWrite")) { - convert_bulk_write_result (&doc, &r); - } else { - /* tests expect "upsertedCount": 0, we add "upsertedCount" only if it's - * not zero. tests also expect insertedId or insertedIds, but they are - * optional and we omit them. */ - while (bson_iter_next (&iter)) { - if (BSON_ITER_IS_KEY (&iter, "upsertedCount")) { - if (bson_iter_as_int64 (&iter) != 0) { - BSON_APPEND_INT64 ( - &r, "upsertedCount", bson_iter_as_int64 (&iter)); - } - } else if (!BSON_ITER_IS_KEY (&iter, "insertedId") && - !BSON_ITER_IS_KEY (&iter, "insertedIds")) { - BSON_APPEND_VALUE ( - &r, bson_iter_key (&iter), bson_iter_value (&iter)); - } - } - } - - /* copies r's contents */ - value_init_from_doc (converted, &r); - /* preserve spec tests' distinction between array and document */ - converted->value_type = spec_result->value_type; - bson_destroy (&r); -} - - -static bool -get_result (const bson_t *test, const bson_t *operation, bson_value_t *value) -{ - const char *op_name; - bson_value_t pre_conversion; - - /* retryable writes tests specify result at the end of the whole test: - * operation: - * name: insertOne - * arguments: ... - * outcome: - * result: - * insertedId: 3 - * - * transactions tests specify the result of each operation: - * operations: - * - name: insertOne - * arguments: ... - * result: - * insertedId: 3 - * - * command monitoring tests have no results - */ - if (bson_has_field (test, "outcome.result")) { - bson_lookup_value (test, "outcome.result", &pre_conversion); - } else if (bson_has_field (operation, "result")) { - bson_lookup_value (operation, "result", &pre_conversion); - } else { - return false; - } - - op_name = bson_lookup_utf8 (operation, "name"); - convert_spec_result (op_name, &pre_conversion, value); - bson_value_destroy (&pre_conversion); - return true; -} - - -static void -check_success_expected (const bson_t *operation, - bool succeeded, - bool expected, - const bson_error_t *error) -{ - char *json = bson_as_json (operation, NULL); - - if (!succeeded && expected) { - test_error ( - "Expected success, got error \"%s\":\n%s", error->message, json); - } - if (succeeded && !expected) { - test_error ("Expected error, got success:\n%s", json); - } - - bson_free (json); -} - - -static uint32_t -error_code_from_name (const char *name) -{ - if (!strcmp (name, "CannotSatisfyWriteConcern")) { - return 100; - } else if (!strcmp (name, "DuplicateKey")) { - return 11000; - } else if (!strcmp (name, "NoSuchTransaction")) { - return 251; - } else if (!strcmp (name, "WriteConflict")) { - return 112; - } else if (!strcmp (name, "Interrupted")) { - return 11601; - } else if (!strcmp (name, "MaxTimeMSExpired")) { - return 50; - } else if (!strcmp (name, "UnknownReplWriteConcern")) { - return 79; - } else if (!strcmp (name, "UnsatisfiableWriteConcern")) { - return 100; - } else if (!strcmp (name, "OperationNotSupportedInTransaction")) { - return 263; - } - - test_error ("Add errorCodeName \"%s\" to error_code_from_name()", name); - - /* test_error() aborts, but add a return to suppress compiler warnings */ - return 0; -} - - -static void -check_error_code_name (const bson_t *operation, const bson_error_t *error) -{ - const char *code_name; - uint32_t expected_error_code; - - if (!bson_has_field (operation, "errorCodeName")) { - return; - } - - code_name = bson_lookup_utf8 (operation, "errorCodeName"); - expected_error_code = error_code_from_name (code_name); - if (error->code != expected_error_code) { - test_error ("Expected error code %d : %s but got error code %d\n", - expected_error_code, - code_name, - error->code); - } -} - - -static void -check_error_contains (const bson_t *operation, const bson_error_t *error) -{ - const char *msg; - - if (!bson_has_field (operation, "errorContains")) { - return; - } - - msg = bson_lookup_utf8 (operation, "errorContains"); - - ASSERT_CONTAINS (error->message, msg); -} - - -static void -check_error_labels_contain (const bson_t *operation, const bson_value_t *result) -{ - bson_t reply; - bson_iter_t operation_iter; - bson_iter_t expected_labels; - bson_iter_t expected_label; - const char *expected_label_str; - - if (!bson_has_field (operation, "errorLabelsContain")) { - return; - } - - BSON_ASSERT (bson_iter_init (&operation_iter, operation)); - BSON_ASSERT (bson_iter_find_descendant ( - &operation_iter, "errorLabelsContain", &expected_labels)); - BSON_ASSERT (bson_iter_recurse (&expected_labels, &expected_label)); - - /* if the test has "errorLabelsContain" then result must be an error reply */ - ASSERT_CMPSTR (_mongoc_bson_type_to_str (result->value_type), "DOCUMENT"); - bson_init_from_value (&reply, result); - - while (bson_iter_next (&expected_label)) { - expected_label_str = bson_iter_utf8 (&expected_label, NULL); - if (!mongoc_error_has_label (&reply, expected_label_str)) { - test_error ("Expected label \"%s\" not found in %s", - expected_label_str, - bson_as_json (&reply, NULL)); - } - } -} - - -static void -check_error_labels_omit (const bson_t *operation, const bson_value_t *result) -{ - bson_t reply; - bson_t omitted_labels; - bson_iter_t omitted_label; - - if (!bson_has_field (operation, "errorLabelsOmit")) { - return; - } - - if (result->value_type != BSON_TYPE_DOCUMENT) { - /* successful result from count, distinct, etc. */ - return; - } - - bson_init_from_value (&reply, result); - if (!bson_has_field (&reply, "errorLabels")) { - return; - } - - bson_lookup_doc (operation, "errorLabelsOmit", &omitted_labels); - BSON_ASSERT (bson_iter_init (&omitted_label, &omitted_labels)); - while (bson_iter_next (&omitted_label)) { - if (mongoc_error_has_label (&reply, - bson_iter_utf8 (&omitted_label, NULL))) { - test_error ("Label \"%s\" should have been omitted %s", - bson_iter_utf8 (&omitted_label, NULL), - value_to_str (result)); - } - } -} - - -/*-------------------------------------------------------------------------- - * - * check_result -- - * - * Verify that a function call's outcome matches the expected outcome. - * - * Consider a JSON test like: - * - * operations: - * - name: insertOne - * arguments: - * document: - * _id: 1 - * session: session0 - * result: - * insertedId: 1 - * - * @test is the BSON representation of the entire test including the - * "operations" array, @operation is one of the documents in array, - * @succeeded is true if the function call actually succeeded, @result - * is the function call's result (optional), and @error is the call's - * error (optional). - * - * Side effects: - * Logs and aborts if the outcome does not match the expected outcome. - * - *-------------------------------------------------------------------------- - */ - -void -check_result (const bson_t *test, - const bson_t *operation, - bool succeeded, - const bson_value_t *result, - const bson_error_t *error) -{ - bson_t expected_doc; - bson_value_t expected_value; - match_ctx_t ctx = {{0}}; - - if (!get_result (test, operation, &expected_value)) { - /* if there's no "result", e.g. in the command monitoring tests, - * we don't know if the command is expected to succeed or fail */ - return; - } - - if (expected_value.value_type == BSON_TYPE_DOCUMENT) { - bson_init_from_value (&expected_doc, &expected_value); - if (bson_has_field (&expected_doc, "errorCodeName") || - bson_has_field (&expected_doc, "errorContains") || - bson_has_field (&expected_doc, "errorLabelsContain") || - bson_has_field (&expected_doc, "errorLabelsOmit")) { - /* Expect the operation has failed. Transactions tests specify errors - * per-operation, with one or more details: - * operations: - * - name: insertOne - * arguments: ... - * result: - * errorCodeName: WriteConflict - * errorContains: "message substring" - * errorLabelsContain: ["TransientTransactionError"] - * errorLabelsOmit: ["UnknownTransactionCommitResult"] - */ - check_success_expected (&expected_doc, succeeded, false, error); - check_error_code_name (&expected_doc, error); - check_error_contains (&expected_doc, error); - check_error_labels_contain (&expected_doc, result); - check_error_labels_omit (&expected_doc, result); - bson_value_destroy (&expected_value); - return; - } - } - - /* retryable writes tests and CRUD tests specify error: <bool> at the end of - * the whole test: - * operation: - * name: insertOne - * outcome: - * error: true - */ - - check_success_expected (operation, - succeeded, - !_mongoc_lookup_bool (test, "outcome.error", false), - error); - - BSON_ASSERT (result); - - /* Database-level aggregate tests use $currentOp, which may return a command - * document containing dots in keys. Retain these as we do for APM checks. */ - ctx.retain_dots_in_keys = true; - - if (!match_bson_value (result, &expected_value, &ctx)) { - test_error ("Error in \"%s\" test %s\n" - "Expected:\n%s\nActual:\n%s", - bson_lookup_utf8 (test, "description"), - ctx.errmsg, - value_to_str (&expected_value), - value_to_str (result)); - } - - bson_value_destroy (&expected_value); -} - - -static bool -add_request_to_bulk (mongoc_bulk_operation_t *bulk, - const bson_t *request, - bson_error_t *error) -{ - const char *name; - bson_t args; - bool r; - bson_t opts = BSON_INITIALIZER; - - name = bson_lookup_utf8 (request, "name"); - bson_lookup_doc (request, "arguments", &args); - - if (bson_has_field (&args, "arrayFilters")) { - bson_value_t array_filters; - bson_lookup_value (&args, "arrayFilters", &array_filters); - BSON_APPEND_VALUE (&opts, "arrayFilters", &array_filters); - bson_value_destroy (&array_filters); - } - - if (bson_has_field (&args, "collation")) { - bson_t collation; - bson_lookup_doc (&args, "collation", &collation); - BSON_APPEND_DOCUMENT (&opts, "collation", &collation); - } - - if (!strcmp (name, "deleteMany")) { - bson_t filter; - - bson_lookup_doc (&args, "filter", &filter); - - r = mongoc_bulk_operation_remove_many_with_opts ( - bulk, &filter, &opts, error); - } else if (!strcmp (name, "deleteOne")) { - bson_t filter; - - bson_lookup_doc (&args, "filter", &filter); - - r = mongoc_bulk_operation_remove_one_with_opts ( - bulk, &filter, &opts, error); - } else if (!strcmp (name, "insertOne")) { - bson_t document; - - bson_lookup_doc (&args, "document", &document); - - r = - mongoc_bulk_operation_insert_with_opts (bulk, &document, &opts, error); - } else if (!strcmp (name, "replaceOne")) { - bson_t filter; - bson_t replacement; - - bson_lookup_doc (&args, "filter", &filter); - bson_lookup_doc (&args, "replacement", &replacement); - - if (bson_has_field (&args, "upsert")) { - BSON_APPEND_BOOL ( - &opts, "upsert", _mongoc_lookup_bool (&args, "upsert", false)); - } - - r = mongoc_bulk_operation_replace_one_with_opts ( - bulk, &filter, &replacement, &opts, error); - } else if (!strcmp (name, "updateMany")) { - bson_t filter; - bson_t update; - - bson_lookup_doc (&args, "filter", &filter); - bson_lookup_doc (&args, "update", &update); - - if (bson_has_field (&args, "upsert")) { - BSON_APPEND_BOOL ( - &opts, "upsert", _mongoc_lookup_bool (&args, "upsert", false)); - } - - r = mongoc_bulk_operation_update_many_with_opts ( - bulk, &filter, &update, &opts, error); - } else if (!strcmp (name, "updateOne")) { - bson_t filter; - bson_t update; - - bson_lookup_doc (&args, "filter", &filter); - bson_lookup_doc (&args, "update", &update); - - if (bson_has_field (&args, "upsert")) { - BSON_APPEND_BOOL ( - &opts, "upsert", _mongoc_lookup_bool (&args, "upsert", false)); - } - - r = mongoc_bulk_operation_update_one_with_opts ( - bulk, &filter, &update, &opts, error); - } else { - test_error ("unrecognized request name %s", name); - abort (); - } - - bson_destroy (&opts); - - return r; -} - - -static void -execute_bulk_operation (mongoc_bulk_operation_t *bulk, - const bson_t *test, - const bson_t *operation, - bson_t *reply) -{ - uint32_t server_id; - bson_error_t error; - bson_value_t value; - - server_id = mongoc_bulk_operation_execute (bulk, reply, &error); - value_init_from_doc (&value, reply); - check_result (test, operation, server_id != 0, &value, &error); - bson_value_destroy (&value); -} - - -static bson_t * -create_bulk_write_opts (const bson_t *operation, - mongoc_client_session_t *session, - mongoc_write_concern_t *wc) -{ - bson_t *opts; - bson_t tmp; - - opts = tmp_bson ("{}"); - - if (bson_has_field (operation, "arguments.options")) { - bson_lookup_doc (operation, "arguments.options", &tmp); - bson_concat (opts, &tmp); - } - - append_session (session, opts); - - if (!mongoc_write_concern_is_default (wc)) { - BSON_ASSERT (mongoc_write_concern_append (wc, opts)); - } - - return opts; -} - - -static bool -bulk_write (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - mongoc_write_concern_t *wc, - bson_t *reply) -{ - bson_t *opts; - mongoc_bulk_operation_t *bulk; - bson_t requests; - bson_iter_t iter; - bson_error_t error; - - opts = create_bulk_write_opts (operation, session, wc); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, opts); - - bson_lookup_doc (operation, "arguments.requests", &requests); - ASSERT (bson_iter_init (&iter, &requests)); - - while (bson_iter_next (&iter)) { - bson_t request; - - bson_iter_bson (&iter, &request); - if (!add_request_to_bulk (bulk, &request, &error)) { - /* For the sake of the test framework, we must init this */ - bson_init (reply); - - check_result (test, operation, false, NULL, &error); - mongoc_bulk_operation_destroy (bulk); - - return false; - } - } - - execute_bulk_operation (bulk, test, operation, reply); - mongoc_bulk_operation_destroy (bulk); - - return true; -} - - -#define COPY_EXCEPT(...) \ - bson_copy_to_excluding_noinit ( \ - &args, &opts, "session", "readPreference", __VA_ARGS__, NULL); - - -static bool -single_write (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - mongoc_write_concern_t *wc, - bson_t *reply) -{ - const char *name; - bson_t args; - bson_t opts = BSON_INITIALIZER; - bson_value_t value; - bson_error_t error; - bool r; - - name = bson_lookup_utf8 (operation, "name"); - bson_lookup_doc (operation, "arguments", &args); - append_session (session, &opts); - - if (!strcmp (name, "deleteMany")) { - bson_t filter; - bson_lookup_doc (&args, "filter", &filter); - COPY_EXCEPT ("filter"); - r = mongoc_collection_delete_many ( - collection, &filter, &opts, reply, &error); - } else if (!strcmp (name, "deleteOne")) { - bson_t filter; - bson_lookup_doc (&args, "filter", &filter); - COPY_EXCEPT ("filter"); - r = mongoc_collection_delete_one ( - collection, &filter, &opts, reply, &error); - } else if (!strcmp (name, "insertOne")) { - bson_t document; - bson_lookup_doc (&args, "document", &document); - COPY_EXCEPT ("document"); - r = mongoc_collection_insert_one ( - collection, &document, &opts, reply, &error); - } else if (!strcmp (name, "replaceOne")) { - bson_t filter; - bson_t replacement; - bson_lookup_doc (&args, "filter", &filter); - bson_lookup_doc (&args, "replacement", &replacement); - COPY_EXCEPT ("filter", "replacement"); - r = mongoc_collection_replace_one ( - collection, &filter, &replacement, &opts, reply, &error); - } else if (!strcmp (name, "updateMany")) { - bson_t filter; - bson_t update; - bson_lookup_doc (&args, "filter", &filter); - bson_lookup_doc (&args, "update", &update); - COPY_EXCEPT ("filter", "update"); - r = mongoc_collection_update_many ( - collection, &filter, &update, &opts, reply, &error); - } else if (!strcmp (name, "updateOne")) { - bson_t filter; - bson_t update; - bson_lookup_doc (&args, "filter", &filter); - bson_lookup_doc (&args, "update", &update); - COPY_EXCEPT ("filter", "update"); - r = mongoc_collection_update_one ( - collection, &filter, &update, &opts, reply, &error); - } else { - test_error ("unrecognized request name %s", name); - abort (); - } - - value_init_from_doc (&value, reply); - check_result (test, operation, r, &value, &error); - bson_value_destroy (&value); - bson_destroy (&opts); - - return r; -} - - -static mongoc_find_and_modify_opts_t * -create_find_and_modify_opts (const char *name, - const bson_t *args, - mongoc_client_session_t *session, - mongoc_write_concern_t *wc) -{ - mongoc_find_and_modify_opts_t *opts; - mongoc_find_and_modify_flags_t flags = MONGOC_FIND_AND_MODIFY_NONE; - bson_t extra = BSON_INITIALIZER; - - opts = mongoc_find_and_modify_opts_new (); - - if (!strcmp (name, "findOneAndDelete")) { - flags |= MONGOC_FIND_AND_MODIFY_REMOVE; - } - - if (!strcmp (name, "findOneAndReplace")) { - bson_t replacement; - bson_lookup_doc (args, "replacement", &replacement); - mongoc_find_and_modify_opts_set_update (opts, &replacement); - } - - if (!strcmp (name, "findOneAndUpdate")) { - bson_t update; - bson_lookup_doc (args, "update", &update); - mongoc_find_and_modify_opts_set_update (opts, &update); - } - - if (bson_has_field (args, "sort")) { - bson_t sort; - bson_lookup_doc (args, "sort", &sort); - mongoc_find_and_modify_opts_set_sort (opts, &sort); - } - - if (_mongoc_lookup_bool (args, "upsert", false)) { - flags |= MONGOC_FIND_AND_MODIFY_UPSERT; - } - - if (bson_has_field (args, "collation")) { - bson_t collation = BSON_INITIALIZER; - bson_t temp; - bson_lookup_doc (args, "collation", &temp); - BSON_APPEND_DOCUMENT (&collation, "collation", &temp); - mongoc_find_and_modify_opts_append (opts, &collation); - bson_destroy (&collation); - bson_destroy (&temp); - } - - if (bson_has_field (args, "arrayFilters")) { - bson_t array_filters = BSON_INITIALIZER; - bson_value_t temp; - bson_lookup_value (args, "arrayFilters", &temp); - BSON_APPEND_VALUE (&array_filters, "arrayFilters", &temp); - mongoc_find_and_modify_opts_append (opts, &array_filters); - bson_destroy (&array_filters); - bson_value_destroy (&temp); - } - - if (bson_has_field (args, "returnDocument") && - !strcmp ("After", bson_lookup_utf8 (args, "returnDocument"))) { - flags |= MONGOC_FIND_AND_MODIFY_RETURN_NEW; - } - - mongoc_find_and_modify_opts_set_flags (opts, flags); - append_session (session, &extra); - - if (!mongoc_write_concern_is_default (wc)) { - BSON_ASSERT (mongoc_write_concern_append (wc, &extra)); - } - - ASSERT (mongoc_find_and_modify_opts_append (opts, &extra)); - bson_destroy (&extra); - - return opts; -} - - -static bool -find_and_modify (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - mongoc_write_concern_t *wc, - bson_t *reply) -{ - const char *name; - bson_t args; - bson_t filter; - mongoc_find_and_modify_opts_t *opts; - bson_value_t value = {0}; - bson_error_t error; - bool r; - - name = bson_lookup_utf8 (operation, "name"); - bson_lookup_doc (operation, "arguments", &args); - bson_lookup_doc (operation, "arguments.filter", &filter); - - opts = create_find_and_modify_opts (name, &args, session, wc); - - r = mongoc_collection_find_and_modify_with_opts ( - collection, &filter, opts, reply, &error); - - - /* Transactions Tests have findAndModify results like: - * result: {_id: 3} - * - * Or for findOneAndDelete with no result: - * result: null - * - * But mongoc_collection_find_and_modify_with_opts returns: - * { ok: 1, value: {_id: 3}} - * - * Or: - * { ok: 1, value: null} - */ - if (r) { - bson_lookup_value (reply, "value", &value); - } else { - value_init_from_doc (&value, reply); - } - - check_result (test, operation, r, &value, &error); - - bson_value_destroy (&value); - mongoc_find_and_modify_opts_destroy (opts); - bson_destroy (&args); - bson_destroy (&filter); - - return r; -} - - -static bool -insert_many (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - mongoc_write_concern_t *wc, - bson_t *reply) -{ - bson_t args; - bson_t opts = BSON_INITIALIZER; - bson_t docs_array; - bson_t *doc_ptrs[100]; - size_t i, n; - bson_iter_t iter; - bson_value_t value; - bson_error_t error; - bool r; - - bson_lookup_doc (operation, "arguments", &args); - bson_lookup_doc (&args, "documents", &docs_array); - ASSERT (bson_iter_init (&iter, &docs_array)); - n = 0; - while (bson_iter_next (&iter)) { - bson_t document; - bson_iter_bson (&iter, &document); - doc_ptrs[n] = bson_copy (&document); - n++; - if (n >= 100) { - test_error ("Too many documents: %s", bson_as_json (operation, NULL)); - } - } - - append_session (session, &opts); - /* transactions tests are like: - * operation: - * name: "insertMany" - * arguments: - * documents: - * - { _id: 2, x: 22 } - * options: { ordered: false } - */ - BSON_APPEND_BOOL ( - &opts, - "ordered", - _mongoc_lookup_bool (&args, "options.ordered", true /* default */)); - - COPY_EXCEPT ("documents", "options"); - - r = mongoc_collection_insert_many ( - collection, (const bson_t **) doc_ptrs, n, &opts, reply, &error); - - /* CRUD tests may specify a write result even if an error is expected. - * From the CRUD spec test readme: - * "drivers may choose to check the result object if their BulkWriteException - * (or equivalent) provides access to a write result object" - * The C driver does not return a full write result for an "InsertMany" on - * error, but instead just the insertedCount. - */ - if (!r) { - BSON_APPEND_INT64 (reply, "deletedCount", 0); - BSON_APPEND_INT64 (reply, "matchedCount", 0); - BSON_APPEND_INT64 (reply, "modifiedCount", 0); - BSON_APPEND_INT64 (reply, "upsertedCount", 0); - BSON_APPEND_DOCUMENT (reply, "upsertedIds", tmp_bson ("{}")); - } - - value_init_from_doc (&value, reply); - check_result (test, operation, r, &value, &error); - bson_value_destroy (&value); - bson_destroy (&opts); - - for (i = 0; i < n; i++) { - bson_destroy (doc_ptrs[i]); - } - - return r; -} - - -static bool -rename_op (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - mongoc_write_concern_t *wc, - bson_t *reply) -{ - bson_t args; - const char *db; - const char *to; - bson_error_t error; - bool res; - - bson_lookup_doc (operation, "arguments", &args); - db = bson_lookup_utf8 (operation, "database"); - to = bson_lookup_utf8 (&args, "to"); - - res = mongoc_collection_rename (collection, db, to, true, &error); - - /* This operation is only run by change stream tests, which use - it to trigger further events and check all results elsewhere. */ - ASSERT_OR_PRINT (res, error); - - bson_destroy (&args); - - /* fake a reply for the test framework's sake */ - bson_init (reply); - - return res; -} - - -static bool -drop (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - mongoc_write_concern_t *wc, - bson_t *reply) -{ - bson_error_t error; - bool res; - - res = mongoc_collection_drop (collection, &error); - - /* This operation is only run by change stream tests, which use - it to trigger further events and check all results elsewhere. */ - ASSERT_OR_PRINT (res, error); - - /* fake a reply for the test framework's sake */ - bson_init (reply); - - return res; -} - - -static bool -count (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply) -{ - bson_t filter; - bson_t opts = BSON_INITIALIZER; - bson_error_t error; - int64_t r; - bson_value_t value; - const char *name; - - if (bson_has_field (operation, "arguments.filter")) { - bson_lookup_doc (operation, "arguments.filter", &filter); - } - if (bson_has_field (operation, "arguments.skip")) { - BSON_APPEND_INT64 ( - &opts, "skip", bson_lookup_int32 (operation, "arguments.skip")); - } - if (bson_has_field (operation, "arguments.limit")) { - BSON_APPEND_INT64 ( - &opts, "limit", bson_lookup_int32 (operation, "arguments.limit")); - } - if (bson_has_field (operation, "arguments.collation")) { - bson_t collation; - bson_lookup_doc (operation, "arguments.collation", &collation); - BSON_APPEND_DOCUMENT (&opts, "collation", &collation); - } - append_session (session, &opts); - - name = bson_lookup_utf8 (operation, "name"); - if (!strcmp (name, "countDocuments")) { - r = mongoc_collection_count_documents ( - collection, &filter, &opts, read_prefs, reply, &error); - } else if (!strcmp (name, "estimatedDocumentCount")) { - r = mongoc_collection_estimated_document_count ( - collection, &opts, read_prefs, reply, &error); - } else if (!strcmp (name, "count")) { - /* deprecated old count function */ - r = mongoc_collection_count_with_opts (collection, - MONGOC_QUERY_NONE, - &filter, - 0, - 0, - &opts, - read_prefs, - &error); - /* fake a reply for the test framework's sake */ - bson_init (reply); - } else { - test_error ("count() called with unrecognized operation name %s", name); - return false; - } - - if (r >= 0) { - value.value_type = BSON_TYPE_INT64; - value.value.v_int64 = r; - } else { - value_init_from_doc (&value, reply); - } - check_result (test, operation, r > -1, &value, &error); - - bson_value_destroy (&value); - bson_destroy (&opts); - - return (r > -1); -} - -static bool -distinct (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply) -{ - bson_t args; - bson_t opts = BSON_INITIALIZER; - const char *field_name; - bson_t query; - bson_value_t value = {0}; - bson_error_t error; - bool r; - - append_session (session, &opts); - bson_lookup_doc (operation, "arguments", &args); - field_name = bson_lookup_utf8 (&args, "fieldName"); - if (bson_has_field (&args, "filter")) { - bson_lookup_doc (&args, "filter", &query); - BSON_APPEND_DOCUMENT (&opts, "query", &query); - } - - COPY_EXCEPT ("fieldName", "filter"); - - r = mongoc_collection_read_command_with_opts ( - collection, - tmp_bson ( - "{'distinct': '%s', 'key': '%s'}", collection->collection, field_name), - read_prefs, - &opts, - reply, - &error); - - /* Transactions Tests have "distinct" results like: - * result: [1, 2, 3] - * - * But the command returns: - * { ok: 1, values: [1, 2, 3]} */ - if (r) { - bson_lookup_value (reply, "values", &value); - } else { - value_init_from_doc (&value, reply); - } - - check_result (test, operation, r, &value, &error); - - bson_value_destroy (&value); - bson_destroy (&opts); - - return r; -} - - -static void -check_cursor (mongoc_cursor_t *cursor, - const bson_t *test, - const bson_t *operation) -{ - const bson_t *doc; - bson_error_t error; - bson_t result = BSON_INITIALIZER; - const char *keyptr = NULL; - char key[12]; - uint32_t i = 0; - bson_value_t value; - - i = 0; - while (mongoc_cursor_next (cursor, &doc)) { - bson_uint32_to_string (i++, &keyptr, key, sizeof key); - BSON_APPEND_DOCUMENT (&result, keyptr, doc); - } - - if (mongoc_cursor_error_document (cursor, &error, &doc)) { - value_init_from_doc (&value, doc); - check_result (test, operation, false, &value, &error); - } else { - value_init_from_doc (&value, &result); - value.value_type = BSON_TYPE_ARRAY; - check_result (test, operation, true, &value, &error); - } - - bson_value_destroy (&value); - bson_destroy (&result); -} - - -static bool -find (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply) -{ - bson_t args; - bson_t tmp; - bson_t filter; - bson_t opts = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - bson_error_t error; - - /* We don't use reply, but we need to initialize it for the test runner */ - bson_init (reply); - - bson_lookup_doc (operation, "arguments", &args); - if (bson_has_field (&args, "filter")) { - bson_lookup_doc (&args, "filter", &tmp); - bson_copy_to (&tmp, &filter); - } else { - bson_init (&filter); - } - - /* Command Monitoring Spec tests use OP_QUERY-style modifiers for "find": - * arguments: - * filter: { _id: { $gt: 1 } } - * sort: { _id: 1 } - * skip: {"$numberLong": "2"} - * modifiers: - * $comment: "test" - * $showDiskLoc: false - * - * Abuse _mongoc_cursor_translate_dollar_query_opts to upgrade "modifiers". - */ - if (bson_has_field (&args, "modifiers")) { - bson_t modifiers; - bson_t *query = tmp_bson ("{'$query': {}}"); - bson_t unwrapped; - bool r; - - bson_lookup_doc (&args, "modifiers", &modifiers); - bson_concat (query, &modifiers); - r = _mongoc_cursor_translate_dollar_query_opts ( - query, &opts, &unwrapped, &error); - ASSERT_OR_PRINT (r, error); - bson_destroy (&unwrapped); - } - - COPY_EXCEPT ("filter", "modifiers"); - append_session (session, &opts); - - cursor = - mongoc_collection_find_with_opts (collection, &filter, &opts, read_prefs); - - check_cursor (cursor, test, operation); - mongoc_cursor_destroy (cursor); - bson_destroy (&filter); - bson_destroy (&opts); - - return true; -} - - -static bool -find_one (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply) -{ - bson_t filter; - bson_t opts = BSON_INITIALIZER; - const bson_t *doc; - mongoc_cursor_t *cursor; - bson_value_t value; - bson_error_t error; - - bson_lookup_doc (operation, "arguments.filter", &filter); - - cursor = - mongoc_collection_find_with_opts (collection, &filter, &opts, read_prefs); - - if (mongoc_cursor_next (cursor, &doc)) { - value_init_from_doc (&value, doc); - mongoc_cursor_error (cursor, &error); - check_result (test, operation, true, &value, &error); - } else if (mongoc_cursor_error_document (cursor, &error, &doc)) { - value_init_from_doc (&value, doc); - check_result (test, operation, false, &value, &error); - } - - mongoc_cursor_destroy (cursor); - bson_destroy (&filter); - bson_destroy (&opts); - bson_value_destroy (&value); - bson_init (reply); - return true; -} - - -static bool -_is_aggregate_out (const bson_t *pipeline) -{ - bson_iter_t iter; - bson_iter_t stage; - - ASSERT (bson_iter_init (&iter, pipeline)); - while (bson_iter_next (&iter)) { - if (BSON_ITER_HOLDS_DOCUMENT (&iter) && - bson_iter_recurse (&iter, &stage)) { - if (bson_iter_find (&stage, "$out")) { - return true; - } - } - } - - return false; -} - - -static bool -aggregate (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply) -{ - bson_t args; - bson_t pipeline; - bson_t opts = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - - /* We don't use reply, but we need to initialize it for the test runner */ - bson_init (reply); - - bson_lookup_doc (operation, "arguments", &args); - bson_lookup_doc (&args, "pipeline", &pipeline); - append_session (session, &opts); - COPY_EXCEPT ("pipeline"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, &pipeline, &opts, read_prefs); - - /* Driver CRUD API Spec: "$out is a special pipeline stage that causes no - * results to be returned from the server. As such, the iterable here would - * never contain documents. Drivers MAY setup a cursor to be executed upon - * iteration against the $out collection such that if a user were to iterate - * a pipeline including $out, results would be returned." - * - * The C Driver chooses the first option, and returns an empty cursor. - */ - if (_is_aggregate_out (&pipeline)) { - const bson_t *doc; - bson_error_t error; - bson_value_t value; - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - if (mongoc_cursor_error_document (cursor, &error, &doc)) { - value_init_from_doc (&value, doc); - check_result (test, operation, false, &value, &error); - bson_value_destroy (&value); - } - } else { - check_cursor (cursor, test, operation); - } - - mongoc_cursor_destroy (cursor); - bson_destroy (&opts); - - return true; -} - - -static bool -db_aggregate (mongoc_database_t *db, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply) -{ - bson_t args; - bson_t pipeline; - bson_t opts = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - - /* We don't use reply, but we need to initialize it for the test runner */ - bson_init (reply); - - bson_lookup_doc (operation, "arguments", &args); - bson_lookup_doc (&args, "pipeline", &pipeline); - append_session (session, &opts); - COPY_EXCEPT ("pipeline"); - - cursor = mongoc_database_aggregate (db, &pipeline, &opts, read_prefs); - - /* Driver CRUD API Spec: "$out is a special pipeline stage that causes no - * results to be returned from the server. As such, the iterable here would - * never contain documents. Drivers MAY setup a cursor to be executed upon - * iteration against the $out collection such that if a user were to iterate - * a pipeline including $out, results would be returned." - * - * The C Driver chooses the first option, and returns an empty cursor. - */ - if (_is_aggregate_out (&pipeline)) { - const bson_t *doc; - bson_error_t error; - bson_value_t value; - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - if (mongoc_cursor_error_document (cursor, &error, &doc)) { - value_init_from_doc (&value, doc); - check_result (test, operation, false, &value, &error); - bson_value_destroy (&value); - } - } else { - check_cursor (cursor, test, operation); - } - - mongoc_cursor_destroy (cursor); - bson_destroy (&opts); - - return true; -} - - -static bool -command (mongoc_database_t *db, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply) -{ - bson_t cmd; - bson_t args; - bson_t opts = BSON_INITIALIZER; - bson_error_t error; - bool r; - bson_value_t value; - - /* arguments are like: - * - * arguments: - * session: session0 - * command: - * find: *collection_name - * readConcern: - * level: majority - */ - bson_lookup_doc (operation, "arguments", &args); - bson_lookup_doc (&args, "command", &cmd); - COPY_EXCEPT ("command"); - append_session (session, &opts); - - r = mongoc_database_command_with_opts ( - db, &cmd, read_prefs, &opts, reply, &error); - - value_init_from_doc (&value, reply); - check_result (test, operation, r, &value, &error); - bson_value_destroy (&value); - bson_destroy (&opts); - bson_destroy (&cmd); - - return r; -} - - -static bool -start_transaction (mongoc_client_session_t *session, - const bson_t *test, - const bson_t *operation, - bson_t *reply) -{ - mongoc_transaction_opt_t *opts = NULL; - bson_error_t error; - bool r; - - /* We don't use reply, but we need to initialize it for the test runner */ - bson_init (reply); - - if (bson_has_field (operation, "arguments.options")) { - opts = bson_lookup_txn_opts (operation, "arguments.options"); - } - - r = mongoc_client_session_start_transaction (session, opts, &error); - check_result (test, operation, r, NULL, &error); - - if (opts) { - mongoc_transaction_opts_destroy (opts); - } - - return r; -} - - -static bool -commit_transaction (mongoc_client_session_t *session, - const bson_t *test, - const bson_t *operation, - bson_t *reply) -{ - bson_value_t value; - bson_error_t error; - bool r; - - r = mongoc_client_session_commit_transaction (session, reply, &error); - value_init_from_doc (&value, reply); - check_result (test, operation, r, &value, &error); - bson_value_destroy (&value); - - return r; -} - - -static bool -abort_transaction (mongoc_client_session_t *session, - const bson_t *test, - const bson_t *operation, - bson_t *reply) -{ - bson_value_t value; - bson_error_t error; - bool r; - - r = mongoc_client_session_abort_transaction (session, &error); - /* fake a reply for the test framework's sake */ - bson_init (reply); - value_init_from_doc (&value, reply); - check_result (test, operation, r, &value, &error); - bson_value_destroy (&value); - - return r; -} - - -static bool -list_databases (mongoc_client_t *client, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - bson_t *reply) -{ - mongoc_cursor_t *cursor; - bson_t opts; - - BSON_ASSERT (client); - bson_init (&opts); - append_session (session, &opts); - - cursor = mongoc_client_find_databases_with_opts (client, &opts); - bson_destroy (&opts); - - check_cursor (cursor, test, operation); - mongoc_cursor_destroy (cursor); - bson_init (reply); - return true; -} - - -static bool -list_database_names (mongoc_client_t *client, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - bson_t *reply) -{ - char **database_names; - bson_t opts; - bson_error_t error; - - BSON_ASSERT (client); - bson_init (&opts); - append_session (session, &opts); - - database_names = - mongoc_client_get_database_names_with_opts (client, &opts, &error); - bson_destroy (&opts); - - check_result ( - test, operation, database_names != NULL, NULL /* result */, &error); - bson_init (reply); - bson_strfreev (database_names); - return true; -} - - -static bool -list_indexes (mongoc_collection_t *collection, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - bson_t *reply) -{ - bson_t opts; - mongoc_cursor_t *cursor; - - BSON_ASSERT (collection); - - bson_init (&opts); - append_session (session, &opts); - - cursor = mongoc_collection_find_indexes_with_opts (collection, &opts); - check_cursor (cursor, test, operation); - mongoc_cursor_destroy (cursor); - bson_init (reply); - bson_destroy (&opts); - return true; -} - - -static bool -list_collections (mongoc_database_t *db, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - bson_t *reply) -{ - mongoc_cursor_t *cursor; - bson_t opts; - - bson_init (&opts); - append_session (session, &opts); - - cursor = mongoc_database_find_collections_with_opts (db, &opts); - - bson_destroy (&opts); - - check_cursor (cursor, test, operation); - mongoc_cursor_destroy (cursor); - bson_init (reply); - - return true; -} - -static bool -list_collection_names (mongoc_database_t *db, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - bson_t *reply) -{ - char **collection_names; - bson_t opts; - bson_error_t error; - - bson_init (&opts); - append_session (session, &opts); - - collection_names = - mongoc_database_get_collection_names_with_opts (db, &opts, &error); - - bson_destroy (&opts); - - check_result ( - test, operation, collection_names != NULL, NULL /* result */, &error); - bson_init (reply); - bson_strfreev (collection_names); - - return true; -} - - -static bool -gridfs_download (mongoc_database_t *db, - const bson_t *test, - const bson_t *operation, - mongoc_client_session_t *session, - const mongoc_read_prefs_t *read_prefs, - bson_t *reply) -{ - mongoc_gridfs_bucket_t *bucket; - bson_value_t value; - bson_error_t error; - mongoc_stream_t *stream; - char buf[512]; - - bson_lookup_value (operation, "arguments.id", &value); - - bucket = mongoc_gridfs_bucket_new (db, NULL, read_prefs, &error); - stream = mongoc_gridfs_bucket_open_download_stream (bucket, &value, &error); - - if (stream != NULL) { - mongoc_stream_read (stream, buf, 1, 1, 0); - } - - mongoc_stream_destroy (stream); - mongoc_gridfs_bucket_destroy (bucket); - bson_init (reply); - - return true; -} - -static bool -op_error (const bson_t *operation) -{ - return bson_has_field (operation, "error") && - bson_lookup_bool (operation, "error"); -} - -bool -json_test_operation (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation, - mongoc_collection_t *collection, - mongoc_client_session_t *session, - bson_t *reply) -{ - const char *op_name; - const char *obj_name = "collection"; - mongoc_read_prefs_t *read_prefs = NULL; - mongoc_write_concern_t *wc; - mongoc_database_t *db = mongoc_database_copy (ctx->db); - mongoc_collection_t *c = mongoc_collection_copy (collection); - bool res = false; - - op_name = bson_lookup_utf8 (operation, "name"); - - if (bson_has_field (operation, "object")) { - obj_name = bson_lookup_utf8 (operation, "object"); - } - - if (bson_has_field (operation, "databaseOptions")) { - bson_lookup_database_opts (operation, "databaseOptions", db); - } - - if (bson_has_field (operation, "collectionOptions")) { - bson_lookup_collection_opts (operation, "collectionOptions", c); - } - - if (bson_has_field (operation, "read_preference")) { - /* command monitoring tests */ - read_prefs = bson_lookup_read_prefs (operation, "read_preference"); - } else if (bson_has_field (operation, "arguments.readPreference")) { - /* transactions tests */ - read_prefs = - bson_lookup_read_prefs (operation, "arguments.readPreference"); - } - - if (bson_has_field (operation, "arguments.writeConcern")) { - wc = bson_lookup_write_concern (operation, "arguments.writeConcern"); - } else { - wc = mongoc_write_concern_new (); - } - - if (!strcmp (obj_name, "collection")) { - if (!strcmp (op_name, "bulkWrite")) { - res = bulk_write (c, test, operation, session, wc, reply); - } else if (!strcmp (op_name, "deleteOne") || - !strcmp (op_name, "deleteMany") || - !strcmp (op_name, "insertOne") || - !strcmp (op_name, "replaceOne") || - !strcmp (op_name, "updateOne") || - !strcmp (op_name, "updateMany")) { - res = single_write (c, test, operation, session, wc, reply); - } else if (!strcmp (op_name, "findOneAndDelete") || - !strcmp (op_name, "findOneAndReplace") || - !strcmp (op_name, "findOneAndUpdate")) { - res = find_and_modify (c, test, operation, session, wc, reply); - } else if (!strcmp (op_name, "insertMany")) { - res = insert_many (c, test, operation, session, wc, reply); - } else if (!strcmp (op_name, "rename")) { - res = rename_op (c, test, operation, session, wc, reply); - } else if (!strcmp (op_name, "drop")) { - res = drop (c, test, operation, session, wc, reply); - } else if (!strcmp (op_name, "count")) { - res = count (c, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "estimatedDocumentCount")) { - res = count (c, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "countDocuments")) { - res = count (c, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "distinct")) { - res = distinct (c, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "find")) { - res = find (c, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "findOne")) { - res = find_one (c, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "aggregate")) { - res = aggregate (c, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "listIndexes")) { - res = list_indexes (c, test, operation, session, reply); - } else if (!strcmp (op_name, "watch")) { - bson_t pipeline = BSON_INITIALIZER; - mongoc_change_stream_destroy (ctx->change_stream); - ctx->change_stream = mongoc_collection_watch (c, &pipeline, NULL); - res = (op_error (operation) == (0 != ctx->change_stream->err.code)); - if (!res) { - test_error ("expected error=%s, but actual error='%s'", - op_error (operation) ? "true" : "false", - ctx->change_stream->err.message); - } - - bson_init (reply); - bson_destroy (&pipeline); - } else if (!strcmp (op_name, "mapReduce") || - !strcmp (op_name, "listIndexNames")) { - test_error ("operation not implemented in libmongoc"); - } else { - test_error ("unrecognized collection operation name %s", op_name); - } - } else if (!strcmp (obj_name, "database")) { - if (!strcmp (op_name, "aggregate")) { - res = db_aggregate (db, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "runCommand")) { - res = command (db, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "listCollections")) { - res = list_collections (db, test, operation, session, reply); - } else if (!strcmp (op_name, "listCollectionNames")) { - res = list_collection_names (db, test, operation, session, reply); - } else if (!strcmp (op_name, "watch")) { - bson_t pipeline = BSON_INITIALIZER; - mongoc_change_stream_destroy (ctx->change_stream); - ctx->change_stream = mongoc_database_watch (db, &pipeline, NULL); - res = (op_error (operation) == (0 != ctx->change_stream->err.code)); - if (!res) { - test_error ("expected error=%s, but actual error='%s'", - op_error (operation) ? "true" : "false", - ctx->change_stream->err.message); - } - - bson_init (reply); - bson_destroy (&pipeline); - } else if (!strcmp (op_name, "listCollectionObjects")) { - test_error ("listCollectionObjects is not implemented in libmongoc"); - } else { - test_error ("unrecognized database operation name %s", op_name); - } - } else if (!strncmp (obj_name, "session", 7)) { - mongoc_client_session_t *named_session = - session_from_name (ctx, obj_name); - - if (!strcmp (op_name, "startTransaction")) { - res = start_transaction (named_session, test, operation, reply); - } else if (!strcmp (op_name, "commitTransaction")) { - res = commit_transaction (named_session, test, operation, reply); - } else if (!strcmp (op_name, "abortTransaction")) { - res = abort_transaction (named_session, test, operation, reply); - } else { - test_error ("unrecognized session operation name %s", op_name); - } - } else if (!strcmp (obj_name, "testRunner")) { - /* We don't use reply, but we need to initialize it for the test runner */ - bson_init (reply); - if (!strcmp (op_name, "assertSessionPinned")) { - res = (0 != mongoc_client_session_get_server_id (session)); - } else if (!strcmp (op_name, "assertSessionUnpinned")) { - res = (0 == mongoc_client_session_get_server_id (session)); - } else if (!strcmp (op_name, "targetedFailPoint")) { - mongoc_client_t *client; - - client = mongoc_client_new_from_uri (ctx->client->uri); - activate_fail_point ( - client, session->server_id, operation, "arguments.failPoint"); - - mongoc_client_destroy (client); - } else { - test_error ("unrecognized session operation name %s", op_name); - } - } else if (!strcmp (obj_name, "client")) { - if (!strcmp (op_name, "listDatabases")) { - res = list_databases (c->client, test, operation, session, reply); - } else if (!strcmp (op_name, "listDatabaseNames")) { - res = list_database_names (c->client, test, operation, session, reply); - } else if (!strcmp (op_name, "watch")) { - bson_t pipeline = BSON_INITIALIZER; - mongoc_change_stream_destroy (ctx->change_stream); - ctx->change_stream = mongoc_client_watch (c->client, &pipeline, NULL); - res = (op_error (operation) == (0 != ctx->change_stream->err.code)); - if (!res) { - test_error ("expected error=%s, but actual error='%s'", - op_error (operation) ? "true" : "false", - ctx->change_stream->err.message); - } - - bson_init (reply); - bson_destroy (&pipeline); - } else if (!strcmp (op_name, "listDatabaseObjects")) { - test_error ("listDatabaseObjects is not implemented in libmongoc"); - } else { - test_error ("unrecognized client operation name %s", op_name); - } - } else if (!strcmp (obj_name, "gridfsbucket")) { - if (!strcmp (op_name, "download")) { - res = - gridfs_download (db, test, operation, session, read_prefs, reply); - } else if (!strcmp (op_name, "download_by_name")) { - test_error ("download_by_name is part of the optional advanced API " - "and not implemented in libmongoc"); - } else { - test_error ("unrecognized gridfs operation name %s", op_name); - } - } else { - test_error ("unrecognized object name %s", obj_name); - } - - mongoc_read_prefs_destroy (read_prefs); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (c); - mongoc_database_destroy (db); - - return res; -} - - -static void -one_operation (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation) -{ - const char *op_name; - mongoc_write_concern_t *wc = NULL; - - op_name = bson_lookup_utf8 (operation, "name"); - if (ctx->verbose) { - printf (" %s\n", op_name); - fflush (stdout); - } - - if (bson_has_field (operation, "arguments.writeConcern")) { - wc = bson_lookup_write_concern (operation, "arguments.writeConcern"); - } else if (bson_has_field (operation, "collectionOptions.writeConcern")) { - wc = bson_lookup_write_concern (operation, - "collectionOptions.writeConcern"); - } - - if (wc) { - ctx->acknowledged = mongoc_write_concern_is_acknowledged (wc); - mongoc_write_concern_destroy (wc); - } else { - ctx->acknowledged = true; - } - - if (ctx->config->run_operation_cb) { - ctx->config->run_operation_cb (ctx, test, operation); - } else { - test_error ("set json_test_config_t.run_operation_cb to a callback" - " that executes json_test_operation()"); - } -} - - -void -json_test_operations (json_test_ctx_t *ctx, const bson_t *test) -{ - bson_t operations; - bson_t operation; - bson_iter_t iter; - - /* run each CRUD operation in the test, using the config's run-operation - * callback, by default json_test_operation(). retryable writes tests have - * one operation each, transactions tests have an array of them. */ - if (bson_has_field (test, "operation")) { - bson_lookup_doc (test, "operation", &operation); - one_operation (ctx, test, &operation); - } else { - bson_lookup_doc (test, "operations", &operations); - BSON_ASSERT (bson_iter_init (&iter, &operations)); - while (bson_iter_next (&iter)) { - bson_iter_bson (&iter, &operation); - one_operation (ctx, test, &operation); - } - } -} diff --git a/lib/mongoc/libmongoc/tests/json-test-operations.h b/lib/mongoc/libmongoc/tests/json-test-operations.h deleted file mode 100644 index b1691910424800bc242bf03d6897493b8b3f5350..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json-test-operations.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2018-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 JSON_TEST_OPERATIONS_H -#define JSON_TEST_OPERATIONS_H - -struct _json_test_config_t; - -typedef struct { - const struct _json_test_config_t *config; - uint32_t n_events; - bson_t events; - mongoc_uri_t *test_framework_uri; - mongoc_client_session_t *sessions[2]; - bson_t lsids[2]; - bool acknowledged; - bool verbose; - bool has_sessions; - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_collection_t *collection; - mongoc_change_stream_t *change_stream; -} json_test_ctx_t; - -mongoc_client_session_t * -session_from_name (json_test_ctx_t *ctx, const char *session_name); - -void -json_test_ctx_init (json_test_ctx_t *ctx, - const bson_t *test, - mongoc_client_t *client, - mongoc_database_t *db, - mongoc_collection_t *collection, - const struct _json_test_config_t *config); - -void -json_test_ctx_end_sessions (json_test_ctx_t *ctx); - -void -json_test_ctx_cleanup (json_test_ctx_t *ctx); - -typedef bool (*json_test_operation_cb_t) (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation); - -typedef void (*json_test_cb_t) (json_test_ctx_t *ctx, const bson_t *test); - -bool -json_test_operation (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation, - mongoc_collection_t *collection, - mongoc_client_session_t *session, - bson_t *reply); - -void -json_test_operations (json_test_ctx_t *ctx, const bson_t *test); - -void -check_result (const bson_t *test, - const bson_t *operation, - bool succeeded, - const bson_value_t *result, - const bson_error_t *error); - -#endif diff --git a/lib/mongoc/libmongoc/tests/json-test.c b/lib/mongoc/libmongoc/tests/json-test.c deleted file mode 100644 index 4646062f6270e2d3b330a3035645d61bae7e6b4f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json-test.c +++ /dev/null @@ -1,1672 +0,0 @@ -/* - * Copyright 2015-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 <mongoc/mongoc.h> -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-client-side-encryption.h" - -#include "json-test.h" -#include "json-test-operations.h" -#include "json-test-monitoring.h" -#include "TestSuite.h" -#include "test-libmongoc.h" - -#ifdef _MSC_VER -#include <io.h> -#else -#include <dirent.h> -#endif - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - - -mongoc_topology_description_type_t -topology_type_from_test (const char *type) -{ - if (strcmp (type, "ReplicaSetWithPrimary") == 0) { - return MONGOC_TOPOLOGY_RS_WITH_PRIMARY; - } else if (strcmp (type, "ReplicaSetNoPrimary") == 0) { - return MONGOC_TOPOLOGY_RS_NO_PRIMARY; - } else if (strcmp (type, "Unknown") == 0) { - return MONGOC_TOPOLOGY_UNKNOWN; - } else if (strcmp (type, "Single") == 0) { - return MONGOC_TOPOLOGY_SINGLE; - } else if (strcmp (type, "Sharded") == 0) { - return MONGOC_TOPOLOGY_SHARDED; - } - - fprintf (stderr, "can't parse this: %s", type); - BSON_ASSERT (0); - return 0; -} - -mongoc_server_description_type_t -server_type_from_test (const char *type) -{ - if (strcmp (type, "RSPrimary") == 0) { - return MONGOC_SERVER_RS_PRIMARY; - } else if (strcmp (type, "RSSecondary") == 0) { - return MONGOC_SERVER_RS_SECONDARY; - } else if (strcmp (type, "Standalone") == 0) { - return MONGOC_SERVER_STANDALONE; - } else if (strcmp (type, "Mongos") == 0) { - return MONGOC_SERVER_MONGOS; - } else if (strcmp (type, "PossiblePrimary") == 0) { - return MONGOC_SERVER_POSSIBLE_PRIMARY; - } else if (strcmp (type, "RSArbiter") == 0) { - return MONGOC_SERVER_RS_ARBITER; - } else if (strcmp (type, "RSOther") == 0) { - return MONGOC_SERVER_RS_OTHER; - } else if (strcmp (type, "RSGhost") == 0) { - return MONGOC_SERVER_RS_GHOST; - } else if (strcmp (type, "Unknown") == 0) { - return MONGOC_SERVER_UNKNOWN; - } - fprintf (stderr, "ERROR: Unknown server type %s\n", type); - BSON_ASSERT (0); - return 0; -} - - -static mongoc_read_mode_t -read_mode_from_test (const char *mode) -{ - if (bson_strcasecmp (mode, "Primary") == 0) { - return MONGOC_READ_PRIMARY; - } else if (bson_strcasecmp (mode, "PrimaryPreferred") == 0) { - return MONGOC_READ_PRIMARY_PREFERRED; - } else if (bson_strcasecmp (mode, "Secondary") == 0) { - return MONGOC_READ_SECONDARY; - } else if (bson_strcasecmp (mode, "SecondaryPreferred") == 0) { - return MONGOC_READ_SECONDARY_PREFERRED; - } else if (bson_strcasecmp (mode, "Nearest") == 0) { - return MONGOC_READ_NEAREST; - } else { - test_error ("Unknown read preference mode \"%s\"", mode); - } - - return MONGOC_READ_PRIMARY; -} - - -static mongoc_ss_optype_t -optype_from_test (const char *op) -{ - if (strcmp (op, "read") == 0) { - return MONGOC_SS_READ; - } else if (strcmp (op, "write") == 0) { - return MONGOC_SS_WRITE; - } - - return MONGOC_SS_READ; -} - - -/* - *----------------------------------------------------------------------- - * - * server_description_by_hostname -- - * - * Return a reference to a mongoc_server_description_t or NULL. - * - *----------------------------------------------------------------------- - */ -mongoc_server_description_t * -server_description_by_hostname (mongoc_topology_description_t *topology, - const char *address) -{ - mongoc_set_t *set = topology->servers; - mongoc_server_description_t *server_iter; - int i; - - for (i = 0; i < set->items_len; i++) { - server_iter = (mongoc_server_description_t *) mongoc_set_get_item ( - topology->servers, i); - - if (strcasecmp (address, server_iter->connection_address) == 0) { - return server_iter; - } - } - - return NULL; -} - - -/* - *----------------------------------------------------------------------- - * - * process_sdam_test_ismaster_responses -- - * - * Update a topology description with the ismaster responses in a "phase" - * from an SDAM or SDAM Monitoring test, like: - * - * [ - * [ - * "a:27017", - * { - * "ok": 1, - * "ismaster": false - * } - * ] - * ] - * - * See: - * https://github.com/mongodb/specifications/tree/master/source/server-discovery-and-monitoring/tests - * - *----------------------------------------------------------------------- - */ -void -process_sdam_test_ismaster_responses (bson_t *phase, - mongoc_topology_description_t *td) -{ - mongoc_server_description_t *sd; - bson_t ismasters; - bson_t ismaster; - bson_t response; - bson_iter_t phase_field_iter; - bson_iter_t ismaster_iter; - bson_iter_t ismaster_field_iter; - const char *hostname; - - /* grab ismaster responses out and feed them to topology */ - BSON_ASSERT (bson_iter_init_find (&phase_field_iter, phase, "responses")); - bson_iter_bson (&phase_field_iter, &ismasters); - bson_iter_init (&ismaster_iter, &ismasters); - - while (bson_iter_next (&ismaster_iter)) { - bson_iter_bson (&ismaster_iter, &ismaster); - - bson_iter_init_find (&ismaster_field_iter, &ismaster, "0"); - hostname = bson_iter_utf8 (&ismaster_field_iter, NULL); - sd = server_description_by_hostname (td, hostname); - - /* if server has been removed from topology, skip */ - if (!sd) { - continue; - } - - bson_iter_init_find (&ismaster_field_iter, &ismaster, "1"); - bson_iter_bson (&ismaster_field_iter, &response); - - /* send ismaster through the topology description's handler */ - capture_logs (true); - mongoc_topology_description_handle_ismaster ( - td, sd->id, &response, 1, NULL); - if (td->servers->items_len == 0) { - ASSERT_CAPTURED_LOG ("topology", - MONGOC_LOG_LEVEL_WARNING, - "Last server removed from topology"); - } - capture_logs (false); - } -} - - -/* - *----------------------------------------------------------------------- - * - * test_server_selection_logic_cb -- - * - * Runs the JSON tests for server selection logic that are - * included with the Server Selection spec. - * - *----------------------------------------------------------------------- - */ -void -test_server_selection_logic_cb (bson_t *test) -{ - bool expected_error; - bson_error_t error; - int32_t heartbeat_msec; - mongoc_topology_description_t topology; - mongoc_server_description_t *sd; - mongoc_read_prefs_t *read_prefs; - mongoc_read_mode_t read_mode; - mongoc_ss_optype_t op; - bson_iter_t iter; - bson_iter_t topology_iter; - bson_iter_t server_iter; - bson_iter_t sd_iter; - bson_iter_t read_pref_iter; - bson_iter_t tag_sets_iter; - bson_iter_t last_write_iter; - bson_iter_t expected_servers_iter; - bson_t first_tag_set; - bson_t test_topology; - bson_t test_servers; - bson_t server; - bson_t test_read_pref; - bson_t test_tag_sets; - uint32_t i = 0; - bool matched_servers[50]; - mongoc_array_t selected_servers; - - _mongoc_array_init (&selected_servers, - sizeof (mongoc_server_description_t *)); - - BSON_ASSERT (test); - - expected_error = - bson_iter_init_find (&iter, test, "error") && bson_iter_as_bool (&iter); - - heartbeat_msec = MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED; - - if (bson_iter_init_find (&iter, test, "heartbeatFrequencyMS")) { - heartbeat_msec = bson_iter_int32 (&iter); - } - - /* pull out topology description field */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "topology_description")); - bson_iter_bson (&iter, &test_topology); - - /* set topology state from test */ - BSON_ASSERT (bson_iter_init_find (&topology_iter, &test_topology, "type")); - - mongoc_topology_description_init (&topology, heartbeat_msec); - topology.type = - topology_type_from_test (bson_iter_utf8 (&topology_iter, NULL)); - - /* for each server description in test, add server to our topology */ - BSON_ASSERT ( - bson_iter_init_find (&topology_iter, &test_topology, "servers")); - bson_iter_bson (&topology_iter, &test_servers); - - bson_iter_init (&server_iter, &test_servers); - while (bson_iter_next (&server_iter)) { - bson_iter_bson (&server_iter, &server); - - /* initialize new server description with given address */ - sd = (mongoc_server_description_t *) bson_malloc0 (sizeof *sd); - BSON_ASSERT (bson_iter_init_find (&sd_iter, &server, "address")); - mongoc_server_description_init (sd, bson_iter_utf8 (&sd_iter, NULL), i++); - - BSON_ASSERT (bson_iter_init_find (&sd_iter, &server, "type")); - sd->type = server_type_from_test (bson_iter_utf8 (&sd_iter, NULL)); - - if (bson_iter_init_find (&sd_iter, &server, "avg_rtt_ms")) { - sd->round_trip_time_msec = bson_iter_int32 (&sd_iter); - } else if (sd->type != MONGOC_SERVER_UNKNOWN) { - test_error ("%s has no avg_rtt_ms", sd->host.host_and_port); - abort (); - } - - if (bson_iter_init_find (&sd_iter, &server, "maxWireVersion")) { - sd->max_wire_version = (int32_t) bson_iter_as_int64 (&sd_iter); - } - - if (bson_iter_init_find (&sd_iter, &server, "lastUpdateTime")) { - sd->last_update_time_usec = bson_iter_as_int64 (&sd_iter) * 1000; - } - - if (bson_iter_init_find (&sd_iter, &server, "lastWrite")) { - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&sd_iter) && - bson_iter_recurse (&sd_iter, &last_write_iter) && - bson_iter_find (&last_write_iter, "lastWriteDate") && - BSON_ITER_HOLDS_INT (&last_write_iter)); - sd->last_write_date_ms = bson_iter_as_int64 (&last_write_iter); - } - - if (bson_iter_init_find (&sd_iter, &server, "tags")) { - bson_destroy (&sd->tags); - bson_iter_bson (&sd_iter, &sd->tags); - } - - /* add new server to our topology description */ - mongoc_set_add (topology.servers, sd->id, sd); - } - - /* create read preference document from test */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "read_preference")); - bson_iter_bson (&iter, &test_read_pref); - - if (bson_iter_init_find (&read_pref_iter, &test_read_pref, "mode")) { - read_mode = read_mode_from_test (bson_iter_utf8 (&read_pref_iter, NULL)); - ASSERT_CMPINT (read_mode, !=, 0); - } else { - read_mode = MONGOC_READ_PRIMARY; - } - - read_prefs = mongoc_read_prefs_new (read_mode); - - if (bson_iter_init_find (&read_pref_iter, &test_read_pref, "tag_sets")) { - /* ignore "tag_sets: [{}]" */ - if (bson_iter_recurse (&read_pref_iter, &tag_sets_iter) && - bson_iter_next (&tag_sets_iter) && - BSON_ITER_HOLDS_DOCUMENT (&tag_sets_iter)) { - bson_iter_bson (&tag_sets_iter, &first_tag_set); - if (!bson_empty (&first_tag_set)) { - /* not empty */ - bson_iter_bson (&read_pref_iter, &test_tag_sets); - mongoc_read_prefs_set_tags (read_prefs, &test_tag_sets); - } - } - } - - if (bson_iter_init_find ( - &read_pref_iter, &test_read_pref, "maxStalenessSeconds")) { - mongoc_read_prefs_set_max_staleness_seconds ( - read_prefs, bson_iter_as_int64 (&read_pref_iter)); - } - - /* get operation type */ - op = MONGOC_SS_READ; - - if (bson_iter_init_find (&iter, test, "operation")) { - op = optype_from_test (bson_iter_utf8 (&iter, NULL)); - } - - if (expected_error) { - BSON_ASSERT (!mongoc_read_prefs_is_valid (read_prefs) || - !mongoc_topology_compatible (&topology, read_prefs, &error)); - goto DONE; - } - - /* no expected error */ - BSON_ASSERT (mongoc_read_prefs_is_valid (read_prefs)); - BSON_ASSERT (mongoc_topology_compatible (&topology, read_prefs, &error)); - - /* read in latency window servers */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "in_latency_window")); - - /* TODO: use topology_select instead? */ - mongoc_topology_description_suitable_servers ( - &selected_servers, - op, - &topology, - read_prefs, - MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS); - - /* check each server in expected_servers is in selected_servers */ - memset (matched_servers, 0, sizeof (matched_servers)); - bson_iter_recurse (&iter, &expected_servers_iter); - while (bson_iter_next (&expected_servers_iter)) { - bool found = false; - bson_iter_t host; - - BSON_ASSERT (bson_iter_recurse (&expected_servers_iter, &host)); - BSON_ASSERT (bson_iter_find (&host, "address")); - - for (i = 0; i < selected_servers.len; i++) { - sd = _mongoc_array_index ( - &selected_servers, mongoc_server_description_t *, i); - - if (strcmp (sd->host.host_and_port, bson_iter_utf8 (&host, NULL)) == - 0) { - found = true; - break; - } - } - - if (!found) { - test_error ("Should have been selected but wasn't: %s", - bson_iter_utf8 (&host, NULL)); - abort (); - } - - matched_servers[i] = true; - } - - /* check each server in selected_servers is in expected_servers */ - for (i = 0; i < selected_servers.len; i++) { - if (!matched_servers[i]) { - sd = _mongoc_array_index ( - &selected_servers, mongoc_server_description_t *, i); - - test_error ("Shouldn't have been selected but was: %s", - sd->host.host_and_port); - abort (); - } - } - -DONE: - mongoc_read_prefs_destroy (read_prefs); - mongoc_topology_description_destroy (&topology); - _mongoc_array_destroy (&selected_servers); -} - -/* - *----------------------------------------------------------------------- - * - * assemble_path -- - * - * Given a parent directory and filename, compile a full path to - * the child file. - * - * "dst" receives the joined path, delimited by "/" even on Windows. - * - *----------------------------------------------------------------------- - */ -void -assemble_path (const char *parent_path, - const char *child_name, - char *dst /* OUT */) -{ - char *p; - int path_len = (int) strlen (parent_path); - int name_len = (int) strlen (child_name); - - BSON_ASSERT (path_len + name_len + 1 < MAX_TEST_NAME_LENGTH); - - memset (dst, '\0', MAX_TEST_NAME_LENGTH * sizeof (char)); - strncat (dst, parent_path, path_len); - strncat (dst, "/", 1); - strncat (dst, child_name, name_len); - - for (p = dst; *p; ++p) { - if (*p == '\\') { - *p = '/'; - } - } -} - -/* - *----------------------------------------------------------------------- - * - * collect_tests_from_dir -- - * - * Recursively search the directory at @dir_path for files with - * '.json' in their filenames. Append all found file paths to - * @paths, and return the number of files found. - * - *----------------------------------------------------------------------- - */ -int -collect_tests_from_dir (char (*paths)[MAX_TEST_NAME_LENGTH] /* OUT */, - const char *dir_path, - int paths_index, - int max_paths) -{ -#ifdef _MSC_VER - char *dir_path_plus_star; - intptr_t handle; - struct _finddata_t info; - - char child_path[MAX_TEST_NAME_LENGTH]; - - dir_path_plus_star = bson_strdup_printf ("%s/*", dir_path); - handle = _findfirst (dir_path_plus_star, &info); - - if (handle == -1) { - bson_free (dir_path_plus_star); - return 0; - } - - while (1) { - BSON_ASSERT (paths_index < max_paths); - - if (info.attrib & _A_SUBDIR) { - /* recursively call on child directories */ - if (strcmp (info.name, "..") != 0 && strcmp (info.name, ".") != 0) { - assemble_path (dir_path, info.name, child_path); - paths_index = collect_tests_from_dir ( - paths, child_path, paths_index, max_paths); - } - } else if (strstr (info.name, ".json")) { - /* if this is a JSON test, collect its path */ - assemble_path (dir_path, info.name, paths[paths_index++]); - } - - if (_findnext (handle, &info) == -1) { - break; - } - } - - bson_free (dir_path_plus_star); - _findclose (handle); - - return paths_index; -#else - struct dirent *entry; - struct stat dir_stat; - char child_path[MAX_TEST_NAME_LENGTH]; - DIR *dir; - - dir = opendir (dir_path); - if (!dir) { - MONGOC_ERROR ("Cannot open \"%s\"", dir_path); - MONGOC_ERROR ("Run test-libmongoc in repository root directory.\n"); - abort (); - } - - while ((entry = readdir (dir))) { - BSON_ASSERT (paths_index < max_paths); - if (strcmp (entry->d_name, "..") == 0 || - strcmp (entry->d_name, ".") == 0) { - continue; - } - - assemble_path (dir_path, entry->d_name, child_path); - - if (0 == stat (child_path, &dir_stat) && S_ISDIR (dir_stat.st_mode)) { - /* recursively call on child directories */ - paths_index = - collect_tests_from_dir (paths, child_path, paths_index, max_paths); - } else if (strstr (entry->d_name, ".json")) { - /* if this is a JSON test, collect its path */ - assemble_path (dir_path, entry->d_name, paths[paths_index++]); - } - } - - closedir (dir); - - return paths_index; -#endif -} - -/* - *----------------------------------------------------------------------- - * - * get_bson_from_json_file -- - * - * Open the file at @filename and store its contents in a - * bson_t. This function assumes that @filename contains a - * single JSON object. - * - * NOTE: caller owns returned bson_t and must free it. - * - *----------------------------------------------------------------------- - */ -bson_t * -get_bson_from_json_file (char *filename) -{ - FILE *file; - long length; - bson_t *data; - bson_error_t error; - const char *buffer; - - file = fopen (filename, "rb"); - if (!file) { - return NULL; - } - - /* get file length */ - fseek (file, 0, SEEK_END); - length = ftell (file); - fseek (file, 0, SEEK_SET); - if (length < 1) { - return NULL; - } - - /* read entire file into buffer */ - buffer = (const char *) bson_malloc0 (length); - if (fread ((void *) buffer, 1, length, file) != length) { - abort (); - } - - fclose (file); - if (!buffer) { - return NULL; - } - - /* convert to bson */ - data = bson_new_from_json ((const uint8_t *) buffer, length, &error); - if (!data) { - fprintf (stderr, "Cannot parse %s: %s\n", filename, error.message); - abort (); - } - - bson_free ((void *) buffer); - - return data; -} - -static bool -check_version_info (const bson_t *scenario, bool print_reason) -{ - const char *s; - char *padded; - server_version_t test_version, server_version; - - if (bson_has_field (scenario, "maxServerVersion")) { - s = bson_lookup_utf8 (scenario, "maxServerVersion"); - /* s is like "3.0", don't skip if server is 3.0.x but skip 3.1+ */ - padded = bson_strdup_printf ("%s.99", s); - test_version = test_framework_str_to_version (padded); - bson_free (padded); - server_version = test_framework_get_server_version (); - if (server_version > test_version) { - if (print_reason && test_suite_debug_output ()) { - printf (" SKIP, maxServerVersion=\"%s\"\n", s); - fflush (stdout); - } - - return false; - } - } - - if (bson_has_field (scenario, "minServerVersion")) { - s = bson_lookup_utf8 (scenario, "minServerVersion"); - test_version = test_framework_str_to_version (s); - server_version = test_framework_get_server_version (); - if (server_version < test_version) { - if (print_reason && test_suite_debug_output ()) { - printf (" SKIP, minServerVersion=\"%s\"\n", s); - fflush (stdout); - } - - return false; - } - } - - if (bson_has_field (scenario, "topology")) { - bson_iter_t iter; - bson_t topology; - char *current_topology; - - BSON_ASSERT (bson_iter_init_find (&iter, scenario, "topology")); - BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (&iter)); - - bson_iter_bson (&iter, &topology); - - /* Determine cluster type */ - if (test_framework_is_mongos ()) { - current_topology = "sharded"; - } else if (test_framework_is_replset ()) { - current_topology = "replicaset"; - } else { - current_topology = "single"; - } - - bson_iter_init (&iter, &topology); - while (bson_iter_next (&iter)) { - const char *test_topology; - - BSON_ASSERT (BSON_ITER_HOLDS_UTF8 (&iter)); - test_topology = bson_iter_utf8 (&iter, NULL); - - if (strcmp (test_topology, current_topology) == 0) { - return true; - } - } - - /* If we didn't match any of the listed topologies, skip */ - if (print_reason && test_suite_debug_output ()) { - printf (" SKIP, test topologies do not match current %s setup\n", - current_topology); - fflush (stdout); - } - - return false; - } - - return true; -} - -static bool -check_scenario_version (const bson_t *scenario) -{ - /* version info can be nested inside "runOn" array */ - if (bson_has_field (scenario, "runOn")) { - bson_iter_t iter; - bson_t run_on; - bson_t version_info; - - bson_lookup_doc (scenario, "runOn", &run_on); - BSON_ASSERT (bson_iter_init (&iter, &run_on)); - - while (bson_iter_next (&iter)) { - bson_iter_bson (&iter, &version_info); - if (check_version_info (&version_info, false)) { - return true; - } - } - - if (test_suite_debug_output ()) { - printf (" SKIP, no matching topologies in runOn\n"); - fflush (stdout); - } - - return false; - } - - return check_version_info (scenario, true); -} - - -static int -check_test_version (const bson_t *test) -{ - const char *s; - char *padded; - server_version_t test_version, server_version; - - if (bson_has_field (test, "minServerVersion")) { - s = bson_lookup_utf8 (test, "minServerVersion"); - test_version = test_framework_str_to_version (s); - server_version = test_framework_get_server_version (); - if (server_version < test_version) { - if (test_suite_debug_output ()) { - printf (" SKIP, minServerVersion %s\n", s); - fflush (stdout); - } - return false; - } - } - - if (bson_has_field (test, "ignore_if_server_version_greater_than")) { - s = bson_lookup_utf8 (test, "ignore_if_server_version_greater_than"); - /* s is like "3.0", don't skip if server is 3.0.x but skip 3.1+ */ - padded = bson_strdup_printf ("%s.99", s); - test_version = test_framework_str_to_version (padded); - bson_free (padded); - server_version = test_framework_get_server_version (); - if (server_version > test_version) { - if (test_suite_debug_output ()) { - printf (" SKIP, ignore_if_server_version_greater_than %s\n", - s); - fflush (stdout); - } - return false; - } - } - - if (bson_has_field (test, "ignore_if_server_version_less_than")) { - s = bson_lookup_utf8 (test, "ignore_if_server_version_less_than"); - test_version = test_framework_str_to_version (s); - server_version = test_framework_get_server_version (); - if (server_version < test_version) { - if (test_suite_debug_output ()) { - printf (" SKIP, ignore_if_server_version_less_than %s\n", s); - fflush (stdout); - } - return false; - } - } - - /* server version is ok, don't skip the test */ - return true; -} - - -/* is this test allowed to run against the current test topology? */ -static bool -check_topology_type (const bson_t *test) -{ - bson_iter_t iter; - bson_iter_t child; - const char *s; - bool compatible; - bool is_mongos; - bool is_replset; - bool is_single; - bool match; - bool can_proceed; - - /* "topology" is an array of compatible topologies. - * "ignore_if_topology_type" is an array of incompatible types. - * So far, the only valid values are "single", "sharded", and "replicaset" - */ - - if (bson_iter_init_find (&iter, test, "topology")) { - compatible = true; - } else if (bson_iter_init_find (&iter, test, "ignore_if_topology_type")) { - compatible = false; - } else { - return true; - } - - ASSERT (BSON_ITER_HOLDS_ARRAY (&iter)); - ASSERT (bson_iter_recurse (&iter, &child)); - - is_mongos = test_framework_is_mongos (); - is_replset = test_framework_is_replset (); - is_single = !is_mongos && !is_replset; - match = false; - - while (bson_iter_next (&child)) { - if (BSON_ITER_HOLDS_UTF8 (&child)) { - s = bson_iter_utf8 (&child, NULL); - if (!strcmp (s, "sharded") && is_mongos) { - match = true; - } else if (!strcmp (s, "replicaset") && is_replset) { - match = true; - } else if (!strcmp (s, "single") && is_single) { - match = true; - } - } - } - - can_proceed = (compatible == match); - - if (!can_proceed && test_suite_debug_output ()) { - printf (" SKIP, incompatible topology type\n"); - fflush (stdout); - } - - return can_proceed; -} - - -static void -_insert_data (mongoc_collection_t *collection, bson_t *documents) -{ - bson_iter_t iter; - mongoc_bulk_operation_t *bulk; - bson_t *majority = tmp_bson ("{'writeConcern': {'w': 'majority'}}"); - bool r; - uint32_t server_id; - bson_error_t error; - - mongoc_collection_delete_many ( - collection, tmp_bson ("{}"), majority, NULL, NULL); - - if (!bson_count_keys (documents)) { - return; - } - - bson_iter_init (&iter, documents); - bulk = - mongoc_collection_create_bulk_operation_with_opts (collection, majority); - - while (bson_iter_next (&iter)) { - bson_t document; - bson_t opts = BSON_INITIALIZER; - - bson_iter_bson (&iter, &document); - r = mongoc_bulk_operation_insert_with_opts ( - bulk, &document, &opts, &error); - ASSERT_OR_PRINT (r, error); - - bson_destroy (&opts); - } - - server_id = mongoc_bulk_operation_execute (bulk, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - - mongoc_bulk_operation_destroy (bulk); -} - - -/* insert the documents in a spec test scenario's "data" array */ -static void -insert_data (const char *db_name, - const char *collection_name, - const bson_t *scenario) -{ - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_collection_t *collection; - mongoc_collection_t *tmp_collection; - bson_error_t error; - bson_t documents; - bson_iter_t iter; - bson_t *majority = tmp_bson ("{'writeConcern': {'w': 'majority'}}"); - - /* use a fresh client to prepare the collection */ - client = test_framework_client_new (); - - db = mongoc_client_get_database (client, db_name); - collection = mongoc_database_get_collection (db, collection_name); - mongoc_collection_delete_many ( - collection, tmp_bson ("{}"), majority, NULL, NULL); - - /* drop the collection in case an existing JSON schema exists. */ - mongoc_collection_drop (collection, &error); - - /* ignore failure if it already exists */ - tmp_collection = - mongoc_database_create_collection (db, collection_name, majority, &error); - - if (tmp_collection) { - mongoc_collection_destroy (tmp_collection); - } - - if (!bson_has_field (scenario, "data")) { - goto DONE; - } - - bson_iter_init_find (&iter, scenario, "data"); - - if (BSON_ITER_HOLDS_ARRAY (&iter)) { - bson_lookup_doc (scenario, "data", &documents); - _insert_data (collection, &documents); - } else { - /* go through collection: [] */ - bson_iter_recurse (&iter, &iter); - while (bson_iter_next (&iter)) { - bson_t collection_documents; - - mongoc_collection_destroy (collection); - collection = - mongoc_database_get_collection (db, bson_iter_key (&iter)); - bson_iter_bson (&iter, &collection_documents); - _insert_data (collection, &collection_documents); - } - } - -DONE: - mongoc_database_destroy (db); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -check_outcome_collection (mongoc_collection_t *collection, bson_t *test) -{ - bson_t data; - bson_iter_t iter; - mongoc_read_concern_t *rc; - mongoc_cursor_t *cursor; - bson_t query = BSON_INITIALIZER; - mongoc_read_prefs_t *prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - bson_lookup_doc (test, "outcome.collection.data", &data); - ASSERT (bson_iter_init (&iter, &data)); - - rc = mongoc_read_concern_new (); - - /* If the collection has had its read_concern set by a test, - make sure it's set to LOCAL for this check. */ - if (mongoc_read_concern_get_level (collection->read_concern)) { - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_LOCAL); - mongoc_collection_set_read_concern (collection, rc); - } - - cursor = mongoc_collection_find_with_opts (collection, &query, NULL, prefs); - - while (bson_iter_next (&iter)) { - bson_t expected_doc; - const bson_t *actual_doc; - - bson_iter_bson (&iter, &expected_doc); - ASSERT_CURSOR_NEXT (cursor, &actual_doc); - ASSERT (match_bson (actual_doc, &expected_doc, false)); - } - - ASSERT_CURSOR_DONE (cursor); - - bson_destroy (&data); - mongoc_read_prefs_destroy (prefs); - bson_destroy (&query); - mongoc_read_concern_destroy (rc); - mongoc_cursor_destroy (cursor); -} - - -static void -execute_test (const json_test_config_t *config, - mongoc_client_t *client, - mongoc_database_t *db, - mongoc_collection_t *collection, - bson_t *test) -{ - json_test_ctx_t ctx; - uint32_t server_id; - bson_error_t error; - mongoc_client_t *outcome_client; - mongoc_collection_t *outcome_coll; - - if (test_suite_debug_output ()) { - const char *description = bson_lookup_utf8 (test, "description"); - printf (" - %s\n", description); - fflush (stdout); - } - - if (!check_test_version (test) || !check_topology_type (test)) { - return; - } - - /* Select a primary for testing */ - server_id = mongoc_topology_select_server_id ( - collection->client->topology, MONGOC_SS_WRITE, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - - json_test_ctx_init (&ctx, test, client, db, collection, config); - - if (config->before_test_cb) { - config->before_test_cb (&ctx, test); - } - - if (bson_has_field (test, "failPoint")) { - activate_fail_point (client, server_id, test, "failPoint"); - } - - set_apm_callbacks (&ctx, collection->client); - - json_test_operations (&ctx, test); - - if (config->after_test_cb) { - config->after_test_cb (&ctx, test); - } - - json_test_ctx_end_sessions (&ctx); - - if (bson_has_field (test, "expectations")) { - bson_t expectations; - - bson_lookup_doc (test, "expectations", &expectations); - check_json_apm_events (&ctx, &expectations); - if (config->events_check_cb) { - config->events_check_cb (&ctx.events); - } - } - - if (bson_has_field (test, "outcome.collection")) { - /* Use a fresh client to check the outcome collection. */ - outcome_client = test_framework_client_new (); - if (bson_has_field (test, "outcome.collection.name")) { - outcome_coll = mongoc_client_get_collection ( - outcome_client, - mongoc_database_get_name (db), - bson_lookup_utf8 (test, "outcome.collection.name")); - - } else { - outcome_coll = mongoc_client_get_collection ( - outcome_client, - mongoc_database_get_name (db), - mongoc_collection_get_name (collection)); - } - check_outcome_collection (outcome_coll, test); - mongoc_collection_destroy (outcome_coll); - mongoc_client_destroy (outcome_client); - } - - mongoc_client_set_apm_callbacks (collection->client, NULL, NULL); - json_test_ctx_cleanup (&ctx); - - if (!client->cse_enabled) { - /* The configureFailpoint command is not supported for CSE. - * But we need to disable failpoints on the client that knows - * the server description for "server_id". I.e. we cannot use - * a separate client. So, as a special case, skip disabling - * failpoints if CSE is enabled. (the CSE tests don't currently - * use failpoints). */ - deactivate_fail_points (client, server_id); - } -} - - -void -activate_fail_point (mongoc_client_t *client, - const uint32_t server_id, - const bson_t *test, - const char *key) -{ - bson_t command; - bson_error_t error; - bool r; - - BSON_ASSERT (client); - BSON_ASSERT (server_id); - - bson_lookup_doc (test, key, &command); - - ASSERT_CMPSTR (_mongoc_get_command_name (&command), "configureFailPoint"); - r = mongoc_client_command_simple_with_server_id ( - client, "admin", &command, NULL, server_id, NULL, &error); - ASSERT_OR_PRINT (r, error); -} - -/* - *----------------------------------------------------------------------- - * - * deactivate_fail_points -- - * - * Deactivate the onPrimaryTransactionalWrite fail point, and all - * future fail points used in JSON tests. - * - *----------------------------------------------------------------------- - */ -void -deactivate_fail_points (mongoc_client_t *client, uint32_t server_id) -{ - mongoc_server_description_t *sd; - bson_t *command; - bool r; - bson_error_t error; - - sd = mongoc_client_get_server_description (client, server_id); - BSON_ASSERT (sd); - - if (sd->type == MONGOC_SERVER_RS_PRIMARY && - sd->max_wire_version >= WIRE_VERSION_RETRY_WRITES) { - command = - tmp_bson ("{'configureFailPoint': 'onPrimaryTransactionalWrite'," - " 'mode': 'off'}"); - - r = mongoc_client_command_simple_with_server_id ( - client, "admin", command, NULL, server_id, NULL, &error); - ASSERT_OR_PRINT (r, error); - - command = tmp_bson ("{'configureFailPoint': 'failCommand'," - " 'mode': 'off'}"); - - r = mongoc_client_command_simple_with_server_id ( - client, "admin", command, NULL, server_id, NULL, &error); - - /* ignore error from servers that predate "failCommand" fail point */ - if (!r && !strstr (error.message, "failCommand not found")) { - ASSERT_OR_PRINT (r, error); - } - } - - mongoc_server_description_destroy (sd); -} - - -static void -set_uri_opts_from_bson (mongoc_uri_t *uri, const bson_t *opts) -{ - bson_iter_t iter; - - BSON_ASSERT (bson_iter_init (&iter, opts)); - while (bson_iter_next (&iter)) { - /* can't use bson_lookup_write_concern etc. with clientOptions format */ - if (!strcmp (bson_iter_key (&iter), "w")) { - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - if (BSON_ITER_HOLDS_UTF8 (&iter)) { - mongoc_write_concern_set_wtag (wc, bson_iter_utf8 (&iter, NULL)); - } else if (BSON_ITER_HOLDS_INT (&iter)) { - mongoc_write_concern_set_w (wc, - (int32_t) bson_iter_as_int64 (&iter)); - } else { - test_error ("Unrecognized type for 'w': %d", - bson_iter_type (&iter)); - } - - mongoc_uri_set_write_concern (uri, wc); - mongoc_write_concern_destroy (wc); - } else if (!strcmp (bson_iter_key (&iter), "readConcernLevel")) { - mongoc_read_concern_t *rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, bson_iter_utf8 (&iter, NULL)); - mongoc_uri_set_read_concern (uri, rc); - mongoc_read_concern_destroy (rc); - } else if (!strcmp (bson_iter_key (&iter), "readPreference")) { - mongoc_read_prefs_t *read_prefs = mongoc_read_prefs_new ( - read_mode_from_test (bson_iter_utf8 (&iter, NULL))); - mongoc_uri_set_read_prefs_t (uri, read_prefs); - mongoc_read_prefs_destroy (read_prefs); - } else if (!strcmp (bson_iter_key (&iter), "retryWrites")) { - mongoc_uri_set_option_as_bool ( - uri, "retryWrites", bson_iter_bool (&iter)); - } else if (!strcmp (bson_iter_key (&iter), "heartbeatFrequencyMS")) { - mongoc_uri_set_option_as_int32 ( - uri, "heartbeatFrequencyMS", bson_iter_int32 (&iter)); - } else if (!strcmp (bson_iter_key (&iter), "retryReads")) { - mongoc_uri_set_option_as_bool ( - uri, "retryReads", bson_iter_bool (&iter)); - } else if (!strcmp (bson_iter_key (&iter), "autoEncryptOpts")) { - /* Auto encrypt options are set on constructed client, not in URI. */ - } else { - MONGOC_ERROR ("Unsupported clientOptions field \"%s\" in %s", - bson_iter_key (&iter), - bson_as_json (opts, NULL)); - abort (); - } - } -} - -static void -set_auto_encryption_opts (mongoc_client_t *client, bson_t *test) -{ - bson_t opts; - bson_iter_t iter; - mongoc_auto_encryption_opts_t *auto_encryption_opts; - bson_error_t error; - bool ret; - bson_t extra; - - if (!bson_has_field (test, "clientOptions.autoEncryptOpts")) { - return; - } - - bson_lookup_doc (test, "clientOptions.autoEncryptOpts", &opts); - auto_encryption_opts = mongoc_auto_encryption_opts_new (); - - if (bson_iter_init_find (&iter, &opts, "kmsProviders")) { - bson_t kms_providers; - bson_t tmp; - - bson_iter_bson (&iter, &tmp); - bson_copy_to_excluding (&tmp, &kms_providers, "aws", NULL); - - /* AWS credentials are set from environment variables. */ - if (bson_has_field (&opts, "kmsProviders.aws")) { - char *aws_secret_access_key; - char *aws_access_key_id; - - aws_secret_access_key = - test_framework_getenv ("MONGOC_TEST_AWS_SECRET_ACCESS_KEY"); - aws_access_key_id = - test_framework_getenv ("MONGOC_TEST_AWS_ACCESS_KEY_ID"); - - if (!aws_secret_access_key || !aws_access_key_id) { - fprintf (stderr, - "Set MONGOC_TEST_AWS_SECRET_ACCESS_KEY and " - "MONGOC_TEST_AWS_ACCESS_KEY_ID environment " - "variables to run Client Side Encryption tests."); - abort (); - } - - bson_concat ( - &kms_providers, - tmp_bson ( - "{ 'aws': { 'secretAccessKey': '%s', 'accessKeyId': '%s' }}", - aws_secret_access_key, - aws_access_key_id)); - - bson_free (aws_secret_access_key); - bson_free (aws_access_key_id); - } - - mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts, - &kms_providers); - bson_destroy (&kms_providers); - } - - if (bson_iter_init_find (&iter, &opts, "schemaMap")) { - bson_t schema_map; - - bson_iter_bson (&iter, &schema_map); - mongoc_auto_encryption_opts_set_schema_map (auto_encryption_opts, - &schema_map); - bson_destroy (&schema_map); - } - - if (bson_iter_init_find (&iter, &opts, "bypassAutoEncryption")) { - mongoc_auto_encryption_opts_set_bypass_auto_encryption ( - auto_encryption_opts, bson_iter_as_bool (&iter)); - } - - if (bson_iter_init_find (&iter, &opts, "keyVaultNamespace")) { - const char *key_vault_ns; - char *db_name; - char *coll_name; - char *dot; - - BSON_ASSERT (BSON_ITER_HOLDS_UTF8 (&iter)); - key_vault_ns = bson_iter_utf8 (&iter, NULL); - dot = strstr (key_vault_ns, "."); - BSON_ASSERT (dot); - db_name = bson_strndup (key_vault_ns, dot - key_vault_ns); - coll_name = bson_strdup (dot + 1); - mongoc_auto_encryption_opts_set_key_vault_namespace ( - auto_encryption_opts, db_name, coll_name); - - bson_free (db_name); - bson_free (coll_name); - } else { - /* "If ``autoEncryptOpts`` does not include ``keyVaultNamespace``, default - * it to ``admin.datakeys``" */ - mongoc_auto_encryption_opts_set_key_vault_namespace ( - auto_encryption_opts, "admin", "datakeys"); - } - - if (bson_iter_init_find (&iter, &opts, "extra")) { - bson_t tmp; - - bson_iter_bson (&iter, &tmp); - bson_copy_to (&tmp, &extra); - } else { - bson_init (&extra); - } - - if (test_framework_getenv_bool ("MONGOC_TEST_MONGOCRYPTD_BYPASS_SPAWN") && - !bson_iter_init_find (&iter, &extra, "mongocryptdBypassSpawn")) { - /* forking is disallowed in test runner, bypass spawning mongocryptd and - * assume it is running in the background. */ - BSON_APPEND_BOOL (&extra, "mongocryptdBypassSpawn", true); - } - - mongoc_auto_encryption_opts_set_extra (auto_encryption_opts, &extra); - bson_destroy (&extra); - - ret = mongoc_client_enable_auto_encryption ( - client, auto_encryption_opts, &error); - ASSERT_OR_PRINT (ret, error); - mongoc_auto_encryption_opts_destroy (auto_encryption_opts); -} - - -static bool -_should_skip_due_to_server_39704 (const bson_t *test) -{ - const char *desc = bson_lookup_utf8 (test, "description"); - const char *bad_tests[] = { - "only first countDocuments includes readConcern", - "only first find includes readConcern", - "only first aggregate includes readConcern", - "only first distinct includes readConcern", - "only first runCommand includes readConcern", - "transaction options inherited from defaultTransactionOptions", - "startTransaction options override defaults", - "defaultTransactionOptions override client options", - "readConcern snapshot in startTransaction options", - "withTransaction inherits transaction options from " - "defaultTransactionOptions", - "withTransaction explicit transaction options", - "withTransaction explicit transaction options override " - "defaultTransactionOptions", - "withTransaction explicit transaction options override client options"}; - int i; - - /* Only an issue for sharded clusters. */ - if (!test_framework_is_mongos ()) { - return false; - } - - for (i = 0; i < sizeof (bad_tests) / sizeof (char *); i++) { - if (0 == strcmp (desc, bad_tests[i])) { - return true; - } - } - - return false; -} - - -/* - *----------------------------------------------------------------------- - * - * run_json_general_test -- - * - * Run a JSON test scenario from the CRUD, Command Monitoring, - * Retryable Writes, Change Stream, or Transactions Spec. - * - * Call json_test_config_cleanup on @config after the last call - * to run_json_general_test. - * - *----------------------------------------------------------------------- - */ -void -run_json_general_test (const json_test_config_t *config) -{ - const bson_t *scenario = config->scenario; - bson_iter_t scenario_iter; - bson_iter_t tests_iter; - const char *db_name; - const char *collection_name; - - ASSERT (scenario); - - if (!check_scenario_version (scenario)) { - return; - } - - db_name = bson_has_field (scenario, "database_name") - ? bson_lookup_utf8 (scenario, "database_name") - : "test"; - collection_name = bson_has_field (scenario, "collection_name") - ? bson_lookup_utf8 (scenario, "collection_name") - : "test"; - - ASSERT (bson_iter_init_find (&scenario_iter, scenario, "tests")); - ASSERT (BSON_ITER_HOLDS_ARRAY (&scenario_iter)); - ASSERT (bson_iter_recurse (&scenario_iter, &tests_iter)); - - while (bson_iter_next (&tests_iter)) { - bson_t test; - char *selected_test; - const char *description; - bson_iter_t client_opts_iter; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_collection_t *collection; - uint32_t server_id; - bson_error_t error; - bool r; - bson_iter_t uri_iter; - - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&tests_iter)); - bson_iter_bson (&tests_iter, &test); - - selected_test = test_framework_getenv ("MONGOC_JSON_SUBTEST"); - description = bson_lookup_utf8 (&test, "description"); - if (selected_test && strcmp (selected_test, description) != 0) { - fprintf ( - stderr, " - %s SKIPPED by MONGOC_JSON_SUBTEST\n", description); - bson_free (selected_test); - continue; - } - - if (bson_has_field (&test, "skipReason")) { - fprintf (stderr, - " - %s SKIPPED, reason: %s\n", - description, - bson_lookup_utf8 (&test, "skipReason")); - continue; - } - - if (_should_skip_due_to_server_39704 (&test)) { - fprintf (stderr, - " - %s SKIPPED, reason: SERVER-39704 causes sharded tests to " - "fail when using readConcern: snapshot\n", - description); - continue; - } - - bson_free (selected_test); - - uri = test_framework_get_uri (); - - /* If we are using multiple mongos, hardcode them in, for now, but keep - * the other URI components (CDRIVER-3285) */ - if (bson_iter_init_find (&uri_iter, &test, "useMultipleMongoses") && - bson_iter_as_bool (&uri_iter)) { - ASSERT_OR_PRINT ( - mongoc_uri_upsert_host_and_port (uri, "localhost:27017", &error), - error); - ASSERT_OR_PRINT ( - mongoc_uri_upsert_host_and_port (uri, "localhost:27018", &error), - error); - } - - if (bson_iter_init_find (&client_opts_iter, &test, "clientOptions")) { - bson_t client_opts; - - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&tests_iter)); - bson_iter_bson (&client_opts_iter, &client_opts); - set_uri_opts_from_bson (uri, &client_opts); - } - - client = mongoc_client_new_from_uri (uri); - mongoc_client_set_error_api (client, 2); - test_framework_set_ssl_opts (client); - /* reconnect right away, if a fail point causes a disconnect */ - client->topology->min_heartbeat_frequency_msec = 0; - mongoc_uri_destroy (uri); - - /* clean up in case a previous test aborted */ - server_id = mongoc_topology_select_server_id ( - client->topology, MONGOC_SS_WRITE, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - deactivate_fail_points (client, server_id); - r = mongoc_client_command_with_opts (client, - "admin", - tmp_bson ("{'killAllSessions': []}"), - NULL, - NULL, - NULL, - &error); - - /* expect "operation was interrupted", ignore "command not found" */ - if (!r && (error.domain != MONGOC_ERROR_SERVER || - (error.code != 11601 && error.code != 59))) { - MONGOC_WARNING ("Error in killAllSessions: %s", error.message); - } - - set_auto_encryption_opts (client, &test); - insert_data (db_name, collection_name, scenario); - - db = mongoc_client_get_database (client, db_name); - collection = mongoc_database_get_collection (db, collection_name); - execute_test (config, client, db, collection, &test); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (db); - mongoc_client_destroy (client); - } -} - - -/* - *----------------------------------------------------------------------- - * - * json_test_config_cleanup -- - * - * Free memory after run_json_general_test. - * - *----------------------------------------------------------------------- - */ - -void -json_test_config_cleanup (json_test_config_t *config) -{ - /* no-op */ -} - - -/* Tests on unsupported operations are automatically skipped with a message - * indicating why. */ -static bson_t * -_skip_if_unsupported (const char *test_name, bson_t *original) -{ - int i; - bool skip = false; - const char *unsupported_tests[] = { - "/retryable_reads/gridfs-downloadByName", - "/retryable_reads/gridfs-downloadByName-serverErrors", - "/retryable_reads/listCollectionObjects", - "/retryable_reads/listCollectionObjects-serverErrors", - "/retryable_reads/listDatabaseObjects", - "/retryable_reads/listDatabaseObjects-serverErrors", - "/retryable_reads/listIndexNames", - "/retryable_reads/listIndexNames-serverErrors", - "/retryable_reads/mapReduce"}; - - for (i = 0; i < sizeof (unsupported_tests) / sizeof (unsupported_tests[0]); - i++) { - if (0 == strcmp (test_name, unsupported_tests[i])) { - skip = true; - break; - } - } - - if (skip) { - /* Modify the test file to give all entries in "tests" a skipReason */ - bson_t *modified = bson_new (); - bson_t modified_tests; - bson_iter_t iter; - - bson_copy_to_excluding_noinit (original, modified, "tests", NULL); - BSON_APPEND_ARRAY_BEGIN (modified, "tests", &modified_tests); - BSON_ASSERT (bson_iter_init_find (&iter, original, "tests")); - for (bson_iter_recurse (&iter, &iter); bson_iter_next (&iter);) { - bson_t original_test; - bson_t modified_test; - - bson_iter_bson (&iter, &original_test); - BSON_APPEND_DOCUMENT_BEGIN ( - &modified_tests, bson_iter_key (&iter), &modified_test); - bson_concat (&modified_test, &original_test); - BSON_APPEND_UTF8 (&modified_test, - "skipReason", - "libmongoc does not support required operation."); - bson_append_document_end (&modified_tests, &modified_test); - } - bson_append_array_end (modified, &modified_tests); - bson_destroy (original); - return modified; - } - return original; -} - -/* - *----------------------------------------------------------------------- - * - * install_json_test_suite -- - * - * Given a path to a directory containing JSON tests, import each - * test into a BSON blob and call the provided callback for - * evaluation. - * - * It is expected that the callback will BSON_ASSERT on failure, so if - * callback returns quietly the test is considered to have passed. - * - *----------------------------------------------------------------------- - */ -void -_install_json_test_suite_with_check (TestSuite *suite, - const char *dir_path, - test_hook callback, - ...) -{ - char test_paths[MAX_NUM_TESTS][MAX_TEST_NAME_LENGTH]; - int num_tests; - int i; - bson_t *test; - char *skip_json; - char *ext; - va_list ap; - - num_tests = - collect_tests_from_dir (&test_paths[0], dir_path, 0, MAX_NUM_TESTS); - - for (i = 0; i < num_tests; i++) { - test = get_bson_from_json_file (test_paths[i]); - skip_json = COALESCE (strstr (test_paths[i], "/json"), - strstr (test_paths[i], "\\json")); - BSON_ASSERT (skip_json); - skip_json += strlen ("/json"); - ext = strstr (skip_json, ".json"); - BSON_ASSERT (ext); - ext[0] = '\0'; - - test = _skip_if_unsupported (skip_json, test); - /* list of "check" functions that decide whether to skip the test */ - va_start (ap, callback); - _V_TestSuite_AddFull (suite, - skip_json, - (void (*) (void *)) callback, - (void (*) (void *)) bson_destroy, - test, - ap); - - va_end (ap); - } -} - - -/* - *----------------------------------------------------------------------- - * - * install_json_test_suite -- - * - * Given a path to a directory containing JSON tests, import each - * test into a BSON blob and call the provided callback for - * evaluation. - * - * It is expected that the callback will BSON_ASSERT on failure, so if - * callback returns quietly the test is considered to have passed. - * - *----------------------------------------------------------------------- - */ -void -install_json_test_suite (TestSuite *suite, - const char *dir_path, - test_hook callback) -{ - install_json_test_suite_with_check ( - suite, dir_path, callback, TestSuite_CheckLive); -} diff --git a/lib/mongoc/libmongoc/tests/json-test.h b/lib/mongoc/libmongoc/tests/json-test.h deleted file mode 100644 index f05a545d80ed808c1988fe7ba9e2405902a06a3c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json-test.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2015-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 JSON_TEST_H -#define JSON_TEST_H - -#include "TestSuite.h" - -#include <bson/bson.h> -#include <mongoc/mongoc.h> - -#include "test-conveniences.h" -#include "json-test-monitoring.h" -#include "json-test-operations.h" - -#define MAX_NUM_TESTS 100 - -typedef void (*test_hook) (bson_t *test); - -typedef struct _json_test_config_t { - void *ctx; - const bson_t *scenario; - json_test_cb_t before_test_cb, after_test_cb; - json_test_operation_cb_t run_operation_cb; - json_test_events_check_cb_t events_check_cb; - bool command_started_events_only; - bool command_monitoring_allow_subset; -} json_test_config_t; - -#define JSON_TEST_CONFIG_INIT \ - { \ - NULL, NULL, NULL, NULL, false \ - } - -bson_t * -get_bson_from_json_file (char *filename); - -int -collect_tests_from_dir (char (*paths)[MAX_TEST_NAME_LENGTH] /* OUT */, - const char *dir_path, - int paths_index, - int max_paths); - -void -assemble_path (const char *parent_path, - const char *child_name, - char *dst /* OUT */); - -mongoc_topology_description_type_t -topology_type_from_test (const char *type); - -mongoc_server_description_t * -server_description_by_hostname (mongoc_topology_description_t *topology, - const char *address); - -void -process_sdam_test_ismaster_responses (bson_t *phase, - mongoc_topology_description_t *td); - -void -test_server_selection_logic_cb (bson_t *test); - -mongoc_server_description_type_t -server_type_from_test (const char *type); - -void -activate_fail_point (mongoc_client_t *client, - const uint32_t server_id, - const bson_t *test, - const char *key); - -void -deactivate_fail_points (mongoc_client_t *client, uint32_t server_id); - -void -run_json_general_test (const json_test_config_t *config); - -void -json_test_config_cleanup (json_test_config_t *config); - -void -_install_json_test_suite_with_check (TestSuite *suite, - const char *dir_path, - test_hook callback, - ...); - -void -install_json_test_suite (TestSuite *suite, - const char *dir_path, - test_hook callback); - -#define install_json_test_suite_with_check(_suite, _dir_path, ...) \ - _install_json_test_suite_with_check (_suite, _dir_path, __VA_ARGS__, NULL) - -#endif diff --git a/lib/mongoc/libmongoc/tests/json/auth/connection-string.json b/lib/mongoc/libmongoc/tests/json/auth/connection-string.json deleted file mode 100644 index 83637733fd46dc8b095db945a252fc24b06c7429..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/auth/connection-string.json +++ /dev/null @@ -1,371 +0,0 @@ -{ - "tests": [ - { - "description": "should use the default source and mechanism", - "uri": "mongodb://user:password@localhost", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "admin", - "mechanism": null, - "mechanism_properties": null - } - }, - { - "description": "should use the database when no authSource is specified", - "uri": "mongodb://user:password@localhost/foo", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "foo", - "mechanism": null, - "mechanism_properties": null - } - }, - { - "description": "should use the authSource when specified", - "uri": "mongodb://user:password@localhost/foo?authSource=bar", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "bar", - "mechanism": null, - "mechanism_properties": null - } - }, - { - "description": "should recognise the mechanism (GSSAPI)", - "uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI", - "valid": true, - "credential": { - "username": "user@DOMAIN.COM", - "password": null, - "source": "$external", - "mechanism": "GSSAPI", - "mechanism_properties": { - "SERVICE_NAME": "mongodb" - } - } - }, - { - "description": "should ignore the database (GSSAPI)", - "uri": "mongodb://user%40DOMAIN.COM@localhost/foo?authMechanism=GSSAPI", - "valid": true, - "credential": { - "username": "user@DOMAIN.COM", - "password": null, - "source": "$external", - "mechanism": "GSSAPI", - "mechanism_properties": { - "SERVICE_NAME": "mongodb" - } - } - }, - { - "description": "should accept valid authSource (GSSAPI)", - "uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authSource=$external", - "valid": true, - "credential": { - "username": "user@DOMAIN.COM", - "password": null, - "source": "$external", - "mechanism": "GSSAPI", - "mechanism_properties": { - "SERVICE_NAME": "mongodb" - } - } - }, - { - "description": "should accept generic mechanism property (GSSAPI)", - "uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true", - "valid": true, - "credential": { - "username": "user@DOMAIN.COM", - "password": null, - "source": "$external", - "mechanism": "GSSAPI", - "mechanism_properties": { - "SERVICE_NAME": "other", - "CANONICALIZE_HOST_NAME": true - } - } - }, - { - "description": "should accept the password (GSSAPI)", - "uri": "mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI&authSource=$external", - "valid": true, - "credential": { - "username": "user@DOMAIN.COM", - "password": "password", - "source": "$external", - "mechanism": "GSSAPI", - "mechanism_properties": { - "SERVICE_NAME": "mongodb" - } - } - }, - { - "description": "should throw an exception if authSource is invalid (GSSAPI)", - "uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authSource=foo", - "valid": false - }, - { - "description": "should throw an exception if no username (GSSAPI)", - "uri": "mongodb://localhost/?authMechanism=GSSAPI", - "valid": false - }, - { - "description": "should recognize the mechanism (MONGODB-CR)", - "uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-CR", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "admin", - "mechanism": "MONGODB-CR", - "mechanism_properties": null - } - }, - { - "description": "should use the database when no authSource is specified (MONGODB-CR)", - "uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "foo", - "mechanism": "MONGODB-CR", - "mechanism_properties": null - } - }, - { - "description": "should use the authSource when specified (MONGODB-CR)", - "uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR&authSource=bar", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "bar", - "mechanism": "MONGODB-CR", - "mechanism_properties": null - } - }, - { - "description": "should throw an exception if no username is supplied (MONGODB-CR)", - "uri": "mongodb://localhost/?authMechanism=MONGODB-CR", - "valid": false - }, - { - "description": "should recognize the mechanism (MONGODB-X509)", - "uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509", - "valid": true, - "credential": { - "username": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry", - "password": null, - "source": "$external", - "mechanism": "MONGODB-X509", - "mechanism_properties": null - } - }, - { - "description": "should ignore the database (MONGODB-X509)", - "uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/foo?authMechanism=MONGODB-X509", - "valid": true, - "credential": { - "username": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry", - "password": null, - "source": "$external", - "mechanism": "MONGODB-X509", - "mechanism_properties": null - } - }, - { - "description": "should accept valid authSource (MONGODB-X509)", - "uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509&authSource=$external", - "valid": true, - "credential": { - "username": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry", - "password": null, - "source": "$external", - "mechanism": "MONGODB-X509", - "mechanism_properties": null - } - }, - { - "description": "should recognize the mechanism with no username (MONGODB-X509)", - "uri": "mongodb://localhost/?authMechanism=MONGODB-X509", - "valid": true, - "credential": { - "username": null, - "password": null, - "source": "$external", - "mechanism": "MONGODB-X509", - "mechanism_properties": null - } - }, - { - "description": "should throw an exception if supplied a password (MONGODB-X509)", - "uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-X509", - "valid": false - }, - { - "description": "should throw an exception if authSource is invalid (MONGODB-X509)", - "uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/foo?authMechanism=MONGODB-X509&authSource=bar", - "valid": false - }, - { - "description": "should recognize the mechanism (PLAIN)", - "uri": "mongodb://user:password@localhost/?authMechanism=PLAIN", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "$external", - "mechanism": "PLAIN", - "mechanism_properties": null - } - }, - { - "description": "should use the database when no authSource is specified (PLAIN)", - "uri": "mongodb://user:password@localhost/foo?authMechanism=PLAIN", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "foo", - "mechanism": "PLAIN", - "mechanism_properties": null - } - }, - { - "description": "should use the authSource when specified (PLAIN)", - "uri": "mongodb://user:password@localhost/foo?authMechanism=PLAIN&authSource=bar", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "bar", - "mechanism": "PLAIN", - "mechanism_properties": null - } - }, - { - "description": "should throw an exception if no username (PLAIN)", - "uri": "mongodb://localhost/?authMechanism=PLAIN", - "valid": false - }, - { - "description": "should recognize the mechanism (SCRAM-SHA-1)", - "uri": "mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-1", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "admin", - "mechanism": "SCRAM-SHA-1", - "mechanism_properties": null - } - }, - { - "description": "should use the database when no authSource is specified (SCRAM-SHA-1)", - "uri": "mongodb://user:password@localhost/foo?authMechanism=SCRAM-SHA-1", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "foo", - "mechanism": "SCRAM-SHA-1", - "mechanism_properties": null - } - }, - { - "description": "should accept valid authSource (SCRAM-SHA-1)", - "uri": "mongodb://user:password@localhost/foo?authMechanism=SCRAM-SHA-1&authSource=bar", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "bar", - "mechanism": "SCRAM-SHA-1", - "mechanism_properties": null - } - }, - { - "description": "should throw an exception if no username (SCRAM-SHA-1)", - "uri": "mongodb://localhost/?authMechanism=SCRAM-SHA-1", - "valid": false - }, - { - "description": "should recognize the mechanism (SCRAM-SHA-256)", - "uri": "mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "admin", - "mechanism": "SCRAM-SHA-256", - "mechanism_properties": null - } - }, - { - "description": "should use the database when no authSource is specified (SCRAM-SHA-256)", - "uri": "mongodb://user:password@localhost/foo?authMechanism=SCRAM-SHA-256", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "foo", - "mechanism": "SCRAM-SHA-256", - "mechanism_properties": null - } - }, - { - "description": "should accept valid authSource (SCRAM-SHA-256)", - "uri": "mongodb://user:password@localhost/foo?authMechanism=SCRAM-SHA-256&authSource=bar", - "valid": true, - "credential": { - "username": "user", - "password": "password", - "source": "bar", - "mechanism": "SCRAM-SHA-256", - "mechanism_properties": null - } - }, - { - "description": "should throw an exception if no username (SCRAM-SHA-256)", - "uri": "mongodb://localhost/?authMechanism=SCRAM-SHA-256", - "valid": false - }, - { - "description": "URI with no auth-related info doesn't create credential", - "uri": "mongodb://localhost/", - "valid": true, - "credential": null - }, - { - "description": "database in URI path doesn't create credentials", - "uri": "mongodb://localhost/foo", - "valid": true, - "credential": null - }, - { - "description": "authSource without username is invalid (default mechanism)", - "uri": "mongodb://localhost/?authSource=foo", - "valid": false - }, - { - "description": "should throw an exception if no username provided (userinfo implies default mechanism)", - "uri": "mongodb://@localhost.com/", - "valid": false - }, - { - "description": "should throw an exception if no username/password provided (userinfo implies default mechanism)", - "uri": "mongodb://:@localhost.com/", - "valid": false - } - ] -} - diff --git a/lib/mongoc/libmongoc/tests/json/change_streams/change-streams-errors.json b/lib/mongoc/libmongoc/tests/json/change_streams/change-streams-errors.json deleted file mode 100644 index 00f51eb47ec78471e1b0abd5fe5ace2acd85d625..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/change_streams/change-streams-errors.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "collection_name": "test", - "database_name": "change-stream-tests", - "collection2_name": "test2", - "database2_name": "change-stream-tests-2", - "tests": [ - { - "description": "The watch helper must not throw a custom exception when executed against a single server topology, but instead depend on a server error", - "minServerVersion": "3.6.0", - "target": "collection", - "topology": [ - "single" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [], - "expectations": [], - "result": { - "error": { - "code": 40573 - } - } - }, - { - "description": "Change Stream should error when an invalid aggregation stage is passed in", - "minServerVersion": "3.6.0", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [ - { - "$unsupported": "foo" - } - ], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "z": 3 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - }, - { - "$unsupported": "foo" - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "error": { - "code": 40324 - } - } - }, - { - "description": "Change Stream should error when _id is projected out", - "minServerVersion": "4.1.11", - "target": "collection", - "topology": [ - "replicaset", - "sharded" - ], - "changeStreamPipeline": [ - { - "$project": { - "_id": 0 - } - } - ], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "z": 3 - } - } - } - ], - "result": { - "error": { - "code": 280, - "errorLabels": [ - "NonResumableChangeStreamError" - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/change_streams/change-streams.json b/lib/mongoc/libmongoc/tests/json/change_streams/change-streams.json deleted file mode 100644 index 34371ced099aac83768d26d70b34766efc5385fe..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/change_streams/change-streams.json +++ /dev/null @@ -1,812 +0,0 @@ -{ - "collection_name": "test", - "database_name": "change-stream-tests", - "collection2_name": "test2", - "database2_name": "change-stream-tests-2", - "tests": [ - { - "description": "$changeStream must be the first stage in a change stream pipeline sent to the server", - "minServerVersion": "3.6.0", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "x": 1 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default" - } - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "success": [ - { - "_id": "42", - "documentKey": "42", - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "x": { - "$numberInt": "1" - } - } - } - ] - } - }, - { - "description": "The server returns change stream responses in the specified server response format", - "minServerVersion": "3.6.0", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "x": 1 - } - } - } - ], - "expectations": [], - "result": { - "success": [ - { - "_id": "42", - "documentKey": "42", - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "x": { - "$numberInt": "1" - } - } - } - ] - } - }, - { - "description": "Executing a watch helper on a Collection results in notifications for changes to the specified collection", - "minServerVersion": "3.6.0", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test2", - "name": "insertOne", - "arguments": { - "document": { - "x": 1 - } - } - }, - { - "database": "change-stream-tests-2", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "y": 2 - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "z": 3 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default" - } - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "success": [ - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "z": { - "$numberInt": "3" - } - } - } - ] - } - }, - { - "description": "Change Stream should allow valid aggregate pipeline stages", - "minServerVersion": "3.6.0", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [ - { - "$match": { - "fullDocument.z": 3 - } - } - ], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "y": 2 - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "z": 3 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default" - } - }, - { - "$match": { - "fullDocument.z": { - "$numberInt": "3" - } - } - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "success": [ - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "z": { - "$numberInt": "3" - } - } - } - ] - } - }, - { - "description": "Executing a watch helper on a Database results in notifications for changes to all collections in the specified database.", - "minServerVersion": "3.8.0", - "target": "database", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test2", - "name": "insertOne", - "arguments": { - "document": { - "x": 1 - } - } - }, - { - "database": "change-stream-tests-2", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "y": 2 - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "z": 3 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": { - "$numberInt": "1" - }, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default" - } - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "success": [ - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test2" - }, - "fullDocument": { - "x": { - "$numberInt": "1" - } - } - }, - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "z": { - "$numberInt": "3" - } - } - } - ] - } - }, - { - "description": "Executing a watch helper on a MongoClient results in notifications for changes to all collections in all databases in the cluster.", - "minServerVersion": "3.8.0", - "target": "client", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test2", - "name": "insertOne", - "arguments": { - "document": { - "x": 1 - } - } - }, - { - "database": "change-stream-tests-2", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "y": 2 - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "z": 3 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": { - "$numberInt": "1" - }, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default", - "allChangesForCluster": true - } - } - ] - }, - "command_name": "aggregate", - "database_name": "admin" - } - } - ], - "result": { - "success": [ - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test2" - }, - "fullDocument": { - "x": { - "$numberInt": "1" - } - } - }, - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests-2", - "coll": "test" - }, - "fullDocument": { - "y": { - "$numberInt": "2" - } - } - }, - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "z": { - "$numberInt": "3" - } - } - } - ] - } - }, - { - "description": "Test insert, update, replace, and delete event types", - "minServerVersion": "3.6.0", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "x": 1 - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "updateOne", - "arguments": { - "filter": { - "x": 1 - }, - "update": { - "$set": { - "x": 2 - } - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "replaceOne", - "arguments": { - "filter": { - "x": 2 - }, - "replacement": { - "x": 3 - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "deleteOne", - "arguments": { - "filter": { - "x": 3 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default" - } - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "success": [ - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "x": { - "$numberInt": "1" - } - } - }, - { - "operationType": "update", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "updateDescription": { - "updatedFields": { - "x": { - "$numberInt": "2" - } - } - } - }, - { - "operationType": "replace", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "x": { - "$numberInt": "3" - } - } - }, - { - "operationType": "delete", - "ns": { - "db": "change-stream-tests", - "coll": "test" - } - } - ] - } - }, - { - "description": "Test rename and invalidate event types", - "minServerVersion": "4.0.1", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "rename", - "arguments": { - "to": "test2" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default" - } - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "success": [ - { - "operationType": "rename", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "to": { - "db": "change-stream-tests", - "coll": "test2" - } - }, - { - "operationType": "invalidate" - } - ] - } - }, - { - "description": "Test drop and invalidate event types", - "minServerVersion": "4.0.1", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": {}, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "drop" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default" - } - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "success": [ - { - "operationType": "drop", - "ns": { - "db": "change-stream-tests", - "coll": "test" - } - }, - { - "operationType": "invalidate" - } - ] - } - }, - { - "description": "Test consecutive resume", - "minServerVersion": "4.1.7", - "target": "collection", - "topology": [ - "replicaset" - ], - "changeStreamPipeline": [], - "changeStreamOptions": { - "batchSize": 1 - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "getMore" - ], - "closeConnection": true - } - }, - "operations": [ - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "x": 1 - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "x": 2 - } - } - }, - { - "database": "change-stream-tests", - "collection": "test", - "name": "insertOne", - "arguments": { - "document": { - "x": 3 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "cursor": { - "batchSize": 1 - }, - "pipeline": [ - { - "$changeStream": { - "fullDocument": "default" - } - } - ] - }, - "command_name": "aggregate", - "database_name": "change-stream-tests" - } - } - ], - "result": { - "success": [ - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "x": { - "$numberInt": "1" - } - } - }, - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "x": { - "$numberInt": "2" - } - } - }, - { - "operationType": "insert", - "ns": { - "db": "change-stream-tests", - "coll": "test" - }, - "fullDocument": { - "x": { - "$numberInt": "3" - } - } - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/aggregate.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/aggregate.json deleted file mode 100644 index d0c763e1e4c8658521b9ae4aec6c531e27bb5ce6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/aggregate.json +++ /dev/null @@ -1,408 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Aggregate with deterministic encryption", - "skipReason": "SERVER-39395", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$match": { - "encrypted_string": "457-55-5642" - } - } - ] - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "default", - "pipeline": [ - { - "$match": { - "encrypted_string": "457-55-5642" - } - } - ] - }, - "command_name": "aggregate" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "Aggregate with empty pipeline", - "skipReason": "SERVER-40829 hides agg support behind enableTestCommands flag.", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "aggregate", - "arguments": { - "pipeline": [] - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "default", - "pipeline": [], - "cursor": {} - }, - "command_name": "aggregate" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "Aggregate should fail with random encryption", - "skipReason": "SERVER-39395", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$match": { - "random": "abc" - } - } - ] - }, - "result": { - "errorContains": "Cannot query on fields encrypted with the randomized encryption" - } - } - ] - }, - { - "description": "Database aggregate should fail", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "aggregate", - "object": "database", - "arguments": { - "pipeline": [ - { - "$currentOp": { - "allUsers": false, - "idleConnections": false, - "localOps": true - } - }, - { - "$match": { - "command.aggregate": { - "$eq": 1 - } - } - }, - { - "$project": { - "command": 1 - } - }, - { - "$project": { - "command.lsid": 0 - } - } - ] - }, - "result": { - "errorContains": "non-collection command not supported for auto encryption: aggregate" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/badSchema.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/badSchema.json deleted file mode 100644 index 1fd0f8ed3f991bc67b28fff2009ec200d6effe6e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/badSchema.json +++ /dev/null @@ -1,254 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Schema with an encrypted field in an array", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - } - }, - "bsonType": "array" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0" - } - }, - "result": { - "errorContains": "Invalid schema" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "Schema without specifying parent object types", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "foo": { - "properties": { - "bar": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - } - } - } - } - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0" - } - }, - "result": { - "errorContains": "Invalid schema" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "Schema with siblings of encrypt document", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - }, - "bsonType": "object" - } - } - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0" - } - }, - "result": { - "errorContains": "'encrypt' cannot be used in conjunction with 'bsonType'" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "Schema with logical keywords", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "anyOf": [ - { - "properties": { - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - } - } - } - ] - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0" - } - }, - "result": { - "errorContains": "Invalid schema" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/basic.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/basic.json deleted file mode 100644 index 6d8fb610855fdcb35fbb82f92f6154ab22052880..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/basic.json +++ /dev/null @@ -1,368 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Insert with deterministic encryption, then find it", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0" - } - } - }, - { - "name": "find", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "Insert with randomized encryption, then find it", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "random": "123" - } - } - }, - { - "name": "find", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1, - "random": "123" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "random": { - "$$type": "binData" - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "random": { - "$$type": "binData" - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/bulk.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/bulk.json deleted file mode 100644 index e8e986257eb08e5c6118759a8f6fb393815a18bd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/bulk.json +++ /dev/null @@ -1,336 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Bulk write with encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0", - "random": "abc" - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "encrypted_string": "string1" - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "encrypted_string": "string0" - }, - "update": { - "$set": { - "encrypted_string": "string1" - } - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "encrypted_string": "string1", - "_id": 2 - } - } - } - ], - "options": { - "ordered": true - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "update": "default", - "updates": [ - { - "q": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - }, - "u": { - "$set": { - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - } - } - ], - "ordered": true - }, - "command_name": "update" - } - }, - { - "command_started_event": { - "command": { - "delete": "default", - "deletes": [ - { - "q": { - "$and": [ - { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - }, - { - "_id": { - "$eq": 2 - } - } - ] - }, - "limit": 1 - } - ], - "ordered": true - }, - "command_name": "delete" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/bypassAutoEncryption.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/bypassAutoEncryption.json deleted file mode 100644 index 97a61651a43f4cc252e23082c5ccf08d46170f48..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/bypassAutoEncryption.json +++ /dev/null @@ -1,396 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Insert with bypassAutoEncryption", - "clientOptions": { - "autoEncryptOpts": { - "bypassAutoEncryption": true, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "encrypted_string": "string0" - }, - "bypassDocumentValidation": true - } - }, - { - "name": "find", - "arguments": { - "filter": {} - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - }, - { - "_id": 2, - "encrypted_string": "string0" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 2, - "encrypted_string": "string0" - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": {} - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": "string0" - } - ] - } - } - }, - { - "description": "Insert with bypassAutoEncryption for local schema", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "bypassAutoEncryption": true, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "encrypted_string": "string0" - }, - "bypassDocumentValidation": true - } - }, - { - "name": "find", - "arguments": { - "filter": {} - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - }, - { - "_id": 2, - "encrypted_string": "string0" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 2, - "encrypted_string": "string0" - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": {} - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": "string0" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/bypassedCommand.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/bypassedCommand.json deleted file mode 100644 index bd0b1c565d7db25829c7378433bdf17f2b9aa260..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/bypassedCommand.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": {}, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "ping is bypassed", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "runCommand", - "object": "database", - "command_name": "ping", - "arguments": { - "command": { - "ping": 1 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "ping": 1 - }, - "command_name": "ping" - } - } - ] - }, - { - "description": "current op is not bypassed", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "runCommand", - "object": "database", - "command_name": "currentOp", - "arguments": { - "command": { - "currentOp": 1 - } - }, - "result": { - "errorContains": "command not supported for auto encryption: currentOp" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/count.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/count.json deleted file mode 100644 index 6fc3ff339308fd2355e5bfe5bb032ee802d0c979..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/count.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Count with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "count", - "arguments": { - "filter": { - "encrypted_string": "string0" - } - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "count": "default", - "query": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - } - }, - "command_name": "count" - } - } - ] - }, - { - "description": "Count fails when filtering on a random encrypted field", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "count", - "arguments": { - "filter": { - "random": "abc" - } - }, - "result": { - "errorContains": "Cannot query on fields encrypted with the randomized encryption" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/countDocuments.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/countDocuments.json deleted file mode 100644 index 1cf0e590eb9c5f6a3dac101ee90efd06365fea28..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/countDocuments.json +++ /dev/null @@ -1,250 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "countDocuments with deterministic encryption", - "skipReason": "waiting on SERVER-39395", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "countDocuments", - "arguments": { - "filter": { - "encrypted_string": "string0" - } - }, - "result": 1 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "default", - "pipeline": [ - { - "$match": { - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "command_name": "aggregate" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/delete.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/delete.json deleted file mode 100644 index 357274195f6d0f4dc763a03dae02e708190a199b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/delete.json +++ /dev/null @@ -1,358 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "deleteOne with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "deleteOne", - "arguments": { - "filter": { - "encrypted_string": "string0" - } - }, - "result": { - "deletedCount": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "delete": "default", - "deletes": [ - { - "q": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - }, - "limit": 1 - } - ], - "ordered": true - }, - "command_name": "delete" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "deleteMany with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "deleteMany", - "arguments": { - "filter": { - "encrypted_string": { - "$in": [ - "string0", - "string1" - ] - } - } - }, - "result": { - "deletedCount": 2 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "delete": "default", - "deletes": [ - { - "q": { - "encrypted_string": { - "$in": [ - { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - }, - { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - ] - } - }, - "limit": 0 - } - ], - "ordered": true - }, - "command_name": "delete" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/distinct.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/distinct.json deleted file mode 100644 index b6dfeefc5b2f25f7a2d0f8332c26aaccd6cf44ba..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/distinct.json +++ /dev/null @@ -1,285 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 3, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "distinct with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "distinct", - "arguments": { - "filter": { - "encrypted_string": "string0" - }, - "fieldName": "encrypted_string" - }, - "result": [ - "string0" - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "distinct": "default", - "key": "encrypted_string", - "query": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - } - }, - "command_name": "distinct" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 3, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "Distinct fails when filtering on a random encrypted field", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "distinct", - "arguments": { - "filter": { - "random": "abc" - }, - "fieldName": "encrypted_string" - }, - "result": { - "errorContains": "Cannot query on fields encrypted with the randomized encryption" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/explain.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/explain.json deleted file mode 100644 index c2ddbde63425b197d476957a05ebde8a3d473207..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/explain.json +++ /dev/null @@ -1,248 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Explain a find with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "runCommand", - "object": "database", - "command_name": "explain", - "arguments": { - "command": { - "explain": { - "find": "default", - "filter": { - "encrypted_string": "string1" - } - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "explain": { - "find": "default", - "filter": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - } - }, - "verbosity": "allPlansExecution" - }, - "command_name": "explain" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/find.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/find.json deleted file mode 100644 index 78c989b6b5da8241b8b09f576366026a788feecc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/find.json +++ /dev/null @@ -1,426 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - }, - "random": { - "$binary": { - "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Find with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "find", - "arguments": { - "filter": { - "encrypted_string": "string0" - } - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - }, - "random": { - "$binary": { - "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "Find with $in with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "find", - "arguments": { - "filter": { - "encrypted_string": { - "$in": [ - "string0", - "string1" - ] - } - } - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - }, - { - "_id": 2, - "encrypted_string": "string1", - "random": "abc" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "encrypted_string": { - "$in": [ - { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - }, - { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - ] - } - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - }, - "random": { - "$binary": { - "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "Find fails when filtering on a random encrypted field", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "find", - "arguments": { - "filter": { - "random": "abc" - } - }, - "result": { - "errorContains": "Cannot query on fields encrypted with the randomized encryption" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndDelete.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndDelete.json deleted file mode 100644 index 417e94c47808149209a333e9d2924157f5de0135..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndDelete.json +++ /dev/null @@ -1,230 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "findOneAndDelete with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "encrypted_string": "string0" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "findAndModify": "default", - "query": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - }, - "remove": true - }, - "command_name": "findAndModify" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndReplace.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndReplace.json deleted file mode 100644 index 8136a3cf63e290db29c76d2768c74a54a542abae..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndReplace.json +++ /dev/null @@ -1,236 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "findOneAndReplace with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "encrypted_string": "string0" - }, - "replacement": { - "encrypted_string": "string1" - }, - "returnDocument": "Before" - }, - "result": { - "_id": 1, - "encrypted_string": "string0" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "findAndModify": "default", - "query": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - }, - "update": { - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - }, - "command_name": "findAndModify" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndUpdate.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndUpdate.json deleted file mode 100644 index c82b0047472cec861f3c0207c031a8fe369a86d7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/findOneAndUpdate.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "findOneAndUpdate with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "encrypted_string": "string0" - }, - "update": { - "$set": { - "encrypted_string": "string1" - } - }, - "returnDocument": "Before" - }, - "result": { - "_id": 1, - "encrypted_string": "string0" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "findAndModify": "default", - "query": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - }, - "update": { - "$set": { - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - } - }, - "command_name": "findAndModify" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/getMore.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/getMore.json deleted file mode 100644 index 780eb569718cfb863d7bbd6321b237ddbee096c9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/getMore.json +++ /dev/null @@ -1,272 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - }, - { - "_id": 3, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "getMore with encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "find", - "arguments": { - "batchSize": 2, - "filter": {} - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - }, - { - "_id": 2, - "encrypted_string": "string1" - }, - { - "_id": 3, - "encrypted_string": "string2" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "batchSize": 2 - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$$type": "long" - }, - "collection": "default", - "batchSize": 2 - }, - "command_name": "getMore" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - }, - { - "_id": 3, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", - "subType": "06" - } - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/insert.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/insert.json deleted file mode 100644 index 48044c6a32370d4842370a01ceb82e8f2df74f36..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/insert.json +++ /dev/null @@ -1,362 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "insertOne with encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0", - "random": "abc" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - ] - } - } - }, - { - "description": "insertMany with encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 1, - "encrypted_string": "string0", - "random": "abc" - }, - { - "_id": 2, - "encrypted_string": "string1" - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/keyAltName.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/keyAltName.json deleted file mode 100644 index 4dc885e667be39dc52e3599b51817b1c7da07384..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/keyAltName.json +++ /dev/null @@ -1,237 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Insert with encryption using key alt name", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_w_altname": "string0", - "altname": "altname" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [] - } - }, - { - "keyAltNames": { - "$in": [ - "altname" - ] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_w_altname": { - "$$type": "binData" - }, - "altname": "altname" - } - ], - "ordered": true - }, - "command_name": "insert" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_w_altname": { - "$$type": "binData" - }, - "altname": "altname" - } - ] - } - } - }, - { - "description": "Replace with key alt name fails", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$set": { - "encrypted_w_altname": "string0" - } - }, - "upsert": true - }, - "result": { - "errorContains": "A non-static (JSONPointer) keyId is not supported" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/localKMS.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/localKMS.json deleted file mode 100644 index febc1ccfc88c35e756d8424a950cdad8ece3c692..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/localKMS.json +++ /dev/null @@ -1,203 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": { - "properties": { - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "keyMaterial": { - "$binary": { - "base64": "Ce9HSz/HKKGkIt4uyy+jDuKGA+rLC2cycykMo6vc8jXxqa1UVDYHWq1r+vZKbnnSRBfB981akzRKZCFpC05CTyFqDhXv6OnMjpG97OZEREGIsHEYiJkBW0jJJvfLLgeLsEpBzsro9FztGGXASxyxFRZFhXvHxyiLOKrdWfs7X1O/iK3pEoHMx6uSNSfUOgbebLfIqW7TO++iQS5g1xovXA==", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "status": { - "$numberInt": "0" - }, - "masterKey": { - "provider": "local" - } - } - ], - "tests": [ - { - "description": "Insert a document with auto encryption using local KMS provider", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {}, - "local": { - "key": { - "$binary": { - "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", - "subType": "00" - } - } - } - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0", - "random": "abc" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACV/+zJmpqMU47yxS/xIVAviGi7wHDuFwaULAixEAoIh0xHz73UYOM3D8D44gcJn67EROjbz4ITpYzzlCJovDL0Q==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACV/+zJmpqMU47yxS/xIVAviGi7wHDuFwaULAixEAoIh0xHz73UYOM3D8D44gcJn67EROjbz4ITpYzzlCJovDL0Q==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/localSchema.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/localSchema.json deleted file mode 100644 index a3bda4b24d8238605f1264c2f13bf5fdec905e48..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/localSchema.json +++ /dev/null @@ -1,267 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": {}, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "A local schema should override", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0" - } - } - }, - { - "name": "find", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1, - "encrypted_string": "string0" - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "A local schema with no encryption is an error", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "test": { - "bsonType": "string" - } - }, - "bsonType": "object", - "required": [ - "test" - ] - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0" - } - }, - "result": { - "errorContains": "JSON schema keyword 'required' is only allowed with a remote schema" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/malformedCiphertext.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/malformedCiphertext.json deleted file mode 100644 index c81330ce83338150cf4c96725e5430fc68e7334e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/malformedCiphertext.json +++ /dev/null @@ -1,321 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "00" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQ==", - "subType": "06" - } - } - }, - { - "_id": 3, - "encrypted_string": { - "$binary": { - "base64": "AQAAa2V2aW4gYWxiZXJ0c29uCg==", - "subType": "06" - } - } - } - ], - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Wrong subtype", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "find", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "00" - } - } - } - ] - } - ] - }, - { - "description": "Empty data", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "find", - "arguments": { - "filter": { - "_id": 2 - } - }, - "result": { - "errorContains": "malformed ciphertext" - } - } - ] - }, - { - "description": "Malformed data", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "find", - "arguments": { - "filter": { - "_id": 3 - } - }, - "result": { - "errorContains": "not all keys requested were satisfied" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/maxWireVersion.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/maxWireVersion.json deleted file mode 100644 index 144786290dcd94e91bd3c3150e7b12ba585ffe22..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/maxWireVersion.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "runOn": [ - { - "maxServerVersion": "4.0" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "operation fails with maxWireVersion < 8", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "encrypted_string": "string0" - } - }, - "result": { - "errorContains": "Auto-encryption requires a minimum MongoDB version of 4.2" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/missingKey.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/missingKey.json deleted file mode 100644 index d1dc9d313b7683ed2189e52be8188401f9d36530..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/missingKey.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "Insert with encryption on a missing key", - "clientOptions": { - "autoEncryptOpts": { - "keyVaultNamespace": "admin.different", - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_string": "string0", - "random": "abc" - } - }, - "result": { - "errorContains": "not all keys requested were satisfied" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "different" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "different", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/replaceOne.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/replaceOne.json deleted file mode 100644 index 2be1ff2853a59f62f4af691ec3f981110c108712..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/replaceOne.json +++ /dev/null @@ -1,248 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "replaceOne with encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "replaceOne", - "arguments": { - "filter": { - "encrypted_string": "string0" - }, - "replacement": { - "encrypted_string": "string1", - "random": "abc" - } - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "update": "default", - "updates": [ - { - "q": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - }, - "u": { - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - } - ], - "ordered": true - }, - "command_name": "update" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/types.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/types.json deleted file mode 100644 index fcab407785029be1bed296565a847293f2eb5dc9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/types.json +++ /dev/null @@ -1,1718 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [], - "json_schema": {}, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "type=objectId", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_objectId": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "objectId", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_objectId": { - "$oid": "AAAAAAAAAAAAAAAAAAAAAAAA" - } - } - } - }, - { - "name": "findOne", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "encrypted_objectId": { - "$oid": "AAAAAAAAAAAAAAAAAAAAAAAA" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_objectId": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAHmkTPqvzfHMWpvS1mEsrjOxVQ2dyihEgIFWD5E0eNEsiMBQsC0GuvjdqYRL5DHLFI1vKuGek7EYYp0Qyii/tHqA==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_objectId": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAHmkTPqvzfHMWpvS1mEsrjOxVQ2dyihEgIFWD5E0eNEsiMBQsC0GuvjdqYRL5DHLFI1vKuGek7EYYp0Qyii/tHqA==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "type=symbol", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_symbol": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "symbol", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_symbol": { - "$symbol": "test" - } - } - } - }, - { - "name": "findOne", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "encrypted_symbol": { - "$symbol": "test" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_symbol": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAOOmvDmWjcuKsSCO7U/7t9HJ8eI73B6wduyMbdkvn7n7V4uTJes/j+BTtneSdyG2JHKHGkevWAJSIU2XoO66BSXw==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_symbol": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAOOmvDmWjcuKsSCO7U/7t9HJ8eI73B6wduyMbdkvn7n7V4uTJes/j+BTtneSdyG2JHKHGkevWAJSIU2XoO66BSXw==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "type=int", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_int": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "int", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_int": { - "$numberInt": "123" - } - } - } - }, - { - "name": "findOne", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "encrypted_int": { - "$numberInt": "123" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_int": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAQPNXJVXMEjGZnftMuf2INKufXCtQIRHdw5wTgn6QYt3ejcoAXyiwI4XIUizkpsob494qpt2in4tWeiO7b9zkA8Q==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_int": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAQPNXJVXMEjGZnftMuf2INKufXCtQIRHdw5wTgn6QYt3ejcoAXyiwI4XIUizkpsob494qpt2in4tWeiO7b9zkA8Q==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "type=double", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_double": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "double", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_double": { - "$numberDouble": "1.23" - } - } - }, - "result": { - "errorContains": "Cannot use deterministic encryption for element of type: double" - } - } - ] - }, - { - "description": "type=decimal", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_decimal": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "decimal", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_decimal": { - "$numberDecimal": "1.23" - } - } - }, - "result": { - "errorContains": "Cannot use deterministic encryption for element of type: decimal" - } - } - ] - }, - { - "description": "type=binData", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_binData": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "binData", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_binData": { - "$binary": { - "base64": "AAAA", - "subType": "00" - } - } - } - } - }, - { - "name": "findOne", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "encrypted_binData": { - "$binary": { - "base64": "AAAA", - "subType": "00" - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_binData": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAFB/KHZQHaHHo8fctcl7v6kR+sLkJoTRx2cPSSck9ya+nbGROSeFhdhDRHaCzhV78fDEqnMDSVPNi+ZkbaIh46GQ==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_binData": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAFB/KHZQHaHHo8fctcl7v6kR+sLkJoTRx2cPSSck9ya+nbGROSeFhdhDRHaCzhV78fDEqnMDSVPNi+ZkbaIh46GQ==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "type=javascript", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_javascript": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "javascript", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_javascript": { - "$code": "var x = 1;" - } - } - } - }, - { - "name": "findOne", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "encrypted_javascript": { - "$code": "var x = 1;" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_javascript": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAANrvMgJkTKWGMc9wt3E2RBR2Hu5gL9p+vIIdHe9FcOm99t1W480/oX1Gnd87ON3B399DuFaxi/aaIiQSo7gTX6Lw==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_javascript": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAANrvMgJkTKWGMc9wt3E2RBR2Hu5gL9p+vIIdHe9FcOm99t1W480/oX1Gnd87ON3B399DuFaxi/aaIiQSo7gTX6Lw==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "type=javascriptWithScope", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_javascriptWithScope": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "javascriptWithScope", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_javascriptWithScope": { - "$code": "var x = 1;", - "$scope": {} - } - } - }, - "result": { - "errorContains": "Cannot use deterministic encryption for element of type: javascriptWithScope" - } - } - ] - }, - { - "description": "type=object", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_object": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "object", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_object": {} - } - }, - "result": { - "errorContains": "Cannot use deterministic encryption for element of type: object" - } - } - ] - }, - { - "description": "type=timestamp", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_timestamp": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "timestamp", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_timestamp": { - "$timestamp": { - "t": 123, - "i": 456 - } - } - } - } - }, - { - "name": "findOne", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "encrypted_timestamp": { - "$timestamp": { - "t": 123, - "i": 456 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_timestamp": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAARJHaM4Gq3MpDTdBasBsEolQaOmxJQU1wsZVaSFAOLpEh1QihDglXI95xemePFMKhg+KNpFg7lw1ChCs2Wn/c26Q==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_timestamp": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAARJHaM4Gq3MpDTdBasBsEolQaOmxJQU1wsZVaSFAOLpEh1QihDglXI95xemePFMKhg+KNpFg7lw1ChCs2Wn/c26Q==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "type=regex", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_regex": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "regex", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_regex": { - "$regularExpression": { - "pattern": "test", - "options": "" - } - } - } - } - }, - { - "name": "findOne", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "encrypted_regex": { - "$regularExpression": { - "pattern": "test", - "options": "" - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_regex": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAALVnxM4UqGhqf5eXw6nsS08am3YJrTf1EvjKitT8tyyMAbHsICIU3GUjuC7EBofCHbusvgo7pDyaClGostFz44nA==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_regex": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAALVnxM4UqGhqf5eXw6nsS08am3YJrTf1EvjKitT8tyyMAbHsICIU3GUjuC7EBofCHbusvgo7pDyaClGostFz44nA==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "type=date", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_date": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "date", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_date": { - "$date": { - "$numberLong": "123" - } - } - } - } - }, - { - "name": "findOne", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "encrypted_date": { - "$date": { - "$numberLong": "123" - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "insert": "default", - "documents": [ - { - "_id": 1, - "encrypted_date": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAJ5sN7u6l97+DswfKTqZAijSTSOo5htinGKQKUD7pHNJYlLXGOkB4glrCu7ibu0g3344RHQ5yUp4YxMEa8GD+Snw==", - "subType": "06" - } - } - } - ], - "ordered": true - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "find": "default", - "filter": { - "_id": 1 - } - }, - "command_name": "find" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_date": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAAJ5sN7u6l97+DswfKTqZAijSTSOo5htinGKQKUD7pHNJYlLXGOkB4glrCu7ibu0g3344RHQ5yUp4YxMEa8GD+Snw==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "type=minKey", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_minKey": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "minKey", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_minKey": { - "$minKey": 1 - } - } - }, - "result": { - "errorContains": "Cannot encrypt element of type: minKey" - } - } - ] - }, - { - "description": "type=maxKey", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_maxKey": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "maxKey", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_maxKey": { - "$maxKey": 1 - } - } - }, - "result": { - "errorContains": "Cannot encrypt element of type: maxKey" - } - } - ] - }, - { - "description": "type=undefined", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_undefined": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "undefined", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_undefined": { - "$undefined": true - } - } - }, - "result": { - "errorContains": "Cannot encrypt element of type: undefined" - } - } - ] - }, - { - "description": "type=array", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_array": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "array", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_array": [] - } - }, - "result": { - "errorContains": "Cannot use deterministic encryption for element of type: array" - } - } - ] - }, - { - "description": "type=bool", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_bool": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "bool", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_bool": true - } - }, - "result": { - "errorContains": "Cannot use deterministic encryption for element of type: bool" - } - } - ] - }, - { - "description": "type=null", - "clientOptions": { - "autoEncryptOpts": { - "schemaMap": { - "default.default": { - "properties": { - "encrypted_null": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "null", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - } - }, - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "encrypted_null": true - } - }, - "result": { - "errorContains": "Cannot encrypt element of type: null" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/updateMany.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/updateMany.json deleted file mode 100644 index 7d01873bd18564a90e073e066879139a95393849..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/updateMany.json +++ /dev/null @@ -1,316 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "updateMany with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateMany", - "arguments": { - "filter": { - "encrypted_string": { - "$in": [ - "string0", - "string1" - ] - } - }, - "update": { - "$set": { - "encrypted_string": "string2", - "random": "abc" - } - } - }, - "result": { - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "update": "default", - "updates": [ - { - "q": { - "encrypted_string": { - "$in": [ - { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - }, - { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - } - ] - } - }, - "u": { - "$set": { - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - }, - "multi": true, - "upsert": false - } - ], - "ordered": true - }, - "command_name": "update" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - }, - { - "_id": 2, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - ] - } - } - }, - { - "description": "updateMany fails when filtering on a random field", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateMany", - "arguments": { - "filter": { - "random": "abc" - }, - "update": { - "$set": { - "encrypted_string": "string1" - } - } - }, - "result": { - "errorContains": "Cannot query on fields encrypted with the randomized encryption" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/client_side_encryption/updateOne.json b/lib/mongoc/libmongoc/tests/json/client_side_encryption/updateOne.json deleted file mode 100644 index 0429ed70ae1161b94ced4685fb776d0a53e35c35..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/client_side_encryption/updateOne.json +++ /dev/null @@ -1,474 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.10" - } - ], - "database_name": "default", - "collection_name": "default", - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ], - "json_schema": { - "properties": { - "encrypted_w_altname": { - "encrypt": { - "keyId": "/altname", - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - }, - "random": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" - } - }, - "encrypted_string_equivalent": { - "encrypt": { - "keyId": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ], - "bsonType": "string", - "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" - } - } - }, - "bsonType": "object" - }, - "key_vault_data": [ - { - "status": 1, - "_id": { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - }, - "masterKey": { - "provider": "aws", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", - "region": "us-east-1" - }, - "updateDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyMaterial": { - "$binary": { - "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1552949630483" - } - }, - "keyAltNames": [ - "altname", - "another_altname" - ] - } - ], - "tests": [ - { - "description": "updateOne with deterministic encryption", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateOne", - "arguments": { - "filter": { - "encrypted_string": "string0" - }, - "update": { - "$set": { - "encrypted_string": "string1", - "random": "abc" - } - } - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "datakeys" - }, - "$db": "admin" - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "find": "datakeys", - "filter": { - "$or": [ - { - "_id": { - "$in": [ - { - "$binary": { - "base64": "AAAAAAAAAAAAAAAAAAAAAA==", - "subType": "04" - } - } - ] - } - }, - { - "keyAltNames": { - "$in": [] - } - } - ] - }, - "$db": "admin" - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "update": "default", - "updates": [ - { - "q": { - "encrypted_string": { - "$eq": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - }, - "u": { - "$set": { - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - } - } - ], - "ordered": true - }, - "command_name": "update" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", - "subType": "06" - } - }, - "random": { - "$$type": "binData" - } - } - ] - } - } - }, - { - "description": "updateOne fails when filtering on a random field", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateOne", - "arguments": { - "filter": { - "random": "abc" - }, - "update": { - "$set": { - "encrypted_string": "string1" - } - } - }, - "result": { - "errorContains": "Cannot query on fields encrypted with the randomized encryption" - } - } - ] - }, - { - "description": "$unset works with an encrypted field", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$unset": { - "encrypted_string": "" - } - } - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "update": "default", - "updates": [ - { - "q": {}, - "u": { - "$unset": { - "encrypted_string": "" - } - } - } - ], - "ordered": true - }, - "command_name": "update" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "$rename works if target value has same encryption options", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$rename": { - "encrypted_string": "encrypted_string_equivalent" - } - } - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1, - "filter": { - "name": "default" - } - }, - "command_name": "listCollections" - } - }, - { - "command_started_event": { - "command": { - "update": "default", - "updates": [ - { - "q": {}, - "u": { - "$rename": { - "encrypted_string": "encrypted_string_equivalent" - } - } - } - ], - "ordered": true - }, - "command_name": "update" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "encrypted_string_equivalent": { - "$binary": { - "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", - "subType": "06" - } - } - } - ] - } - } - }, - { - "description": "$rename fails if target value has different encryption options", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$rename": { - "encrypted_string": "random" - } - } - }, - "result": { - "errorContains": "$rename between two encrypted fields must have the same metadata or both be unencrypted" - } - } - ] - }, - { - "description": "an invalid update (no $ operators) is validated and errors", - "clientOptions": { - "autoEncryptOpts": { - "kmsProviders": { - "aws": {} - } - } - }, - "operations": [ - { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "encrypted_string": "random" - } - }, - "result": { - "errorContains": "" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/bulkWrite.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/bulkWrite.json deleted file mode 100644 index c5cd5a239982a8c2e87ecb78e21b1ec3a7d3d3c0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/bulkWrite.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful mixed bulk write", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 4, - "x": 44 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 3 - }, - "update": { - "$set": { - "x": 333 - } - } - } - } - ] - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 4, - "x": 44 - } - ], - "ordered": true - }, - "command_name": "insert", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "insert" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 3 - }, - "u": { - "$set": { - "x": 333 - } - }, - "upsert": false, - "multi": false - } - ], - "ordered": true - }, - "command_name": "update", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "update" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/command.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/command.json deleted file mode 100644 index 7e1e347be0739cac1944a093dfd9c473390a4c44..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/command.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful command", - "operation": { - "name": "count", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "count": "test", - "query": { - "_id": 1 - } - }, - "command_name": "count", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "count" - } - } - ] - }, - { - "description": "A failed command event", - "operation": { - "name": "count", - "arguments": { - "filter": { - "$or": true - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "count": "test", - "query": { - "$or": true - } - }, - "command_name": "count", - "database_name": "command-monitoring-tests" - } - }, - { - "command_failed_event": { - "command_name": "count" - } - } - ] - }, - { - "description": "A successful command with a non-primary read preference", - "operation": { - "name": "count", - "arguments": { - "filter": { - "_id": 1 - } - }, - "read_preference": { - "mode": "primaryPreferred" - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "count": "test", - "query": { - "_id": 1 - } - }, - "command_name": "count", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "count" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/deleteMany.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/deleteMany.json deleted file mode 100644 index 7cd396806cc06a47d7f0dae0b413fcdb3deef4b1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/deleteMany.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful delete many", - "operation": { - "name": "deleteMany", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": { - "$gt": 1 - } - }, - "limit": 0 - } - ], - "ordered": true - }, - "command_name": "delete", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 2 - }, - "command_name": "delete" - } - } - ] - }, - { - "description": "A successful delete many command with write errors", - "operation": { - "name": "deleteMany", - "arguments": { - "filter": { - "_id": { - "$nothing": 1 - } - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": { - "$nothing": 1 - } - }, - "limit": 0 - } - ], - "ordered": true - }, - "command_name": "delete", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 0, - "writeErrors": [ - { - "index": 0, - "code": 42, - "errmsg": "" - } - ] - }, - "command_name": "delete" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/deleteOne.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/deleteOne.json deleted file mode 100644 index 0971dfcf2cdae5aa9ce2af951fd5224819cdaa2e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/deleteOne.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful delete one", - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": { - "$gt": 1 - } - }, - "limit": 1 - } - ], - "ordered": true - }, - "command_name": "delete", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "delete" - } - } - ] - }, - { - "description": "A successful delete one command with write errors", - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": { - "$nothing": 1 - } - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": { - "$nothing": 1 - } - }, - "limit": 1 - } - ], - "ordered": true - }, - "command_name": "delete", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 0, - "writeErrors": [ - { - "index": 0, - "code": 42, - "errmsg": "" - } - ] - }, - "command_name": "delete" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/find.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/find.json deleted file mode 100644 index 039c5fead1a27f5e056d1d353562b53828a8ed57..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/find.json +++ /dev/null @@ -1,560 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - }, - { - "_id": 5, - "x": 55 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "namespace": "command-monitoring-tests.test", - "tests": [ - { - "description": "A successful find event with no options", - "operation": { - "name": "find", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "filter": { - "_id": 1 - } - }, - "command_name": "find", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursor": { - "id": { - "$numberLong": "0" - }, - "ns": "command-monitoring-tests.test", - "firstBatch": [ - { - "_id": 1, - "x": 11 - } - ] - } - }, - "command_name": "find" - } - } - ] - }, - { - "description": "A successful find event with options", - "operation": { - "name": "find", - "read_preference": { - "mode": "primaryPreferred" - }, - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "sort": { - "_id": 1 - }, - "skip": { - "$numberLong": "2" - }, - "modifiers": { - "$comment": "test", - "$hint": { - "_id": 1 - }, - "$max": { - "_id": 6 - }, - "$maxTimeMS": 6000, - "$min": { - "_id": 0 - }, - "$returnKey": false, - "$showDiskLoc": false - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "filter": { - "_id": { - "$gt": 1 - } - }, - "sort": { - "_id": 1 - }, - "skip": { - "$numberLong": "2" - }, - "comment": "test", - "hint": { - "_id": 1 - }, - "max": { - "_id": 6 - }, - "maxTimeMS": 6000, - "min": { - "_id": 0 - }, - "returnKey": false, - "showRecordId": false - }, - "command_name": "find", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursor": { - "id": { - "$numberLong": "0" - }, - "ns": "command-monitoring-tests.test", - "firstBatch": [ - { - "_id": 4, - "x": 44 - }, - { - "_id": 5, - "x": 55 - } - ] - } - }, - "command_name": "find" - } - } - ] - }, - { - "description": "A successful find event with a getmore", - "operation": { - "name": "find", - "arguments": { - "filter": { - "_id": { - "$gte": 1 - } - }, - "sort": { - "_id": 1 - }, - "batchSize": { - "$numberLong": "3" - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "filter": { - "_id": { - "$gte": 1 - } - }, - "sort": { - "_id": 1 - }, - "batchSize": { - "$numberLong": "3" - } - }, - "command_name": "find", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursor": { - "id": { - "$numberLong": "42" - }, - "ns": "command-monitoring-tests.test", - "firstBatch": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": { - "$numberLong": "3" - } - }, - "command_name": "getMore", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursor": { - "id": { - "$numberLong": "0" - }, - "ns": "command-monitoring-tests.test", - "nextBatch": [ - { - "_id": 4, - "x": 44 - }, - { - "_id": 5, - "x": 55 - } - ] - } - }, - "command_name": "getMore" - } - } - ] - }, - { - "description": "A successful find event with a getmore and killcursors", - "ignore_if_server_version_greater_than": "3.0", - "operation": { - "name": "find", - "arguments": { - "filter": { - "_id": { - "$gte": 1 - } - }, - "sort": { - "_id": 1 - }, - "batchSize": { - "$numberLong": "3" - }, - "limit": { - "$numberLong": "4" - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "filter": { - "_id": { - "$gte": 1 - } - }, - "sort": { - "_id": 1 - }, - "batchSize": { - "$numberLong": "3" - }, - "limit": { - "$numberLong": "4" - } - }, - "command_name": "find", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursor": { - "id": { - "$numberLong": "42" - }, - "ns": "command-monitoring-tests.test", - "firstBatch": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": { - "$numberLong": "1" - } - }, - "command_name": "getMore", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursor": { - "id": { - "$numberLong": "42" - }, - "ns": "command-monitoring-tests.test", - "nextBatch": [ - { - "_id": 4, - "x": 44 - } - ] - } - }, - "command_name": "getMore" - } - }, - { - "command_started_event": { - "command": { - "killCursors": "test", - "cursors": [ - { - "$numberLong": "42" - } - ] - }, - "command_name": "killCursors", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursorsUnknown": [ - { - "$numberLong": "42" - } - ] - }, - "command_name": "killCursors" - } - } - ] - }, - { - "description": "A successful find event with a getmore and the server kills the cursor", - "ignore_if_server_version_less_than": "3.1", - "ignore_if_topology_type": [ - "sharded" - ], - "operation": { - "name": "find", - "arguments": { - "filter": { - "_id": { - "$gte": 1 - } - }, - "sort": { - "_id": 1 - }, - "batchSize": { - "$numberLong": "3" - }, - "limit": { - "$numberLong": "4" - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "filter": { - "_id": { - "$gte": 1 - } - }, - "sort": { - "_id": 1 - }, - "batchSize": { - "$numberLong": "3" - }, - "limit": { - "$numberLong": "4" - } - }, - "command_name": "find", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursor": { - "id": { - "$numberLong": "42" - }, - "ns": "command-monitoring-tests.test", - "firstBatch": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - }, - "command_name": "find" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": { - "$numberLong": "1" - } - }, - "command_name": "getMore", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "cursor": { - "id": { - "$numberLong": "0" - }, - "ns": "command-monitoring-tests.test", - "nextBatch": [ - { - "_id": 4, - "x": 44 - } - ] - } - }, - "command_name": "getMore" - } - } - ] - }, - { - "description": "A failed find event", - "operation": { - "name": "find", - "arguments": { - "filter": { - "$or": true - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "filter": { - "$or": true - } - }, - "command_name": "find", - "database_name": "command-monitoring-tests" - } - }, - { - "command_failed_event": { - "command_name": "find" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/insertMany.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/insertMany.json deleted file mode 100644 index 0becf928e4dd24649c4039c6fddb3c8c8e27513a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/insertMany.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful insert many", - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - } - ] - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2, - "x": 22 - } - ], - "ordered": true - }, - "command_name": "insert", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "insert" - } - } - ] - }, - { - "description": "A successful insert many command with write errors", - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 1, - "x": 11 - } - ] - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1, - "x": 11 - } - ], - "ordered": true - }, - "command_name": "insert", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 0, - "writeErrors": [ - { - "index": 0, - "code": 42, - "errmsg": "" - } - ] - }, - "command_name": "insert" - } - } - ] - }, - { - "description": "A successful unordered insert many", - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - } - ], - "options": { - "ordered": false - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2, - "x": 22 - } - ], - "ordered": false - }, - "command_name": "insert", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "insert" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/insertOne.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/insertOne.json deleted file mode 100644 index 877bca1a615dc15efa337699619cda4866d9f0e4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/insertOne.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful insert one", - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2, - "x": 22 - } - ], - "ordered": true - }, - "command_name": "insert", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "insert" - } - } - ] - }, - { - "description": "A successful insert one command with write errors", - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1, - "x": 11 - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1, - "x": 11 - } - ], - "ordered": true - }, - "command_name": "insert", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 0, - "writeErrors": [ - { - "index": 0, - "code": 42, - "errmsg": "" - } - ] - }, - "command_name": "insert" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/unacknowledgedBulkWrite.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/unacknowledgedBulkWrite.json deleted file mode 100644 index ae116289eba62b12853c95fd4b7b89e7817c3f37..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/unacknowledgedBulkWrite.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "collection_name": "test-unacknowledged-bulk-write", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful unordered bulk write with an unacknowledged write concern", - "comment": "On a 2.4 server, no GLE is sent and requires a client-side manufactured reply", - "operation": { - "name": "bulkWrite", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": "unorderedBulkWriteInsertW0", - "x": 44 - } - } - } - ], - "options": { - "ordered": false - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test-unacknowledged-bulk-write", - "documents": [ - { - "_id": "unorderedBulkWriteInsertW0", - "x": 44 - } - ], - "ordered": false, - "writeConcern": { - "w": 0 - } - }, - "command_name": "insert", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1 - }, - "command_name": "insert" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/updateMany.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/updateMany.json deleted file mode 100644 index 8e98fc92fdd0aaa424805a537dc25561080f03dc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/updateMany.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful update many", - "operation": { - "name": "updateMany", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "ordered": true, - "updates": [ - { - "q": { - "_id": { - "$gt": 1 - } - }, - "u": { - "$inc": { - "x": 1 - } - }, - "multi": true, - "upsert": false - } - ] - }, - "command_name": "update", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 2 - }, - "command_name": "update" - } - } - ] - }, - { - "description": "A successful update many command with write errors", - "operation": { - "name": "updateMany", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$nothing": { - "x": 1 - } - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "ordered": true, - "updates": [ - { - "q": { - "_id": { - "$gt": 1 - } - }, - "u": { - "$nothing": { - "x": 1 - } - }, - "multi": true, - "upsert": false - } - ] - }, - "command_name": "update", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 0, - "writeErrors": [ - { - "index": 0, - "code": 42, - "errmsg": "" - } - ] - }, - "command_name": "update" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/command_monitoring/updateOne.json b/lib/mongoc/libmongoc/tests/json/command_monitoring/updateOne.json deleted file mode 100644 index 565b749704ca7403b1c7de5bf361cdf26262eba0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/command_monitoring/updateOne.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "collection_name": "test", - "database_name": "command-monitoring-tests", - "tests": [ - { - "description": "A successful update one", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "ordered": true, - "updates": [ - { - "q": { - "_id": { - "$gt": 1 - } - }, - "u": { - "$inc": { - "x": 1 - } - }, - "multi": false, - "upsert": false - } - ] - }, - "command_name": "update", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1 - }, - "command_name": "update" - } - } - ] - }, - { - "description": "A successful update one with upsert when the upserted id is not an object id", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "ordered": true, - "updates": [ - { - "q": { - "_id": 4 - }, - "u": { - "$inc": { - "x": 1 - } - }, - "multi": false, - "upsert": true - } - ] - }, - "command_name": "update", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 1, - "upserted": [ - { - "index": 0, - "_id": 4 - } - ] - }, - "command_name": "update" - } - } - ] - }, - { - "description": "A successful update one command with write errors", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$nothing": { - "x": 1 - } - } - } - }, - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "ordered": true, - "updates": [ - { - "q": { - "_id": { - "$gt": 1 - } - }, - "u": { - "$nothing": { - "x": 1 - } - }, - "multi": false, - "upsert": false - } - ] - }, - "command_name": "update", - "database_name": "command-monitoring-tests" - } - }, - { - "command_succeeded_event": { - "reply": { - "ok": 1, - "n": 0, - "writeErrors": [ - { - "index": 0, - "code": 42, - "errmsg": "" - } - ] - }, - "command_name": "update" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/README.rst b/lib/mongoc/libmongoc/tests/json/connection_uri/README.rst deleted file mode 100644 index 1c63d3d491edb7e59e3237b261aab05b4090ed36..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/README.rst +++ /dev/null @@ -1,99 +0,0 @@ -======================= -Connection String Tests -======================= - -The YAML and JSON files in this directory tree are platform-independent tests -that drivers can use to prove their conformance to the Connection String Spec. - -As the spec is primarily concerned with parsing the parts of a URI, these tests -do not focus on host and option validation. Where necessary, the tests use -options known to be (un)supported by drivers to BSON_ASSERT behavior such as issuing -a warning on repeated option keys. As such these YAML tests are in no way a -replacement for more thorough testing. However, they can provide an initial -verification of your implementation. - -Converting to JSON ------------------- - -The tests are written in YAML because it is easier for humans to write and read, -and because YAML includes a standard comment format. A JSONified version of each -YAML file is included in this repository. Whenever you change the YAML, -re-convert to JSON. One method to convert to JSON is with -`jsonwidget-python <http://jsonwidget.org/wiki/Jsonwidget-python>`_:: - - pip install PyYAML urwid jsonwidget - make - -Or instead of "make":: - - for i in `find . -iname '*.yml'`; do - echo "${i%.*}" - jwc yaml2json $i > ${i%.*}.json - done - -Alternatively, you can use `yamljs <https://www.npmjs.com/package/yamljs>`_:: - - npm install -g yamljs - yaml2json -s -p -r . - -Version -------- - -Files in the "specifications" repository have no version scheme. They are not -tied to a MongoDB server version, and it is our intention that each -specification moves from "draft" to "final" with no further versions; it is -superseded by a future spec, not revised. - -However, implementers must have stable sets of tests to target. As test files -evolve they will be occasionally tagged like "uri-tests-tests-2015-07-16", until -the spec is final. - -Format ------- - -Each YAML file contains an object with a single ``tests`` key. This key is an -array of test case objects, each of which have the following keys: - -- ``description``: A string describing the test. -- ``uri``: A string containing the URI to be parsed. -- ``valid:`` A boolean indicating if the URI should be considered valid. -- ``warning:`` A boolean indicating whether URI parsing should emit a warning - (independent of whether or not the URI is valid). -- ``hosts``: An array of host objects, each of which have the following keys: - - - ``type``: A string denoting the type of host. Possible values are "ipv4", - "ip_literal", "hostname", and "unix". Asserting the type is *optional*. - - ``host``: A string containing the parsed host. - - ``port``: An integer containing the parsed port number. -- ``auth``: An object containing the following keys: - - - ``username``: A string containing the parsed username. For auth mechanisms - that do not utilize a password, this may be the entire ``userinfo`` token - (as discussed in `RFC 2396 <https://www.ietf.org/rfc/rfc2396.txt>`_). - - ``password``: A string containing the parsed password. - - ``db``: A string containing the parsed authentication database. For legacy - implementations that support namespaces (databases and collections) this may - be the full namespace eg: ``<db>.<coll>`` -- ``options``: An object containing key/value pairs for each parsed query string - option. - -If a test case includes a null value for one of these keys (e.g. ``auth: ~``, -``port: ~``), no assertion is necessary. This both simplifies parsing of the -test files (keys should always exist) and allows flexibility for drivers that -might substitute default values *during* parsing (e.g. omitted ``port`` could be -parsed as 27017). - -The ``valid`` and ``warning`` fields are boolean in order to keep the tests -flexible. We are not concerned with asserting the format of specific error or -warnings messages strings. - -Use as unit tests -================= - -Testing whether a URI is valid or not should simply be a matter of checking -whether URI parsing (or MongoClient construction) raises an error or exception. -Testing for emitted warnings may require more legwork (e.g. configuring a log -handler and watching for output). - -Not all drivers may be able to directly BSON_ASSERT the hosts, auth credentials, and -options. Doing so may require exposing the driver's URI parsing component. diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/additional-nonspec-tests.json b/lib/mongoc/libmongoc/tests/json/connection_uri/additional-nonspec-tests.json deleted file mode 100644 index 563dc535374bee8f70eab8bdb22457adddafaefd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/additional-nonspec-tests.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "tests": [ - { - "description": "Repeated authSource key", - "uri": "mongodb://example.com/?authSource=bar&authSource=foo", - "valid": false, - "comment": "invalid URI (see SPEC-1424)", - "warning": true, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": { - "authSource": "foo" - } - }, - { - "description": "Repeated readConcernLevel key", - "uri": "mongodb://example.com/?readConcernLevel=local&readConcernLevel=majority", - "valid": true, - "warning": true, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": { - "readconcernlevel": "majority" - } - }, - { - "description": "Repeated authmechanismproperties: key", - "uri": "mongodb://example.com/?authmechanismproperties=SERVICE_NAME:42&authmechanismproperties=SERVICE_NAME:49", - "valid": true, - "warning": true, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": { - "authmechanismproperties": { "SERVICE_NAME": "49" } - } - }, - { - "description": "Repeated appname key", - "uri": "mongodb://example.com/?appname=example&appname=example42", - "valid": true, - "warning": true, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": { - "appname": "example42" - } - }, - { - "description": "Username containing an unescaped :", - "uri": "mongodb://alic::e@127.0.0.1:27017", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username containing an unescaped :", - "uri": "mongodb://alic::e@[::1]", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username containing an unescaped :", - "uri": "mongodb://alic::e@[::1]:27017", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username containing an unescaped :", - "uri": "mongodb://alic::e@%2Ftmp%2Fmongodb-27017.sock/", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "should default to SERVICE_NAME:mongodb even if other authMechanismProperties present", - "uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authMechanismProperties=CANONICALIZE_HOST_NAME:true", - "valid": true, - "credential": { - "username": "user@DOMAIN.COM", - "password": null, - "source": "$external", - "mechanism": "GSSAPI", - "mechanism_properties": { - "SERVICE_NAME": "mongodb", - "CANONICALIZE_HOST_NAME": true - } - } - }, - { - "description": "should detect case-insensitive service_name", - "uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authMechanismProperties=CANONICALIZE_HOST_NAME:true,service_name:abc", - "valid": true, - "credential": { - "username": "user@DOMAIN.COM", - "password": null, - "source": "$external", - "mechanism": "GSSAPI", - "mechanism_properties": { - "SERVICE_NAME": "abc", - "CANONICALIZE_HOST_NAME": true - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/invalid-uris.json b/lib/mongoc/libmongoc/tests/json/connection_uri/invalid-uris.json deleted file mode 100644 index 2a182fac7e237598bf28e457d80ec19b256d0e71..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/invalid-uris.json +++ /dev/null @@ -1,274 +0,0 @@ -{ - "tests": [ - { - "description": "Empty string", - "uri": "", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid scheme", - "uri": "mongo://localhost:27017", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Missing host", - "uri": "mongodb://", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Double colon in host identifier", - "uri": "mongodb://localhost::27017", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Double colon in host identifier and trailing slash", - "uri": "mongodb://localhost::27017/", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Double colon in host identifier with missing host and port", - "uri": "mongodb://::", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Double colon in host identifier with missing port", - "uri": "mongodb://localhost,localhost::", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Double colon in host identifier and second host", - "uri": "mongodb://localhost::27017,abc", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (negative number) with hostname", - "uri": "mongodb://localhost:-1", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (zero) with hostname", - "uri": "mongodb://localhost:0/", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (positive number) with hostname", - "uri": "mongodb://localhost:65536", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (positive number) with hostname and trailing slash", - "uri": "mongodb://localhost:65536/", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (non-numeric string) with hostname", - "uri": "mongodb://localhost:foo", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (negative number) with IP literal", - "uri": "mongodb://[::1]:-1", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (zero) with IP literal", - "uri": "mongodb://[::1]:0/", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (positive number) with IP literal", - "uri": "mongodb://[::1]:65536", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (positive number) with IP literal and trailing slash", - "uri": "mongodb://[::1]:65536/", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Invalid port (non-numeric string) with IP literal", - "uri": "mongodb://[::1]:foo", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Missing delimiting slash between hosts and options", - "uri": "mongodb://example.com?w=1", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Incomplete key value pair for option", - "uri": "mongodb://example.com/?w", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username with password containing an unescaped colon", - "uri": "mongodb://alice:foo:bar@127.0.0.1", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username containing an unescaped at-sign", - "uri": "mongodb://alice@@127.0.0.1", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username with password containing an unescaped at-sign", - "uri": "mongodb://alice@foo:bar@127.0.0.1", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username containing an unescaped slash", - "uri": "mongodb://alice/@localhost/db", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username containing unescaped slash with password", - "uri": "mongodb://alice/bob:foo@localhost/db", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username with password containing an unescaped slash", - "uri": "mongodb://alice:foo/bar@localhost/db", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Host with unescaped slash", - "uri": "mongodb:///tmp/mongodb-27017.sock/", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "mongodb+srv with multiple service names", - "uri": "mongodb+srv://test5.test.mongodb.com,test6.test.mongodb.com", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "mongodb+srv with port number", - "uri": "mongodb+srv://test7.test.mongodb.com:27018", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - }, - { - "description": "Username with password containing an unescaped percent sign", - "uri": "mongodb://alice%foo:bar@127.0.0.1", - "valid": false, - "warning": null, - "hosts": null, - "auth": null, - "options": null - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-auth.json b/lib/mongoc/libmongoc/tests/json/connection_uri/valid-auth.json deleted file mode 100644 index 4f684ff185620d5d8e1d784f51dcf22f8f09b706..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-auth.json +++ /dev/null @@ -1,332 +0,0 @@ -{ - "tests": [ - { - "description": "User info for single IPv4 host without database", - "uri": "mongodb://alice:foo@127.0.0.1", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - } - ], - "auth": { - "username": "alice", - "password": "foo", - "db": null - }, - "options": null - }, - { - "description": "User info for single IPv4 host with database", - "uri": "mongodb://alice:foo@127.0.0.1/test", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - } - ], - "auth": { - "username": "alice", - "password": "foo", - "db": "test" - }, - "options": null - }, - { - "description": "User info for single IP literal host without database", - "uri": "mongodb://bob:bar@[::1]:27018", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ip_literal", - "host": "::1", - "port": 27018 - } - ], - "auth": { - "username": "bob", - "password": "bar", - "db": null - }, - "options": null - }, - { - "description": "User info for single IP literal host with database", - "uri": "mongodb://bob:bar@[::1]:27018/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ip_literal", - "host": "::1", - "port": 27018 - } - ], - "auth": { - "username": "bob", - "password": "bar", - "db": "admin" - }, - "options": null - }, - { - "description": "User info for single hostname without database", - "uri": "mongodb://eve:baz@example.com", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": { - "username": "eve", - "password": "baz", - "db": null - }, - "options": null - }, - { - "description": "User info for single hostname with database", - "uri": "mongodb://eve:baz@example.com/db2", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": { - "username": "eve", - "password": "baz", - "db": "db2" - }, - "options": null - }, - { - "description": "User info for multiple hosts without database", - "uri": "mongodb://alice:secret@127.0.0.1,example.com:27018", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - }, - { - "type": "hostname", - "host": "example.com", - "port": 27018 - } - ], - "auth": { - "username": "alice", - "password": "secret", - "db": null - }, - "options": null - }, - { - "description": "User info for multiple hosts with database", - "uri": "mongodb://alice:secret@example.com,[::1]:27019/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - }, - { - "type": "ip_literal", - "host": "::1", - "port": 27019 - } - ], - "auth": { - "username": "alice", - "password": "secret", - "db": "admin" - }, - "options": null - }, - { - "description": "Username without password", - "uri": "mongodb://alice@127.0.0.1", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - } - ], - "auth": { - "username": "alice", - "password": null, - "db": null - }, - "options": null - }, - { - "description": "Username with empty password", - "uri": "mongodb://alice:@127.0.0.1", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - } - ], - "auth": { - "username": "alice", - "password": "", - "db": null - }, - "options": null - }, - { - "description": "Escaped username and database without password", - "uri": "mongodb://%40l%3Ace%2F%3D@example.com/my%3Ddb", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": { - "username": "@l:ce/=", - "password": null, - "db": "my=db" - }, - "options": null - }, - { - "description": "Escaped user info and database (MONGODB-CR)", - "uri": "mongodb://%24am:f%3Azzb%40z%2Fz%3D@127.0.0.1/admin%3F?authMechanism=MONGODB-CR", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - } - ], - "auth": { - "username": "$am", - "password": "f:zzb@z/z=", - "db": "admin?" - }, - "options": { - "authmechanism": "MONGODB-CR" - } - }, - { - "description": "Subdelimiters in user/pass don't need escaping (MONGODB-CR)", - "uri": "mongodb://!$&'()*+,;=:!$&'()*+,;=@127.0.0.1/admin?authMechanism=MONGODB-CR", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - } - ], - "auth": { - "username": "!$&'()*+,;=", - "password": "!$&'()*+,;=", - "db": "admin" - }, - "options": { - "authmechanism": "MONGODB-CR" - } - }, - { - "description": "Escaped username (MONGODB-X509)", - "uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "localhost", - "port": null - } - ], - "auth": { - "username": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry", - "password": null, - "db": null - }, - "options": { - "authmechanism": "MONGODB-X509" - } - }, - { - "description": "Escaped username (GSSAPI)", - "uri": "mongodb://user%40EXAMPLE.COM:secret@localhost/?authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true&authMechanism=GSSAPI", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "localhost", - "port": null - } - ], - "auth": { - "username": "user@EXAMPLE.COM", - "password": "secret", - "db": null - }, - "options": { - "authmechanism": "GSSAPI", - "authmechanismproperties": { - "SERVICE_NAME": "other", - "CANONICALIZE_HOST_NAME": true - } - } - }, - { - "description": "At-signs in options aren't part of the userinfo", - "uri": "mongodb://alice:secret@example.com/admin?replicaset=my@replicaset", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": { - "username": "alice", - "password": "secret", - "db": "admin" - }, - "options": { - "replicaset": "my@replicaset" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-db-with-dotted-name.json b/lib/mongoc/libmongoc/tests/json/connection_uri/valid-db-with-dotted-name.json deleted file mode 100644 index 5b5aaa5ee3b6588f04de26731c0a53dd6440e887..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-db-with-dotted-name.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "tests": [ - { - "description": "Multiple Unix domain sockets and auth DB resembling a socket (relative path)", - "uri": "mongodb://rel%2Fmongodb-27017.sock,rel%2Fmongodb-27018.sock/admin.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "rel/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": null, - "password": null, - "db": "admin.sock" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets with auth DB resembling a path (relative path)", - "uri": "mongodb://rel%2Fmongodb-27017.sock,rel%2Fmongodb-27018.sock/admin.shoe", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "rel/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": null, - "password": null, - "db": "admin.shoe" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets and auth DB resembling a socket (absolute path)", - "uri": "mongodb://%2Ftmp%2Fmongodb-27017.sock,%2Ftmp%2Fmongodb-27018.sock/admin.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "/tmp/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": null, - "password": null, - "db": "admin.sock" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets with auth DB resembling a path (absolute path)", - "uri": "mongodb://%2Ftmp%2Fmongodb-27017.sock,%2Ftmp%2Fmongodb-27018.sock/admin.shoe", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "/tmp/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": null, - "password": null, - "db": "admin.shoe" - }, - "options": null - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-host_identifiers.json b/lib/mongoc/libmongoc/tests/json/connection_uri/valid-host_identifiers.json deleted file mode 100644 index e8833b4af2992f01c826f9812417e1a130963d7e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-host_identifiers.json +++ /dev/null @@ -1,154 +0,0 @@ -{ - "tests": [ - { - "description": "Single IPv4 host without port", - "uri": "mongodb://127.0.0.1", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Single IPv4 host with port", - "uri": "mongodb://127.0.0.1:27018", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": 27018 - } - ], - "auth": null, - "options": null - }, - { - "description": "Single IP literal host without port", - "uri": "mongodb://[::1]", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ip_literal", - "host": "::1", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Single IP literal host with port", - "uri": "mongodb://[::1]:27019", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ip_literal", - "host": "::1", - "port": 27019 - } - ], - "auth": null, - "options": null - }, - { - "description": "Single hostname without port", - "uri": "mongodb://example.com", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Single hostname with port", - "uri": "mongodb://example.com:27020", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": 27020 - } - ], - "auth": null, - "options": null - }, - { - "description": "Single hostname (resembling IPv4) without port", - "uri": "mongodb://256.0.0.1", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "256.0.0.1", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Multiple hosts (mixed formats)", - "uri": "mongodb://127.0.0.1,[::1]:27018,example.com:27019", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": null - }, - { - "type": "ip_literal", - "host": "::1", - "port": 27018 - }, - { - "type": "hostname", - "host": "example.com", - "port": 27019 - } - ], - "auth": null, - "options": null - }, - { - "description": "UTF-8 hosts", - "uri": "mongodb://bücher.example.com,umläut.example.com/", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "bücher.example.com", - "port": null - }, - { - "type": "hostname", - "host": "umläut.example.com", - "port": null - } - ], - "auth": null, - "options": null - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-options.json b/lib/mongoc/libmongoc/tests/json/connection_uri/valid-options.json deleted file mode 100644 index 4c2bded9e72dbb96d294417c486141fd2fda2596..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-options.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "tests": [ - { - "description": "Option names are normalized to lowercase", - "uri": "mongodb://alice:secret@example.com/admin?AUTHMechanism=MONGODB-CR", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": { - "username": "alice", - "password": "secret", - "db": "admin" - }, - "options": { - "authmechanism": "MONGODB-CR" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-unix_socket-absolute.json b/lib/mongoc/libmongoc/tests/json/connection_uri/valid-unix_socket-absolute.json deleted file mode 100644 index 5bb02476eb7d0c56f27a9c0e4d23251463d7914a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-unix_socket-absolute.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "tests": [ - { - "description": "Unix domain socket (absolute path with trailing slash)", - "uri": "mongodb://%2Ftmp%2Fmongodb-27017.sock/", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket (absolute path without trailing slash)", - "uri": "mongodb://%2Ftmp%2Fmongodb-27017.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket (absolute path with spaces in path)", - "uri": "mongodb://%2Ftmp%2F %2Fmongodb-27017.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/ /mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Multiple Unix domain sockets (absolute paths)", - "uri": "mongodb://%2Ftmp%2Fmongodb-27017.sock,%2Ftmp%2Fmongodb-27018.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "/tmp/mongodb-27018.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Multiple hosts (absolute path and ipv4)", - "uri": "mongodb://127.0.0.1:27017,%2Ftmp%2Fmongodb-27017.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": 27017 - }, - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Multiple hosts (absolute path and hostname resembling relative path)", - "uri": "mongodb://mongodb-27017.sock,%2Ftmp%2Fmongodb-27018.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "/tmp/mongodb-27018.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket with auth database (absolute path)", - "uri": "mongodb://alice:foo@%2Ftmp%2Fmongodb-27017.sock/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - } - ], - "auth": { - "username": "alice", - "password": "foo", - "db": "admin" - }, - "options": null - }, - { - "description": "Unix domain socket with path resembling socket file (absolute path with trailing slash)", - "uri": "mongodb://%2Ftmp%2Fpath.to.sock%2Fmongodb-27017.sock/", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/path.to.sock/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket with path resembling socket file (absolute path without trailing slash)", - "uri": "mongodb://%2Ftmp%2Fpath.to.sock%2Fmongodb-27017.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/path.to.sock/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket with path resembling socket file and auth (absolute path)", - "uri": "mongodb://bob:bar@%2Ftmp%2Fpath.to.sock%2Fmongodb-27017.sock/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/path.to.sock/mongodb-27017.sock", - "port": null - } - ], - "auth": { - "username": "bob", - "password": "bar", - "db": "admin" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets and auth DB (absolute path)", - "uri": "mongodb://%2Ftmp%2Fmongodb-27017.sock,%2Ftmp%2Fmongodb-27018.sock/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "/tmp/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": null, - "password": null, - "db": "admin" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets with auth DB (absolute path)", - "uri": "mongodb://%2Ftmp%2Fmongodb-27017.sock,%2Ftmp%2Fmongodb-27018.sock/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "/tmp/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": null, - "password": null, - "db": "admin" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets with auth and query string (absolute path)", - "uri": "mongodb://bob:bar@%2Ftmp%2Fmongodb-27017.sock,%2Ftmp%2Fmongodb-27018.sock/admin?w=1", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "/tmp/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "/tmp/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": "bob", - "password": "bar", - "db": "admin" - }, - "options": { - "w": 1 - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-unix_socket-relative.json b/lib/mongoc/libmongoc/tests/json/connection_uri/valid-unix_socket-relative.json deleted file mode 100644 index 2ce649ffc238d45c223fa0d761762d4750d0071e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-unix_socket-relative.json +++ /dev/null @@ -1,271 +0,0 @@ -{ - "tests": [ - { - "description": "Unix domain socket (relative path with trailing slash)", - "uri": "mongodb://rel%2Fmongodb-27017.sock/", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket (relative path without trailing slash)", - "uri": "mongodb://rel%2Fmongodb-27017.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket (relative path with spaces)", - "uri": "mongodb://rel%2F %2Fmongodb-27017.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/ /mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Multiple Unix domain sockets (relative paths)", - "uri": "mongodb://rel%2Fmongodb-27017.sock,rel%2Fmongodb-27018.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "rel/mongodb-27018.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Multiple Unix domain sockets (relative and absolute paths)", - "uri": "mongodb://rel%2Fmongodb-27017.sock,%2Ftmp%2Fmongodb-27018.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "/tmp/mongodb-27018.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Multiple hosts (relative path and ipv4)", - "uri": "mongodb://127.0.0.1:27017,rel%2Fmongodb-27017.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "ipv4", - "host": "127.0.0.1", - "port": 27017 - }, - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Multiple hosts (relative path and hostname resembling relative path)", - "uri": "mongodb://mongodb-27017.sock,rel%2Fmongodb-27018.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "hostname", - "host": "mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "rel/mongodb-27018.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket with auth database (relative path)", - "uri": "mongodb://alice:foo@rel%2Fmongodb-27017.sock/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - } - ], - "auth": { - "username": "alice", - "password": "foo", - "db": "admin" - }, - "options": null - }, - { - "description": "Unix domain socket with path resembling socket file (relative path with trailing slash)", - "uri": "mongodb://rel%2Fpath.to.sock%2Fmongodb-27017.sock/", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/path.to.sock/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket with path resembling socket file (relative path without trailing slash)", - "uri": "mongodb://rel%2Fpath.to.sock%2Fmongodb-27017.sock", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/path.to.sock/mongodb-27017.sock", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unix domain socket with path resembling socket file and auth (relative path)", - "uri": "mongodb://bob:bar@rel%2Fpath.to.sock%2Fmongodb-27017.sock/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/path.to.sock/mongodb-27017.sock", - "port": null - } - ], - "auth": { - "username": "bob", - "password": "bar", - "db": "admin" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets and auth DB resembling a socket (relative path)", - "uri": "mongodb://rel%2Fmongodb-27017.sock,rel%2Fmongodb-27018.sock/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "rel/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": null, - "password": null, - "db": "admin" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets with auth DB resembling a path (relative path)", - "uri": "mongodb://rel%2Fmongodb-27017.sock,rel%2Fmongodb-27018.sock/admin", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "rel/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": null, - "password": null, - "db": "admin" - }, - "options": null - }, - { - "description": "Multiple Unix domain sockets with auth and query string (relative path)", - "uri": "mongodb://bob:bar@rel%2Fmongodb-27017.sock,rel%2Fmongodb-27018.sock/admin?w=1", - "valid": true, - "warning": false, - "hosts": [ - { - "type": "unix", - "host": "rel/mongodb-27017.sock", - "port": null - }, - { - "type": "unix", - "host": "rel/mongodb-27018.sock", - "port": null - } - ], - "auth": { - "username": "bob", - "password": "bar", - "db": "admin" - }, - "options": { - "w": 1 - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-warnings.json b/lib/mongoc/libmongoc/tests/json/connection_uri/valid-warnings.json deleted file mode 100644 index 87f7248f21ec2fa67b0eca285927bec8259d291d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/connection_uri/valid-warnings.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "tests": [ - { - "description": "Unrecognized option keys are ignored", - "uri": "mongodb://example.com/?foo=bar", - "valid": true, - "warning": true, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Unsupported option values are ignored", - "uri": "mongodb://example.com/?fsync=ifPossible", - "valid": true, - "warning": true, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": null - }, - { - "description": "Repeated option keys", - "uri": "mongodb://example.com/?replicaSet=test&replicaSet=test", - "valid": true, - "warning": true, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": { - "replicaset": "test" - } - }, - { - "description": "Deprecated (or unknown) options are ignored if replacement exists", - "uri": "mongodb://example.com/?wtimeout=5&wtimeoutMS=10", - "valid": true, - "warning": true, - "hosts": [ - { - "type": "hostname", - "host": "example.com", - "port": null - } - ], - "auth": null, - "options": { - "wtimeoutms": 10 - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate-collation.json deleted file mode 100644 index 85662a442fb13f397cf4b1546cebbe2aed7c4031..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate-collation.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": "ping" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "Aggregate with collation", - "operation": { - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$match": { - "x": "PING" - } - } - ], - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": [ - { - "_id": 1, - "x": "ping" - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate-out.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate-out.json deleted file mode 100644 index 4e33f9288f087ad8d285e029cd4f214538b4448c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate-out.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "minServerVersion": "2.6", - "tests": [ - { - "description": "Aggregate with $out", - "operation": { - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ], - "batchSize": 2 - } - }, - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "Aggregate with $out and batch size of 0", - "operation": { - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ], - "batchSize": 0 - } - }, - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate.json deleted file mode 100644 index 797a922395a8519bd8c6706a85697081a6eef1e8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/aggregate.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "Aggregate with multiple stages", - "operation": { - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - } - ], - "batchSize": 2 - } - }, - "outcome": { - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/count-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/count-collation.json deleted file mode 100644 index 6f75282fe0fc78636221639d91d9e4fe9a9939d0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/count-collation.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": "PING" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "Count documents with collation", - "operation": { - "name": "countDocuments", - "arguments": { - "filter": { - "x": "ping" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": 1 - } - }, - { - "description": "Deprecated count with collation", - "operation": { - "name": "count", - "arguments": { - "filter": { - "x": "ping" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": 1 - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/count-empty.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/count-empty.json deleted file mode 100644 index 2b8627e0c69ec22abae5709d8bd12fe83632dbf5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/count-empty.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "data": [], - "tests": [ - { - "description": "Estimated document count with empty collection", - "operation": { - "name": "estimatedDocumentCount", - "arguments": {} - }, - "outcome": { - "result": 0 - } - }, - { - "description": "Count documents with empty collection", - "operation": { - "name": "countDocuments", - "arguments": { - "filter": {} - } - }, - "outcome": { - "result": 0 - } - }, - { - "description": "Deprecated count with empty collection", - "operation": { - "name": "count", - "arguments": { - "filter": {} - } - }, - "outcome": { - "result": 0 - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/count.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/count.json deleted file mode 100644 index 9642b2fbd087a4753a3bbe082ca9e4bf690e9651..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/count.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "Estimated document count", - "operation": { - "name": "estimatedDocumentCount", - "arguments": {} - }, - "outcome": { - "result": 3 - } - }, - { - "description": "Count documents without a filter", - "operation": { - "name": "countDocuments", - "arguments": { - "filter": {} - } - }, - "outcome": { - "result": 3 - } - }, - { - "description": "Count documents with a filter", - "operation": { - "name": "countDocuments", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - } - } - }, - "outcome": { - "result": 2 - } - }, - { - "description": "Count documents with skip and limit", - "operation": { - "name": "countDocuments", - "arguments": { - "filter": {}, - "skip": 1, - "limit": 3 - } - }, - "outcome": { - "result": 2 - } - }, - { - "description": "Deprecated count without a filter", - "operation": { - "name": "count", - "arguments": { - "filter": {} - } - }, - "outcome": { - "result": 3 - } - }, - { - "description": "Deprecated count with a filter", - "operation": { - "name": "count", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - } - } - }, - "outcome": { - "result": 2 - } - }, - { - "description": "Deprecated count with skip and limit", - "operation": { - "name": "count", - "arguments": { - "filter": {}, - "skip": 1, - "limit": 3 - } - }, - "outcome": { - "result": 2 - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/distinct-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/distinct-collation.json deleted file mode 100644 index 0af0c67cb70f9b4743a9d64cb4566d04eb7c9003..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/distinct-collation.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "string": "PING" - }, - { - "_id": 2, - "string": "ping" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "Distinct with a collation", - "operation": { - "name": "distinct", - "arguments": { - "fieldName": "string", - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": [ - "PING" - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/distinct.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/distinct.json deleted file mode 100644 index a57ee36a8345e8e93472b996f252d02729809e3d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/distinct.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "Distinct without a filter", - "operation": { - "name": "distinct", - "arguments": { - "fieldName": "x", - "filter": {} - } - }, - "outcome": { - "result": [ - 11, - 22, - 33 - ] - } - }, - { - "description": "Distinct with a filter", - "operation": { - "name": "distinct", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - } - }, - "outcome": { - "result": [ - 22, - 33 - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/find-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/find-collation.json deleted file mode 100644 index 53d0e94900dd9fd085f5a330faa84c83214488d9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/find-collation.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": "ping" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "Find with a collation", - "operation": { - "name": "find", - "arguments": { - "filter": { - "x": "PING" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": [ - { - "_id": 1, - "x": "ping" - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/read/find.json b/lib/mongoc/libmongoc/tests/json/crud/v1/read/find.json deleted file mode 100644 index 3597e37be6f5e1d7d52c7c6ce366bdf1e3ff9a48..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/read/find.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - }, - { - "_id": 5, - "x": 55 - } - ], - "tests": [ - { - "description": "Find with filter", - "operation": { - "name": "find", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - "outcome": { - "result": [ - { - "_id": 1, - "x": 11 - } - ] - } - }, - { - "description": "Find with filter, sort, skip, and limit", - "operation": { - "name": "find", - "arguments": { - "filter": { - "_id": { - "$gt": 2 - } - }, - "sort": { - "_id": 1 - }, - "skip": 2, - "limit": 2 - } - }, - "outcome": { - "result": [ - { - "_id": 5, - "x": 55 - } - ] - } - }, - { - "description": "Find with limit, sort, and batchsize", - "operation": { - "name": "find", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4, - "batchSize": 2 - } - }, - "outcome": { - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite-arrayFilters.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite-arrayFilters.json deleted file mode 100644 index 99e73f5d7554b58b659d906f0ae4d334051614d5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite-arrayFilters.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ], - "minServerVersion": "3.5.6", - "tests": [ - { - "description": "BulkWrite with arrayFilters", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 3 - } - ] - } - }, - { - "name": "updateMany", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 1 - } - ] - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 3, - "modifiedCount": 3, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 2 - }, - { - "b": 2 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 2 - } - ] - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite-collation.json deleted file mode 100644 index 8e9d1bcb1ac4bb335988dc4591ae2b87dc4c8943..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite-collation.json +++ /dev/null @@ -1,217 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - }, - { - "_id": 3, - "x": "pINg" - }, - { - "_id": 4, - "x": "pong" - }, - { - "_id": 5, - "x": "pONg" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "BulkWrite with delete operations and collation", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "deleteOne", - "arguments": { - "filter": { - "x": "PING" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "x": "PING" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - { - "name": "deleteMany", - "arguments": { - "filter": { - "x": "PONG" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 4, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - } - ] - } - } - }, - { - "description": "BulkWrite with update operations and collation", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "updateMany", - "arguments": { - "filter": { - "x": "ping" - }, - "update": { - "$set": { - "x": "PONG" - } - }, - "collation": { - "locale": "en_US", - "strength": 3 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "x": "ping" - }, - "update": { - "$set": { - "x": "PONG" - } - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - { - "name": "replaceOne", - "arguments": { - "filter": { - "x": "ping" - }, - "replacement": { - "_id": 6, - "x": "ping" - }, - "upsert": true, - "collation": { - "locale": "en_US", - "strength": 3 - } - } - }, - { - "name": "updateMany", - "arguments": { - "filter": { - "x": "pong" - }, - "update": { - "$set": { - "x": "PONG" - } - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 6, - "modifiedCount": 4, - "upsertedCount": 1, - "upsertedIds": { - "2": 6 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "PONG" - }, - { - "_id": 3, - "x": "PONG" - }, - { - "_id": 4, - "x": "PONG" - }, - { - "_id": 5, - "x": "PONG" - }, - { - "_id": 6, - "x": "ping" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite.json deleted file mode 100644 index dc00da28add6f25fe657f89276577c8e2f18a9b5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/bulkWrite.json +++ /dev/null @@ -1,778 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "minServerVersion": "2.6", - "tests": [ - { - "description": "BulkWrite with deleteOne operations", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 3 - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 2 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 1, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - } - ] - } - } - }, - { - "description": "BulkWrite with deleteMany operations", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "deleteMany", - "arguments": { - "filter": { - "x": { - "$lt": 11 - } - } - } - }, - { - "name": "deleteMany", - "arguments": { - "filter": { - "x": { - "$lte": 22 - } - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 2, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [] - } - } - }, - { - "description": "BulkWrite with insertOne operations", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 4, - "x": 44 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 2, - "insertedIds": { - "0": 3, - "1": 4 - }, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - }, - { - "description": "BulkWrite with replaceOne operations", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 3 - }, - "replacement": { - "x": 33 - } - } - }, - { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "x": 12 - } - } - }, - { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 3 - }, - "replacement": { - "x": 33 - }, - "upsert": true - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 1, - "upsertedIds": { - "2": 3 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "BulkWrite with updateOne operations", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 0 - }, - "update": { - "$set": { - "x": 0 - } - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$set": { - "x": 11 - } - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 3 - }, - "update": { - "$set": { - "x": 33 - } - }, - "upsert": true - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 2, - "modifiedCount": 1, - "upsertedCount": 1, - "upsertedIds": { - "3": 3 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "BulkWrite with updateMany operations", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "updateMany", - "arguments": { - "filter": { - "x": { - "$lt": 11 - } - }, - "update": { - "$set": { - "x": 0 - } - } - } - }, - { - "name": "updateMany", - "arguments": { - "filter": { - "x": { - "$lte": 22 - } - }, - "update": { - "$unset": { - "y": 1 - } - } - } - }, - { - "name": "updateMany", - "arguments": { - "filter": { - "x": { - "$lte": 22 - } - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "updateMany", - "arguments": { - "filter": { - "_id": 3 - }, - "update": { - "$set": { - "x": 33 - } - }, - "upsert": true - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 4, - "modifiedCount": 2, - "upsertedCount": 1, - "upsertedIds": { - "3": 3 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "BulkWrite with mixed ordered operations", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "updateMany", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 4, - "x": 44 - } - } - }, - { - "name": "deleteMany", - "arguments": { - "filter": { - "x": { - "$nin": [ - 24, - 34 - ] - } - } - } - }, - { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "_id": 4, - "x": 44 - }, - "upsert": true - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 2, - "insertedCount": 2, - "insertedIds": { - "0": 3, - "3": 4 - }, - "matchedCount": 3, - "modifiedCount": 3, - "upsertedCount": 1, - "upsertedIds": { - "5": 4 - } - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 24 - }, - { - "_id": 3, - "x": 34 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - }, - { - "description": "BulkWrite with mixed unordered operations", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 3 - }, - "replacement": { - "_id": 3, - "x": 33 - }, - "upsert": true - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - } - ], - "options": { - "ordered": false - } - } - }, - "outcome": { - "result": { - "deletedCount": 1, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 1, - "upsertedIds": { - "0": 3 - } - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "BulkWrite continue-on-error behavior with unordered (preexisting duplicate key)", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 4, - "x": 44 - } - } - } - ], - "options": { - "ordered": false - } - } - }, - "outcome": { - "error": true, - "result": { - "deletedCount": 0, - "insertedCount": 2, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - }, - { - "description": "BulkWrite continue-on-error behavior with unordered (duplicate key in requests)", - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 4, - "x": 44 - } - } - } - ], - "options": { - "ordered": false - } - } - }, - "outcome": { - "error": true, - "result": { - "deletedCount": 0, - "insertedCount": 2, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteMany-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteMany-collation.json deleted file mode 100644 index d17bf3bcb9ead2a45addc0c2eb61763639b21b50..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteMany-collation.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - }, - { - "_id": 3, - "x": "pINg" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "DeleteMany when many documents match with collation", - "operation": { - "name": "deleteMany", - "arguments": { - "filter": { - "x": "PING" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": { - "deletedCount": 2 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteMany.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteMany.json deleted file mode 100644 index 7eee85e77f473ae1473603b35c895bf1e223ec59..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteMany.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "DeleteMany when many documents match", - "operation": { - "name": "deleteMany", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - } - } - }, - "outcome": { - "result": { - "deletedCount": 2 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - } - ] - } - } - }, - { - "description": "DeleteMany when no document matches", - "operation": { - "name": "deleteMany", - "arguments": { - "filter": { - "_id": 4 - } - } - }, - "outcome": { - "result": { - "deletedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteOne-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteOne-collation.json deleted file mode 100644 index 2f7f9211300e4ecbc8f1c124a7ce480a8e4724fe..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteOne-collation.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - }, - { - "_id": 3, - "x": "pINg" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "DeleteOne when many documents matches with collation", - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "x": "PING" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": { - "deletedCount": 1 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 3, - "x": "pINg" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteOne.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteOne.json deleted file mode 100644 index a1106deae36dcbfcaae2093114c482e3be095a61..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/deleteOne.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "DeleteOne when many documents match", - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - } - } - }, - "outcome": { - "result": { - "deletedCount": 1 - } - } - }, - { - "description": "DeleteOne when one document matches", - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 2 - } - } - }, - "outcome": { - "result": { - "deletedCount": 1 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "DeleteOne when no documents match", - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 4 - } - } - }, - "outcome": { - "result": { - "deletedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndDelete-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndDelete-collation.json deleted file mode 100644 index 1ff37d2e88ad11ce435783113c7e46a99d30e7a3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndDelete-collation.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - }, - { - "_id": 3, - "x": "pINg" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "FindOneAndDelete when one document matches with collation", - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "_id": 2, - "x": "PING" - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": { - "x": "ping" - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 3, - "x": "pINg" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndDelete.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndDelete.json deleted file mode 100644 index e424e2aad10e359697ea4535c266f0db55837930..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndDelete.json +++ /dev/null @@ -1,127 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "FindOneAndDelete when many documents match", - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 22 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndDelete when one document matches", - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "_id": 2 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 22 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndDelete when no documents match", - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "_id": 4 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": null, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace-collation.json deleted file mode 100644 index babb2f7c11ffe0db3470f4a44e237c3d6a87e9e0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace-collation.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "FindOneAndReplace when one document matches with collation returning the document after modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "x": "PING" - }, - "replacement": { - "x": "pong" - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": { - "x": "pong" - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "pong" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace-upsert.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace-upsert.json deleted file mode 100644 index 0f07bf9c18d4cdbcb316d1d01a0636b96e6c31ad..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace-upsert.json +++ /dev/null @@ -1,201 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "minServerVersion": "2.6", - "tests": [ - { - "description": "FindOneAndReplace when no documents match without id specified with upsert returning the document before modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "x": 44 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "upsert": true - } - }, - "outcome": { - "result": null, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - }, - { - "description": "FindOneAndReplace when no documents match without id specified with upsert returning the document after modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "x": 44 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - }, - "upsert": true - } - }, - "outcome": { - "result": { - "x": 44 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - }, - { - "description": "FindOneAndReplace when no documents match with id specified with upsert returning the document before modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "_id": 4, - "x": 44 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "upsert": true - } - }, - "outcome": { - "result": null, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - }, - { - "description": "FindOneAndReplace when no documents match with id specified with upsert returning the document after modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "_id": 4, - "x": 44 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - }, - "upsert": true - } - }, - "outcome": { - "result": { - "x": 44 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace.json deleted file mode 100644 index 70e5c3df4e9e569a829444c6fb99f6316003974c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndReplace.json +++ /dev/null @@ -1,273 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "FindOneAndReplace when many documents match returning the document before modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "replacement": { - "x": 32 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 22 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 32 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndReplace when many documents match returning the document after modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "replacement": { - "x": 32 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 32 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 32 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndReplace when one document matches returning the document before modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 2 - }, - "replacement": { - "x": 32 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 22 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 32 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndReplace when one document matches returning the document after modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 2 - }, - "replacement": { - "x": 32 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 32 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 32 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndReplace when no documents match returning the document before modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "x": 44 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": null, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndReplace when no documents match returning the document after modification", - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "x": 44 - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": null, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate-arrayFilters.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate-arrayFilters.json deleted file mode 100644 index 1aa13b863e7879ee26910643db8ddbd46288ea8a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate-arrayFilters.json +++ /dev/null @@ -1,203 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ], - "minServerVersion": "3.5.6", - "tests": [ - { - "description": "FindOneAndUpdate when no document matches arrayFilters", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 4 - } - ] - } - }, - "outcome": { - "result": { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when one document matches arrayFilters", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 3 - } - ] - } - }, - "outcome": { - "result": { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 2 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when multiple documents match arrayFilters", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 1 - } - ] - } - }, - "outcome": { - "result": { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 2 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate-collation.json deleted file mode 100644 index 04c1fe73ec5a063330cac0cd3d38d93067128f65..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate-collation.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - }, - { - "_id": 3, - "x": "pINg" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "FindOneAndUpdate when many documents match with collation returning the document before modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "x": "PING" - }, - "update": { - "$set": { - "x": "pong" - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "_id": 1 - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": { - "x": "ping" - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "pong" - }, - { - "_id": 3, - "x": "pINg" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate.json deleted file mode 100644 index 6da8325273b061b11b9f366c766561aa2c7ab428..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/findOneAndUpdate.json +++ /dev/null @@ -1,379 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "FindOneAndUpdate when many documents match returning the document before modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 22 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when many documents match returning the document after modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 23 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when one document matches returning the document before modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 22 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when one document matches returning the document after modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "x": 23 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when no documents match returning the document before modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": null, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when no documents match with upsert returning the document before modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "upsert": true - } - }, - "outcome": { - "result": null, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 1 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when no documents match returning the document after modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": null, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate when no documents match with upsert returning the document after modification", - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "projection": { - "x": 1, - "_id": 0 - }, - "returnDocument": "After", - "sort": { - "x": 1 - }, - "upsert": true - } - }, - "outcome": { - "result": { - "x": 1 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/insertMany.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/insertMany.json deleted file mode 100644 index 6a2e5261b74a4eadf71cb59d07a192fd3ffde87f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/insertMany.json +++ /dev/null @@ -1,159 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "tests": [ - { - "description": "InsertMany with non-existing documents", - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "insertedIds": { - "0": 2, - "1": 3 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertMany continue-on-error behavior with unordered (preexisting duplicate key)", - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "options": { - "ordered": false - } - } - }, - "outcome": { - "error": true, - "result": { - "deletedCount": 0, - "insertedCount": 2, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertMany continue-on-error behavior with unordered (duplicate key in requests)", - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "options": { - "ordered": false - } - } - }, - "outcome": { - "error": true, - "result": { - "deletedCount": 0, - "insertedCount": 2, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/insertOne.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/insertOne.json deleted file mode 100644 index 525de75e078d1d2c8420da4a2eb05ff236a295e7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/insertOne.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "tests": [ - { - "description": "InsertOne with a non-existing document", - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - "outcome": { - "result": { - "insertedId": 2 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/replaceOne-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/replaceOne-collation.json deleted file mode 100644 index a668fe738317751f41a8e2c01fb209cb20d9e8a5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/replaceOne-collation.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "ReplaceOne when one document matches with collation", - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "x": "PING" - }, - "replacement": { - "_id": 2, - "x": "pong" - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "pong" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/replaceOne.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/replaceOne.json deleted file mode 100644 index 101af25c7c51b13de772075e81c7ef5263280298..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/replaceOne.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "minServerVersion": "2.6", - "tests": [ - { - "description": "ReplaceOne when many documents match", - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "replacement": { - "x": 111 - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - } - }, - { - "description": "ReplaceOne when one document matches", - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "ReplaceOne when no documents match", - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "_id": 4, - "x": 1 - } - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "ReplaceOne with upsert when no documents match without an id specified", - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "x": 1 - }, - "upsert": true - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 1, - "upsertedId": 4 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 1 - } - ] - } - } - }, - { - "description": "ReplaceOne with upsert when no documents match with an id specified", - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 4 - }, - "replacement": { - "_id": 4, - "x": 1 - }, - "upsert": true - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 1, - "upsertedId": 4 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany-arrayFilters.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany-arrayFilters.json deleted file mode 100644 index ae4c123ea51acf659990f9fd8960c153e784c019..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany-arrayFilters.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ], - "minServerVersion": "3.5.6", - "tests": [ - { - "description": "UpdateMany when no documents match arrayFilters", - "operation": { - "name": "updateMany", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 4 - } - ] - } - }, - "outcome": { - "result": { - "matchedCount": 2, - "modifiedCount": 0, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ] - } - } - }, - { - "description": "UpdateMany when one document matches arrayFilters", - "operation": { - "name": "updateMany", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 3 - } - ] - } - }, - "outcome": { - "result": { - "matchedCount": 2, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 2 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ] - } - } - }, - { - "description": "UpdateMany when multiple documents match arrayFilters", - "operation": { - "name": "updateMany", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 1 - } - ] - } - }, - "outcome": { - "result": { - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 2 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 2 - } - ] - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany-collation.json deleted file mode 100644 index 3cb49f229814eafe39abea5c61d103b3606f1036..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany-collation.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - }, - { - "_id": 3, - "x": "pINg" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "UpdateMany when many documents match with collation", - "operation": { - "name": "updateMany", - "arguments": { - "filter": { - "x": "ping" - }, - "update": { - "$set": { - "x": "pong" - } - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": { - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "pong" - }, - { - "_id": 3, - "x": "pong" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany.json deleted file mode 100644 index a3c339987d934a5e9c02916ae2f1a6714952c83d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateMany.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "minServerVersion": "2.6", - "tests": [ - { - "description": "UpdateMany when many documents match", - "operation": { - "name": "updateMany", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 34 - } - ] - } - } - }, - { - "description": "UpdateMany when one document matches", - "operation": { - "name": "updateMany", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "UpdateMany when no documents match", - "operation": { - "name": "updateMany", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "UpdateMany with upsert when no documents match", - "operation": { - "name": "updateMany", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 1, - "upsertedId": 4 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne-arrayFilters.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne-arrayFilters.json deleted file mode 100644 index 087ed4b82fc09bbd22e4bee156cc505a4be5b142..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne-arrayFilters.json +++ /dev/null @@ -1,395 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - }, - { - "_id": 3, - "y": [ - { - "b": 5, - "c": [ - { - "d": 2 - }, - { - "d": 1 - } - ] - } - ] - } - ], - "minServerVersion": "3.5.6", - "tests": [ - { - "description": "UpdateOne when no document matches arrayFilters", - "operation": { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 4 - } - ] - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 0, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - }, - { - "_id": 3, - "y": [ - { - "b": 5, - "c": [ - { - "d": 2 - }, - { - "d": 1 - } - ] - } - ] - } - ] - } - } - }, - { - "description": "UpdateOne when one document matches arrayFilters", - "operation": { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 3 - } - ] - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 2 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - }, - { - "_id": 3, - "y": [ - { - "b": 5, - "c": [ - { - "d": 2 - }, - { - "d": 1 - } - ] - } - ] - } - ] - } - } - }, - { - "description": "UpdateOne when multiple documents match arrayFilters", - "operation": { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 1 - } - ] - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 2 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - }, - { - "_id": 3, - "y": [ - { - "b": 5, - "c": [ - { - "d": 2 - }, - { - "d": 1 - } - ] - } - ] - } - ] - } - } - }, - { - "description": "UpdateOne when no documents match multiple arrayFilters", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 3 - }, - "update": { - "$set": { - "y.$[i].c.$[j].d": 0 - } - }, - "arrayFilters": [ - { - "i.b": 5 - }, - { - "j.d": 3 - } - ] - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 0, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - }, - { - "_id": 3, - "y": [ - { - "b": 5, - "c": [ - { - "d": 2 - }, - { - "d": 1 - } - ] - } - ] - } - ] - } - } - }, - { - "description": "UpdateOne when one document matches multiple arrayFilters", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 3 - }, - "update": { - "$set": { - "y.$[i].c.$[j].d": 0 - } - }, - "arrayFilters": [ - { - "i.b": 5 - }, - { - "j.d": 1 - } - ] - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - }, - { - "_id": 3, - "y": [ - { - "b": 5, - "c": [ - { - "d": 2 - }, - { - "d": 0 - } - ] - } - ] - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne-collation.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne-collation.json deleted file mode 100644 index c49112d519c9a499338fef54d7eccf42055d94e4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne-collation.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "ping" - } - ], - "minServerVersion": "3.4", - "tests": [ - { - "description": "UpdateOne when one document matches with collation", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "x": "PING" - }, - "update": { - "$set": { - "x": "pong" - } - }, - "collation": { - "locale": "en_US", - "strength": 2 - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": "pong" - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne.json b/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne.json deleted file mode 100644 index 76d2086bdb934ca450f22d8f89ea7ca121f02704..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v1/write/updateOne.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "minServerVersion": "2.6", - "tests": [ - { - "description": "UpdateOne when many documents match", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - } - }, - { - "description": "UpdateOne when one document matches", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "UpdateOne when no documents match", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "UpdateOne with upsert when no documents match", - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 1, - "upsertedId": 4 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v2/aggregate-merge.json b/lib/mongoc/libmongoc/tests/json/crud/v2/aggregate-merge.json deleted file mode 100644 index 037ae25d2468df4a0a1a6b48b378107fed4d53ba..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v2/aggregate-merge.json +++ /dev/null @@ -1,415 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.2.0" - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "collection_name": "test_aggregate_merge", - "tests": [ - { - "description": "Aggregate with $merge", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_merge", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ] - } - } - } - ], - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "Aggregate with $merge and batch size of 0", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ], - "batchSize": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_merge", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ], - "cursor": {} - } - } - } - ], - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "Aggregate with $merge and majority readConcern", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_merge", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ], - "readConcern": { - "level": "majority" - } - } - } - } - ], - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "Aggregate with $merge and local readConcern", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "collectionOptions": { - "readConcern": { - "level": "local" - } - }, - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_merge", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ], - "readConcern": { - "level": "local" - } - } - } - } - ], - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "Aggregate with $merge and available readConcern", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "collectionOptions": { - "readConcern": { - "level": "available" - } - }, - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_merge", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$merge": { - "into": "other_test_collection" - } - } - ], - "readConcern": { - "level": "available" - } - } - } - } - ], - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v2/aggregate-out-readConcern.json b/lib/mongoc/libmongoc/tests/json/crud/v2/aggregate-out-readConcern.json deleted file mode 100644 index c39ee0e2815e8218f24df8b17f62f0dea9338b37..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v2/aggregate-out-readConcern.json +++ /dev/null @@ -1,385 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.0", - "topology": [ - "replicaset", - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "collection_name": "test_aggregate_out_readconcern", - "tests": [ - { - "description": "readConcern majority with out stage", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_out_readconcern", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ], - "readConcern": { - "level": "majority" - } - } - } - } - ], - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "readConcern local with out stage", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "collectionOptions": { - "readConcern": { - "level": "local" - } - }, - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_out_readconcern", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ], - "readConcern": { - "level": "local" - } - } - } - } - ], - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "readConcern available with out stage", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "collectionOptions": { - "readConcern": { - "level": "available" - } - }, - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_out_readconcern", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ], - "readConcern": { - "level": "available" - } - } - } - } - ], - "outcome": { - "collection": { - "name": "other_test_collection", - "data": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "readConcern linearizable with out stage", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "collectionOptions": { - "readConcern": { - "level": "linearizable" - } - }, - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ] - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_out_readconcern", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ], - "readConcern": { - "level": "linearizable" - } - } - } - } - ] - }, - { - "description": "invalid readConcern with out stage", - "operations": [ - { - "object": "collection", - "name": "aggregate", - "collectionOptions": { - "readConcern": { - "level": "!invalid123" - } - }, - "arguments": { - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ] - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test_aggregate_out_readconcern", - "pipeline": [ - { - "$sort": { - "x": 1 - } - }, - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$out": "other_test_collection" - } - ], - "readConcern": { - "level": "!invalid123" - } - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v2/bulkWrite-arrayFilters.json b/lib/mongoc/libmongoc/tests/json/crud/v2/bulkWrite-arrayFilters.json deleted file mode 100644 index be26a337a5acfe4d299dcb18ebd2adcf6f4357ce..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v2/bulkWrite-arrayFilters.json +++ /dev/null @@ -1,160 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.5.6" - } - ], - "data": [ - { - "_id": 1, - "y": [ - { - "b": 3 - }, - { - "b": 1 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 1 - } - ] - } - ], - "collection_name": "test", - "database_name": "crud-tests", - "tests": [ - { - "description": "BulkWrite with arrayFilters", - "operations": [ - { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "updateOne", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 3 - } - ] - } - }, - { - "name": "updateMany", - "arguments": { - "filter": {}, - "update": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 1 - } - ] - } - } - ], - "options": { - "ordered": true - } - }, - "result": { - "deletedCount": 0, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 3, - "modifiedCount": 3, - "upsertedCount": 0, - "upsertedIds": {} - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": {}, - "u": { - "$set": { - "y.$[i].b": 2 - } - }, - "arrayFilters": [ - { - "i.b": 3 - } - ] - }, - { - "q": {}, - "u": { - "$set": { - "y.$[i].b": 2 - } - }, - "multi": true, - "arrayFilters": [ - { - "i.b": 1 - } - ] - } - ], - "ordered": true - }, - "command_name": "update", - "database_name": "crud-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "y": [ - { - "b": 2 - }, - { - "b": 2 - } - ] - }, - { - "_id": 2, - "y": [ - { - "b": 0 - }, - { - "b": 2 - } - ] - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v2/db-aggregate.json b/lib/mongoc/libmongoc/tests/json/crud/v2/db-aggregate.json deleted file mode 100644 index d88b9e18197cca88dac6265efb76947ebf8b4dcc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v2/db-aggregate.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6.0" - } - ], - "database_name": "admin", - "tests": [ - { - "description": "Aggregate with $listLocalSessions", - "operations": [ - { - "name": "aggregate", - "object": "database", - "arguments": { - "pipeline": [ - { - "$listLocalSessions": {} - }, - { - "$limit": 1 - }, - { - "$addFields": { - "dummy": "dummy field" - } - }, - { - "$project": { - "_id": 0, - "dummy": 1 - } - } - ] - }, - "result": [ - { - "dummy": "dummy field" - } - ] - } - ] - }, - { - "description": "Aggregate with $listLocalSessions and allowDiskUse", - "operations": [ - { - "name": "aggregate", - "object": "database", - "arguments": { - "pipeline": [ - { - "$listLocalSessions": {} - }, - { - "$limit": 1 - }, - { - "$addFields": { - "dummy": "dummy field" - } - }, - { - "$project": { - "_id": 0, - "dummy": 1 - } - } - ], - "allowDiskUse": true - }, - "result": [ - { - "dummy": "dummy field" - } - ] - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/crud/v2/updateWithPipelines.json b/lib/mongoc/libmongoc/tests/json/crud/v2/updateWithPipelines.json deleted file mode 100644 index 02286b1a288b7acb6dd018d7d9018a457188f07f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/crud/v2/updateWithPipelines.json +++ /dev/null @@ -1,239 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 1, - "y": 1, - "t": { - "u": { - "v": 1 - } - } - }, - { - "_id": 2, - "x": 2, - "y": 1 - } - ], - "minServerVersion": "4.1.11", - "collection_name": "test", - "database_name": "crud-tests", - "tests": [ - { - "description": "UpdateOne using pipelines", - "operations": [ - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": [ - { - "$replaceRoot": { - "newRoot": "$t" - } - }, - { - "$addFields": { - "foo": 1 - } - } - ] - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 1 - }, - "u": [ - { - "$replaceRoot": { - "newRoot": "$t" - } - }, - { - "$addFields": { - "foo": 1 - } - } - ] - } - ] - }, - "command_name": "update", - "database_name": "crud-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "u": { - "v": 1 - }, - "foo": 1 - }, - { - "_id": 2, - "x": 2, - "y": 1 - } - ] - } - } - }, - { - "description": "UpdateMany using pipelines", - "operations": [ - { - "name": "updateMany", - "arguments": { - "filter": {}, - "update": [ - { - "$project": { - "x": 1 - } - }, - { - "$addFields": { - "foo": 1 - } - } - ] - }, - "result": { - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": {}, - "u": [ - { - "$project": { - "x": 1 - } - }, - { - "$addFields": { - "foo": 1 - } - } - ], - "multi": true - } - ] - }, - "command_name": "update", - "database_name": "crud-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "x": 1, - "foo": 1 - }, - { - "_id": 2, - "x": 2, - "foo": 1 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate using pipelines", - "operations": [ - { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 1 - }, - "update": [ - { - "$project": { - "x": 1 - } - }, - { - "$addFields": { - "foo": 1 - } - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "update": [ - { - "$project": { - "x": 1 - } - }, - { - "$addFields": { - "foo": 1 - } - } - ] - }, - "command_name": "findAndModify", - "database_name": "crud-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "x": 1, - "foo": 1 - }, - { - "_id": 2, - "x": 2, - "y": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/gridfs/delete.json b/lib/mongoc/libmongoc/tests/json/gridfs/delete.json deleted file mode 100644 index d74e49284bdfea65f6cd21ba14b63e530b417cfc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/gridfs/delete.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "data": { - "files": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "length": 0, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "d41d8cd98f00b204e9800998ecf8427e", - "filename": "length-0", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000002" - }, - "length": 0, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "d41d8cd98f00b204e9800998ecf8427e", - "filename": "length-0-with-empty-chunk", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000003" - }, - "length": 2, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "c700ed4fdb1d27055aa3faa2c2432283", - "filename": "length-2", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000004" - }, - "length": 8, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "dd254cdc958e53abaa67da9f797125f5", - "filename": "length-8", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - } - ], - "chunks": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "files_id": { - "$oid": "000000000000000000000002" - }, - "n": 0, - "data": { - "$hex": "" - } - }, - { - "_id": { - "$oid": "000000000000000000000002" - }, - "files_id": { - "$oid": "000000000000000000000003" - }, - "n": 0, - "data": { - "$hex": "1122" - } - }, - { - "_id": { - "$oid": "000000000000000000000003" - }, - "files_id": { - "$oid": "000000000000000000000004" - }, - "n": 0, - "data": { - "$hex": "11223344" - } - }, - { - "_id": { - "$oid": "000000000000000000000004" - }, - "files_id": { - "$oid": "000000000000000000000004" - }, - "n": 1, - "data": { - "$hex": "55667788" - } - } - ] - }, - "tests": [ - { - "description": "Delete when length is 0", - "act": { - "operation": "delete", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - }, - "assert": { - "result": "void", - "data": [ - { - "delete": "expected.files", - "deletes": [ - { - "q": { - "_id": { - "$oid": "000000000000000000000001" - } - }, - "limit": 1 - } - ] - } - ] - } - }, - { - "description": "Delete when length is 0 and there is one extra empty chunk", - "act": { - "operation": "delete", - "arguments": { - "id": { - "$oid": "000000000000000000000002" - } - } - }, - "assert": { - "result": "void", - "data": [ - { - "delete": "expected.files", - "deletes": [ - { - "q": { - "_id": { - "$oid": "000000000000000000000002" - } - }, - "limit": 1 - } - ] - }, - { - "delete": "expected.chunks", - "deletes": [ - { - "q": { - "files_id": { - "$oid": "000000000000000000000002" - } - }, - "limit": 0 - } - ] - } - ] - } - }, - { - "description": "Delete when length is 8", - "act": { - "operation": "delete", - "arguments": { - "id": { - "$oid": "000000000000000000000004" - } - } - }, - "assert": { - "result": "void", - "data": [ - { - "delete": "expected.files", - "deletes": [ - { - "q": { - "_id": { - "$oid": "000000000000000000000004" - } - }, - "limit": 1 - } - ] - }, - { - "delete": "expected.chunks", - "deletes": [ - { - "q": { - "files_id": { - "$oid": "000000000000000000000004" - } - }, - "limit": 0 - } - ] - } - ] - } - }, - { - "description": "Delete when files entry does not exist", - "act": { - "operation": "delete", - "arguments": { - "id": { - "$oid": "000000000000000000000000" - } - } - }, - "assert": { - "error": "FileNotFound" - } - }, - { - "description": "Delete when files entry does not exist and there are orphaned chunks", - "arrange": { - "data": [ - { - "delete": "fs.files", - "deletes": [ - { - "q": { - "_id": { - "$oid": "000000000000000000000004" - } - }, - "limit": 1 - } - ] - } - ] - }, - "act": { - "operation": "delete", - "arguments": { - "id": { - "$oid": "000000000000000000000004" - } - } - }, - "assert": { - "error": "FileNotFound", - "data": [ - { - "delete": "expected.files", - "deletes": [ - { - "q": { - "_id": { - "$oid": "000000000000000000000004" - } - }, - "limit": 1 - } - ] - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/gridfs/download.json b/lib/mongoc/libmongoc/tests/json/gridfs/download.json deleted file mode 100644 index 5092fba981ad0e38dbf2415fa4400d8e51134491..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/gridfs/download.json +++ /dev/null @@ -1,467 +0,0 @@ -{ - "data": { - "files": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "length": 0, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "d41d8cd98f00b204e9800998ecf8427e", - "filename": "length-0", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000002" - }, - "length": 0, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "d41d8cd98f00b204e9800998ecf8427e", - "filename": "length-0-with-empty-chunk", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000003" - }, - "length": 2, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "c700ed4fdb1d27055aa3faa2c2432283", - "filename": "length-2", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000004" - }, - "length": 8, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "dd254cdc958e53abaa67da9f797125f5", - "filename": "length-8", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000005" - }, - "length": 10, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "57d83cd477bfb1ccd975ab33d827a92b", - "filename": "length-10", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000006" - }, - "length": 2, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "c700ed4fdb1d27055aa3faa2c2432283", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - } - ], - "chunks": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "files_id": { - "$oid": "000000000000000000000002" - }, - "n": 0, - "data": { - "$hex": "" - } - }, - { - "_id": { - "$oid": "000000000000000000000002" - }, - "files_id": { - "$oid": "000000000000000000000003" - }, - "n": 0, - "data": { - "$hex": "1122" - } - }, - { - "_id": { - "$oid": "000000000000000000000003" - }, - "files_id": { - "$oid": "000000000000000000000004" - }, - "n": 0, - "data": { - "$hex": "11223344" - } - }, - { - "_id": { - "$oid": "000000000000000000000004" - }, - "files_id": { - "$oid": "000000000000000000000004" - }, - "n": 1, - "data": { - "$hex": "55667788" - } - }, - { - "_id": { - "$oid": "000000000000000000000005" - }, - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 0, - "data": { - "$hex": "11223344" - } - }, - { - "_id": { - "$oid": "000000000000000000000006" - }, - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 1, - "data": { - "$hex": "55667788" - } - }, - { - "_id": { - "$oid": "000000000000000000000007" - }, - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 2, - "data": { - "$hex": "99aa" - } - }, - { - "_id": { - "$oid": "000000000000000000000008" - }, - "files_id": { - "$oid": "000000000000000000000006" - }, - "n": 0, - "data": { - "$hex": "1122" - } - } - ] - }, - "tests": [ - { - "description": "Download when length is zero", - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - }, - "options": {} - } - }, - "assert": { - "result": { - "$hex": "" - } - } - }, - { - "description": "Download when length is zero and there is one empty chunk", - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000002" - }, - "options": {} - } - }, - "assert": { - "result": { - "$hex": "" - } - } - }, - { - "description": "Download when there is one chunk", - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000003" - }, - "options": {} - } - }, - "assert": { - "result": { - "$hex": "1122" - } - } - }, - { - "description": "Download when there are two chunks", - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000004" - }, - "options": {} - } - }, - "assert": { - "result": { - "$hex": "1122334455667788" - } - } - }, - { - "description": "Download when there are three chunks", - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000005" - }, - "options": {} - } - }, - "assert": { - "result": { - "$hex": "112233445566778899aa" - } - } - }, - { - "description": "Download when files entry does not exist", - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000000" - }, - "options": {} - } - }, - "assert": { - "error": "FileNotFound" - } - }, - { - "description": "Download when an intermediate chunk is missing", - "arrange": { - "data": [ - { - "delete": "fs.chunks", - "deletes": [ - { - "q": { - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 1 - }, - "limit": 1 - } - ] - } - ] - }, - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000005" - } - } - }, - "assert": { - "error": "ChunkIsMissing" - } - }, - { - "description": "Download when final chunk is missing", - "arrange": { - "data": [ - { - "delete": "fs.chunks", - "deletes": [ - { - "q": { - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 1 - }, - "limit": 1 - } - ] - } - ] - }, - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000005" - } - } - }, - "assert": { - "error": "ChunkIsMissing" - } - }, - { - "description": "Download when an intermediate chunk is the wrong size", - "arrange": { - "data": [ - { - "update": "fs.chunks", - "updates": [ - { - "q": { - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 1 - }, - "u": { - "$set": { - "data": { - "$hex": "556677" - } - } - } - }, - { - "q": { - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 2 - }, - "u": { - "$set": { - "data": { - "$hex": "8899aa" - } - } - } - } - ] - } - ] - }, - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000005" - } - } - }, - "assert": { - "error": "ChunkIsWrongSize" - } - }, - { - "description": "Download when final chunk is the wrong size", - "arrange": { - "data": [ - { - "update": "fs.chunks", - "updates": [ - { - "q": { - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 2 - }, - "u": { - "$set": { - "data": { - "$hex": "99" - } - } - } - } - ] - } - ] - }, - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000005" - } - } - }, - "assert": { - "error": "ChunkIsWrongSize" - } - }, - { - "description": "Download legacy file with no name", - "act": { - "operation": "download", - "arguments": { - "id": { - "$oid": "000000000000000000000006" - }, - "options": {} - } - }, - "assert": { - "result": { - "$hex": "1122" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/gridfs/download_by_name.json b/lib/mongoc/libmongoc/tests/json/gridfs/download_by_name.json deleted file mode 100644 index ecc8c9e2ccae2f4117f5cfde7316ecff43b5761a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/gridfs/download_by_name.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "data": { - "files": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "md5": "47ed733b8d10be225eceba344d533586", - "filename": "abc", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000002" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-02T00:00:00.000Z" - }, - "md5": "b15835f133ff2e27c7cb28117bfae8f4", - "filename": "abc", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000003" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-03T00:00:00.000Z" - }, - "md5": "eccbc87e4b5ce2fe28308fd9f2a7baf3", - "filename": "abc", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000004" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-04T00:00:00.000Z" - }, - "md5": "f623e75af30e62bbd73d6df5b50bb7b5", - "filename": "abc", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - }, - { - "_id": { - "$oid": "000000000000000000000005" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-05T00:00:00.000Z" - }, - "md5": "4c614360da93c0a041b22e537de151eb", - "filename": "abc", - "contentType": "application/octet-stream", - "aliases": [], - "metadata": {} - } - ], - "chunks": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "files_id": { - "$oid": "000000000000000000000001" - }, - "n": 0, - "data": { - "$hex": "11" - } - }, - { - "_id": { - "$oid": "000000000000000000000002" - }, - "files_id": { - "$oid": "000000000000000000000002" - }, - "n": 0, - "data": { - "$hex": "22" - } - }, - { - "_id": { - "$oid": "000000000000000000000003" - }, - "files_id": { - "$oid": "000000000000000000000003" - }, - "n": 0, - "data": { - "$hex": "33" - } - }, - { - "_id": { - "$oid": "000000000000000000000004" - }, - "files_id": { - "$oid": "000000000000000000000004" - }, - "n": 0, - "data": { - "$hex": "44" - } - }, - { - "_id": { - "$oid": "000000000000000000000005" - }, - "files_id": { - "$oid": "000000000000000000000005" - }, - "n": 0, - "data": { - "$hex": "55" - } - } - ] - }, - "tests": [ - { - "description": "Download_by_name when revision is 0", - "act": { - "operation": "download_by_name", - "arguments": { - "filename": "abc", - "options": { - "revision": 0 - } - } - }, - "assert": { - "result": { - "$hex": "11" - } - } - }, - { - "description": "Download_by_name when revision is 1", - "act": { - "operation": "download_by_name", - "arguments": { - "filename": "abc", - "options": { - "revision": 1 - } - } - }, - "assert": { - "result": { - "$hex": "22" - } - } - }, - { - "description": "Download_by_name when revision is -2", - "act": { - "operation": "download_by_name", - "arguments": { - "filename": "abc", - "options": { - "revision": -2 - } - } - }, - "assert": { - "result": { - "$hex": "44" - } - } - }, - { - "description": "Download_by_name when revision is -1", - "act": { - "operation": "download_by_name", - "arguments": { - "filename": "abc", - "options": { - "revision": -1 - } - } - }, - "assert": { - "result": { - "$hex": "55" - } - } - }, - { - "description": "Download_by_name when files entry does not exist", - "act": { - "operation": "download_by_name", - "arguments": { - "filename": "xyz" - } - }, - "assert": { - "error": "FileNotFound" - } - }, - { - "description": "Download_by_name when revision does not exist", - "act": { - "operation": "download_by_name", - "arguments": { - "filename": "abc", - "options": { - "revision": 999 - } - } - }, - "assert": { - "error": "RevisionNotFound" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/gridfs/upload.json b/lib/mongoc/libmongoc/tests/json/gridfs/upload.json deleted file mode 100644 index ecec0c548842072518461b63cf7cf4db7204ca5f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/gridfs/upload.json +++ /dev/null @@ -1,466 +0,0 @@ -{ - "data": { - "files": [], - "chunks": [] - }, - "tests": [ - { - "description": "Upload when length is 0", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "" - }, - "options": { - "chunkSizeBytes": 4 - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 0, - "chunkSize": 4, - "uploadDate": "*actual", - "md5": "d41d8cd98f00b204e9800998ecf8427e", - "filename": "filename" - } - ] - } - ] - } - }, - { - "description": "Upload when length is 1", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "11" - }, - "options": { - "chunkSizeBytes": 4 - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 1, - "chunkSize": 4, - "uploadDate": "*actual", - "md5": "47ed733b8d10be225eceba344d533586", - "filename": "filename" - } - ] - }, - { - "insert": "expected.chunks", - "documents": [ - { - "_id": "*actual", - "files_id": "*result", - "n": 0, - "data": { - "$hex": "11" - } - } - ] - } - ] - } - }, - { - "description": "Upload when length is 3", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "112233" - }, - "options": { - "chunkSizeBytes": 4 - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 3, - "chunkSize": 4, - "uploadDate": "*actual", - "md5": "bafae3a174ab91fc70db7a6aa50f4f52", - "filename": "filename" - } - ] - }, - { - "insert": "expected.chunks", - "documents": [ - { - "_id": "*actual", - "files_id": "*result", - "n": 0, - "data": { - "$hex": "112233" - } - } - ] - } - ] - } - }, - { - "description": "Upload when length is 4", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "11223344" - }, - "options": { - "chunkSizeBytes": 4 - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 4, - "chunkSize": 4, - "uploadDate": "*actual", - "md5": "7e7c77cff5705d1f7574a25ef6662117", - "filename": "filename" - } - ] - }, - { - "insert": "expected.chunks", - "documents": [ - { - "_id": "*actual", - "files_id": "*result", - "n": 0, - "data": { - "$hex": "11223344" - } - } - ] - } - ] - } - }, - { - "description": "Upload when length is 5", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "1122334455" - }, - "options": { - "chunkSizeBytes": 4 - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 5, - "chunkSize": 4, - "uploadDate": "*actual", - "md5": "283d4fea5dded59cf837d3047328f5af", - "filename": "filename" - } - ] - }, - { - "insert": "expected.chunks", - "documents": [ - { - "_id": "*actual", - "files_id": "*result", - "n": 0, - "data": { - "$hex": "11223344" - } - }, - { - "_id": "*actual", - "files_id": "*result", - "n": 1, - "data": { - "$hex": "55" - } - } - ] - } - ] - } - }, - { - "description": "Upload when length is 8", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "1122334455667788" - }, - "options": { - "chunkSizeBytes": 4 - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 8, - "chunkSize": 4, - "uploadDate": "*actual", - "md5": "dd254cdc958e53abaa67da9f797125f5", - "filename": "filename" - } - ] - }, - { - "insert": "expected.chunks", - "documents": [ - { - "_id": "*actual", - "files_id": "*result", - "n": 0, - "data": { - "$hex": "11223344" - } - }, - { - "_id": "*actual", - "files_id": "*result", - "n": 1, - "data": { - "$hex": "55667788" - } - } - ] - } - ] - } - }, - { - "description": "Upload when contentType is provided", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "11" - }, - "options": { - "chunkSizeBytes": 4, - "contentType": "image/jpeg" - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 1, - "chunkSize": 4, - "uploadDate": "*actual", - "md5": "47ed733b8d10be225eceba344d533586", - "filename": "filename", - "contentType": "image/jpeg" - } - ] - }, - { - "insert": "expected.chunks", - "documents": [ - { - "_id": "*actual", - "files_id": "*result", - "n": 0, - "data": { - "$hex": "11" - } - } - ] - } - ] - } - }, - { - "description": "Upload when metadata is provided", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "11" - }, - "options": { - "chunkSizeBytes": 4, - "metadata": { - "x": 1 - } - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 1, - "chunkSize": 4, - "uploadDate": "*actual", - "md5": "47ed733b8d10be225eceba344d533586", - "filename": "filename", - "metadata": { - "x": 1 - } - } - ] - }, - { - "insert": "expected.chunks", - "documents": [ - { - "_id": "*actual", - "files_id": "*result", - "n": 0, - "data": { - "$hex": "11" - } - } - ] - } - ] - } - }, - { - "description": "Upload when length is 0 sans MD5", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "" - }, - "options": { - "chunkSizeBytes": 4, - "disableMD5": true - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 0, - "chunkSize": 4, - "uploadDate": "*actual", - "filename": "filename" - } - ] - } - ] - } - }, - { - "description": "Upload when length is 1 sans MD5", - "act": { - "operation": "upload", - "arguments": { - "filename": "filename", - "source": { - "$hex": "11" - }, - "options": { - "chunkSizeBytes": 4, - "disableMD5": true - } - } - }, - "assert": { - "result": "&result", - "data": [ - { - "insert": "expected.files", - "documents": [ - { - "_id": "*result", - "length": 1, - "chunkSize": 4, - "uploadDate": "*actual", - "filename": "filename" - } - ] - }, - { - "insert": "expected.chunks", - "documents": [ - { - "_id": "*actual", - "files_id": "*result", - "n": 0, - "data": { - "$hex": "11" - } - } - ] - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_auth/README b/lib/mongoc/libmongoc/tests/json/initial_dns_auth/README deleted file mode 100644 index bc47c618544429a352a2ab435286384e0661f06a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_auth/README +++ /dev/null @@ -1,7 +0,0 @@ -This test substitutes for the spec test here: - -https://github.com/mongodb/specifications/blob/master/source/initial-dns-seedlist-discovery/tests/uri-with-auth.json - -Since our Mongo Orchestration configurations set username and password to -"bob:pwd123", it's easier to test with that username and password than the -"auser:apass" user in the official spec test. See CDRIVER-2868. diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_auth/dns-auth.json b/lib/mongoc/libmongoc/tests/json/initial_dns_auth/dns-auth.json deleted file mode 100644 index d907c54c86f8072078d415bfdbcaee34bce4a8f7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_auth/dns-auth.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "uri": "mongodb+srv://bob:pwd123@test5.test.build.10gen.cc/", - "seeds": [ - "localhost.test.build.10gen.cc:27017" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "authSource": "thisDB", - "ssl": true - } -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/longer-parent-in-return.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/longer-parent-in-return.json deleted file mode 100644 index 9a8267eaeb13fac03f98884fe56a9261732b20f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/longer-parent-in-return.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "uri": "mongodb+srv://test18.test.build.10gen.cc/?replicaSet=repl0", - "seeds": [ - "localhost.sub.test.build.10gen.cc:27017" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "ssl": true - }, - "comment": "Is correct, as returned host name shared the URI root \"test.build.10gen.cc\"." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/misformatted-option.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/misformatted-option.json deleted file mode 100644 index 3c8c29ace68c95e657ab40e09c939c81cd63a72b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/misformatted-option.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test8.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because the options in the TXT record are incorrectly formatted (misses value)." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/no-results.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/no-results.json deleted file mode 100644 index c1dc02d281d3130f86320201abd5f8b3cb66a924..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/no-results.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test4.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because no SRV records are present for this URI." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/not-enough-parts.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/not-enough-parts.json deleted file mode 100644 index 7cfce2ec57ef74da97172c7093a4e255ea79d2bc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/not-enough-parts.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because host in URI does not have {hostname}, {domainname} and {tld}." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-result-default-port.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-result-default-port.json deleted file mode 100644 index cebb3b1ec32052b15cd017ad7692493177b1b450..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-result-default-port.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "uri": "mongodb+srv://test3.test.build.10gen.cc/?replicaSet=repl0", - "seeds": [ - "localhost.test.build.10gen.cc:27017" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "ssl": true - } -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-txt-record-multiple-strings.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-txt-record-multiple-strings.json deleted file mode 100644 index 622668c351faf756fb4c5181627f83ea77a24a0d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-txt-record-multiple-strings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "uri": "mongodb+srv://test11.test.build.10gen.cc/", - "seeds": [ - "localhost.test.build.10gen.cc:27017" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "ssl": true - } -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-txt-record.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-txt-record.json deleted file mode 100644 index 2385021ad4b3464c2d9b618ad900bfbec57f2a15..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/one-txt-record.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "uri": "mongodb+srv://test5.test.build.10gen.cc/", - "seeds": [ - "localhost.test.build.10gen.cc:27017" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "authSource": "thisDB", - "ssl": true - } -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch1.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch1.json deleted file mode 100644 index 8d0147a48b8513d131649f9ad1e5bfa541aae3f7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test14.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because returned host name's part \"not-test\" mismatches URI parent part \"test\"." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch2.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch2.json deleted file mode 100644 index 996249eb99d53a654b9650d4d50a4598738d4fcd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch2.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test15.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because returned host name's part \"not-build\" mismatches URI parent part \"build\"." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch3.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch3.json deleted file mode 100644 index 69e724af6c704b97ed63f4d096231f4cf6394936..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch3.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test16.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because returned host name's part \"not-10gen\" mismatches URI parent part \"10gen\"." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch4.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch4.json deleted file mode 100644 index 254168e34caa32381ccc57022af0515970d61c1a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch4.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test17.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because returned host name's TLD \"not-cc\" mismatches URI TLD \"cc\"." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch5.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch5.json deleted file mode 100644 index 92c024b4f342f9c90760617f5499fe164d16fab9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/parent-part-mismatch5.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test19.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because one of the returned host names' domain name parts \"evil\" mismatches \"test\"." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/returned-parent-too-short.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/returned-parent-too-short.json deleted file mode 100644 index 676eb0c0d09ccb309eb37063d1ef615ab20f2c2b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/returned-parent-too-short.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test13.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because returned host name's parent (build.10gen.cc) misses \"test.\"" -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/returned-parent-wrong.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/returned-parent-wrong.json deleted file mode 100644 index 3aabfd81962a0a5985fb35c2af3fe4860211c60f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/returned-parent-wrong.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test12.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because returned host name is too short and mismatches a parent." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-results-default-port.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-results-default-port.json deleted file mode 100644 index 66028310a6d99a4c434cdf7a788248a53ba95e12..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-results-default-port.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "uri": "mongodb+srv://test1.test.build.10gen.cc/?replicaSet=repl0", - "seeds": [ - "localhost.test.build.10gen.cc:27017", - "localhost.test.build.10gen.cc:27018" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "ssl": true - } -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-results-nonstandard-port.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-results-nonstandard-port.json deleted file mode 100644 index 4900f7cff1c922c5817e2c201b208de5ea34b18f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-results-nonstandard-port.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "uri": "mongodb+srv://test2.test.build.10gen.cc/?replicaSet=repl0", - "seeds": [ - "localhost.test.build.10gen.cc:27018", - "localhost.test.build.10gen.cc:27019" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "ssl": true - } -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-txt-records.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-txt-records.json deleted file mode 100644 index f0654ef6cb211228961769abd34e5f93389d5106..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/two-txt-records.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test6.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because there are two TXT records." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-not-allowed-option.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-not-allowed-option.json deleted file mode 100644 index 2a5cf2f007085b1a76bcc8a1dd54b60d477a58e9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-not-allowed-option.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test10.test.build.10gen.cc/?replicaSet=repl0", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because socketTimeoutMS is not an allowed option." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-overridden-ssl-option.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-overridden-ssl-option.json deleted file mode 100644 index 0ebc737bd5facdc0dc1b940b5cfc966272d58933..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-overridden-ssl-option.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "uri": "mongodb+srv://test5.test.build.10gen.cc/?ssl=false", - "seeds": [ - "localhost.test.build.10gen.cc:27017" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "authSource": "thisDB", - "ssl": false - } -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-overridden-uri-option.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-overridden-uri-option.json deleted file mode 100644 index 59814b9da0f37691c291cb6065949e2097c0a4b5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-overridden-uri-option.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "uri": "mongodb+srv://test5.test.build.10gen.cc/?authSource=otherDB", - "seeds": [ - "localhost.test.build.10gen.cc:27017" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "authSource": "otherDB", - "ssl": true - }, - "error": true, - "comment": "invalid URI (see SPEC-1424)" -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-unallowed-option.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-unallowed-option.json deleted file mode 100644 index 0d333a459ddee17af06022162fb233c8e8c452fd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/txt-record-with-unallowed-option.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test7.test.build.10gen.cc/", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because \"ssl\" is not an allowed option." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-admin-database.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-admin-database.json deleted file mode 100644 index 32710d75f774a3446fbc4b71fbf6330824052cbe..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-admin-database.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "uri": "mongodb+srv://test1.test.build.10gen.cc/adminDB?replicaSet=repl0", - "seeds": [ - "localhost.test.build.10gen.cc:27017", - "localhost.test.build.10gen.cc:27018" - ], - "hosts": [ - "localhost:27017", - "localhost:27018", - "localhost:27019" - ], - "options": { - "replicaSet": "repl0", - "ssl": true - }, - "parsed_options": { - "auth_database": "adminDB" - } -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-port.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-port.json deleted file mode 100644 index b981e2a1bfc3ee6e24ead531544bd8d3a355c61f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-port.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test5.test.build.10gen.cc:8123/?replicaSet=repl0", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because the mongodb+srv URI includes a port." -} diff --git a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-two-hosts.json b/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-two-hosts.json deleted file mode 100644 index 5261a39cfa7ef73d2f4db4114e8fc61fb3348246..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/initial_dns_seedlist_discovery/uri-with-two-hosts.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "uri": "mongodb+srv://test5.test.build.10gen.cc,test6.test.build.10gen.cc/?replicaSet=repl0", - "seeds": [], - "hosts": [], - "error": true, - "comment": "Should fail because the mongodb+srv URI includes two host names." -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.json deleted file mode 100644 index 1e3dd0bfd94a24d5909cd9e9c47e1c839b7f95f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest" - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Incompatible.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Incompatible.json deleted file mode 100644 index 7f9fa764c7cce82f7226faaa0425683fdf7d1904..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Incompatible.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 4, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 120 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.json deleted file mode 100644 index e1abef2844b7dadd7fc28ac783ebbbe9ba2a5798..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 1, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 25002, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 25001, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5 - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 150 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 1, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 25002, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 1, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Nearest.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Nearest.json deleted file mode 100644 index 53549e64317ea1fe059c7196016cf3e4aa0e6c78..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Nearest.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - }, - { - "address": "c:27017", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "type": "RSSecondary", - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5 - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 150 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Nearest2.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Nearest2.json deleted file mode 100644 index e2768c7fb8a8626f86c66aceef885ab6ac84fea8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Nearest2.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - }, - { - "address": "c:27017", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "type": "RSSecondary", - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5 - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 150 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/NoKnownServers.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/NoKnownServers.json deleted file mode 100644 index 28e5e2aa4a5d46bd5aa7eeb9a92e8b8146e2564a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/NoKnownServers.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "Unknown" - }, - { - "address": "b:27017", - "type": "Unknown" - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 1 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.json deleted file mode 100644 index 8c6be6886a798611bdff45c8d8f119f8a6b6e422..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "PrimaryPreferred", - "maxStalenessSeconds": 90 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.json deleted file mode 100644 index 26007c026ee3240b066e61376b38ce325a66c9c9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "nyc" - } - } - ] - }, - "read_preference": { - "mode": "PrimaryPreferred", - "maxStalenessSeconds": 150, - "tag_sets": [ - { - "data_center": "nyc" - }, - { - "data_center": "tokyo" - } - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Secondary.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Secondary.json deleted file mode 100644 index 7d5eb58f4da91d5041b15991c4811de0287d0d2a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/Secondary.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "tags": { - "data_center": "tokyo" - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "d:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "tokyo" - } - } - ] - }, - "read_preference": { - "mode": "Secondary", - "maxStalenessSeconds": 150, - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.json deleted file mode 100644 index df0bb5d77f04d47170b7d9723dbe3665da421da3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "SecondaryPreferred", - "maxStalenessSeconds": 120 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.json deleted file mode 100644 index 1ac3ea0aed999a046ce80d4569949da8f985640a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "tags": { - "data_center": "tokyo" - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "d:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "tokyo" - } - } - ] - }, - "read_preference": { - "mode": "SecondaryPreferred", - "maxStalenessSeconds": 150, - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.json deleted file mode 100644 index cb5dc5175a9cedaad8db4bb2566dcbb2d15f35b4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 4, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 0 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.json deleted file mode 100644 index ed18d5837ecff439f2525ca9f771033665146df8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest" - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Incompatible.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Incompatible.json deleted file mode 100644 index d27ea11202c1f31d11454dec22c0409118257f65..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Incompatible.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 4, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 120 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.json deleted file mode 100644 index bbd8238e8a9746f54e149f80e4fe01df0d1524f7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 50, - "lastUpdateTime": 1, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 125001, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 125001, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5 - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 150 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 50, - "lastUpdateTime": 1, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 125001, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 125001, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.json deleted file mode 100644 index cb05f52aa2681883e6abadda4cb43e50606ec84d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "heartbeatFrequencyMS": 120000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 130 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.json deleted file mode 100644 index be169a3dcb6f12170a23c562a1aa6e7a33f77464..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "heartbeatFrequencyMS": 120000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 129 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.json deleted file mode 100644 index 173f5742a20711416415a1bb7b833b9fc473d9e9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "heartbeatFrequencyMS": 500, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 89 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.json deleted file mode 100644 index eee346278318f2c8218f35def05eb9e5d5f7d3cf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "maxStalenessSeconds": 120 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest.json deleted file mode 100644 index 753fb82ca3215f598cd92eb4bb9c13b9ea8dc45c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - }, - { - "address": "c:27017", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "type": "RSSecondary", - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5 - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 150 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest2.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest2.json deleted file mode 100644 index 6233c0815aa945becf55d89e8b5ec99b47ff1914..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest2.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - }, - { - "address": "c:27017", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "type": "RSSecondary", - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5 - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 150 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5 - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest_tags.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest_tags.json deleted file mode 100644 index 9a1cd3bb124252f67e5c36e2454e4a1d464c676e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Nearest_tags.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "nyc" - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 150, - "tag_sets": [ - { - "data_center": "nyc" - }, - { - "data_center": "tokyo" - } - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.json deleted file mode 100644 index 107ae2755e29be9a3809c2216c705f422bbc77d6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "PrimaryPreferred", - "maxStalenessSeconds": 150 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.json deleted file mode 100644 index a6681f6a13044425f4448de664cf8d5a01e8333a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 4, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "PrimaryPreferred", - "maxStalenessSeconds": 150 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.json deleted file mode 100644 index 5f8a21f15c94203efa024d4f6a5f8c637fc50637..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "SecondaryPreferred", - "maxStalenessSeconds": 120 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.json deleted file mode 100644 index 09ce6d6bd0a854433f67cbc06df2758ffb335c38..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 1, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "d:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "e:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "tokyo" - } - } - ] - }, - "read_preference": { - "mode": "SecondaryPreferred", - "maxStalenessSeconds": 150, - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 1, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - }, - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.json deleted file mode 100644 index 3700c30453e7046855c241413d6be5ec293718b5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "nyc" - } - } - ] - }, - "read_preference": { - "mode": "SecondaryPreferred", - "maxStalenessSeconds": 150, - "tag_sets": [ - { - "data_center": "nyc" - }, - { - "data_center": "tokyo" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Secondary_tags.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Secondary_tags.json deleted file mode 100644 index f117159f64dd1679afb7563f5e3fb3a6b2f91242..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Secondary_tags.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 1, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "d:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "e:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "tokyo" - } - } - ] - }, - "read_preference": { - "mode": "Secondary", - "maxStalenessSeconds": 150, - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 50, - "lastUpdateTime": 1, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1000001" - } - }, - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.json deleted file mode 100644 index b739c6141bfce488456fc5013798113580e0c435..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "heartbeatFrequencyMS": 25000, - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "125002" - } - }, - "maxWireVersion": 5 - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - }, - { - "address": "c:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "nyc" - } - } - ] - }, - "read_preference": { - "mode": "Secondary", - "maxStalenessSeconds": 150, - "tag_sets": [ - { - "data_center": "nyc" - }, - { - "data_center": "tokyo" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - }, - "maxWireVersion": 5, - "tags": { - "data_center": "tokyo" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.json b/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.json deleted file mode 100644 index f17aa93a3fbc7805bd4b0414c76848f6bfb446a2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "type": "RSPrimary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "2" - } - } - }, - { - "address": "b:27017", - "type": "RSSecondary", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 4, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 0 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/Sharded/Incompatible.json b/lib/mongoc/libmongoc/tests/json/max_staleness/Sharded/Incompatible.json deleted file mode 100644 index c261383f4a6c7a35c297c39d7bdb50d5620dedab..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/Sharded/Incompatible.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "a:27017", - "type": "Mongos", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "Mongos", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 4, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 120 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/Sharded/SmallMaxStaleness.json b/lib/mongoc/libmongoc/tests/json/max_staleness/Sharded/SmallMaxStaleness.json deleted file mode 100644 index 27b9f1c12fd1259babb952a85d56b0757afe86d6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/Sharded/SmallMaxStaleness.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "heartbeatFrequencyMS": 10000, - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "a:27017", - "type": "Mongos", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "Mongos", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 1 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "Mongos", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - }, - { - "address": "b:27017", - "type": "Mongos", - "avg_rtt_ms": 50, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "Mongos", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/Single/Incompatible.json b/lib/mongoc/libmongoc/tests/json/max_staleness/Single/Incompatible.json deleted file mode 100644 index b37fec7c1acfcbc440b40369ab446661414c118f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/Single/Incompatible.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "topology_description": { - "type": "Single", - "servers": [ - { - "address": "a:27017", - "type": "Standalone", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 4, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 120 - }, - "error": true -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/Single/SmallMaxStaleness.json b/lib/mongoc/libmongoc/tests/json/max_staleness/Single/SmallMaxStaleness.json deleted file mode 100644 index c6b10231b87e84f6c4e59d0013575ea9df730cc6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/Single/SmallMaxStaleness.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "heartbeatFrequencyMS": 10000, - "topology_description": { - "type": "Single", - "servers": [ - { - "address": "a:27017", - "type": "Standalone", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 1 - }, - "suitable_servers": [ - { - "address": "a:27017", - "type": "Standalone", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "type": "Standalone", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "lastWrite": { - "lastWriteDate": { - "$numberLong": "1" - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/Unknown/SmallMaxStaleness.json b/lib/mongoc/libmongoc/tests/json/max_staleness/Unknown/SmallMaxStaleness.json deleted file mode 100644 index bf6174b8e4d9aa61f49cc9e361ac542c4b53a9aa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/Unknown/SmallMaxStaleness.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "heartbeatFrequencyMS": 10000, - "topology_description": { - "type": "Unknown", - "servers": [ - { - "address": "a:27017", - "type": "Unknown", - "maxWireVersion": 5 - } - ] - }, - "read_preference": { - "mode": "Nearest", - "maxStalenessSeconds": 1 - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/max_staleness/supplemental/MissingLastWriteDate.json b/lib/mongoc/libmongoc/tests/json/max_staleness/supplemental/MissingLastWriteDate.json deleted file mode 100644 index b64ee0379d2b9600aba70a1c4a9cc25ce0f3a3e5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/max_staleness/supplemental/MissingLastWriteDate.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "error": true, - "read_preference": { - "maxStalenessSeconds": 120, - "mode": "Nearest" - }, - "topology_description": { - "servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "lastUpdateTime": 0, - "maxWireVersion": 5, - "type": "RSSecondary" - } - ], - "type": "ReplicaSetNoPrimary" - } -} diff --git a/lib/mongoc/libmongoc/tests/json/read_write_concern/connection-string/read-concern.json b/lib/mongoc/libmongoc/tests/json/read_write_concern/connection-string/read-concern.json deleted file mode 100644 index 1ecad8c268db65bf059624ab32d5625ee976fc87..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/read_write_concern/connection-string/read-concern.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "tests": [ - { - "description": "Default", - "uri": "mongodb://localhost/", - "valid": true, - "warning": false, - "readConcern": {} - }, - { - "description": "local specified", - "uri": "mongodb://localhost/?readConcernLevel=local", - "valid": true, - "warning": false, - "readConcern": { - "level": "local" - } - }, - { - "description": "majority specified", - "uri": "mongodb://localhost/?readConcernLevel=majority", - "valid": true, - "warning": false, - "readConcern": { - "level": "majority" - } - }, - { - "description": "linearizable specified", - "uri": "mongodb://localhost/?readConcernLevel=linearizable", - "valid": true, - "warning": false, - "readConcern": { - "level": "linearizable" - } - }, - { - "description": "available specified", - "uri": "mongodb://localhost/?readConcernLevel=available", - "valid": true, - "warning": false, - "readConcern": { - "level": "available" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/read_write_concern/connection-string/write-concern.json b/lib/mongoc/libmongoc/tests/json/read_write_concern/connection-string/write-concern.json deleted file mode 100644 index 51bdf821c34acab5c66392b93770af7d23d408ca..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/read_write_concern/connection-string/write-concern.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "tests": [ - { - "description": "Default", - "uri": "mongodb://localhost/", - "valid": true, - "warning": false, - "writeConcern": {} - }, - { - "description": "w as a valid number", - "uri": "mongodb://localhost/?w=1", - "valid": true, - "warning": false, - "writeConcern": { - "w": 1 - } - }, - { - "description": "w as an invalid number", - "uri": "mongodb://localhost/?w=-2", - "valid": false, - "warning": null - }, - { - "description": "w as a string", - "uri": "mongodb://localhost/?w=majority", - "valid": true, - "warning": false, - "writeConcern": { - "w": "majority" - } - }, - { - "description": "wtimeoutMS as a valid number", - "uri": "mongodb://localhost/?wtimeoutMS=500", - "valid": true, - "warning": false, - "writeConcern": { - "wtimeoutMS": 500 - } - }, - { - "description": "wtimeoutMS as an invalid number", - "uri": "mongodb://localhost/?wtimeoutMS=-500", - "valid": false, - "warning": null - }, - { - "description": "journal as false", - "uri": "mongodb://localhost/?journal=false", - "valid": true, - "warning": false, - "writeConcern": { - "journal": false - } - }, - { - "description": "journal as true", - "uri": "mongodb://localhost/?journal=true", - "valid": true, - "warning": false, - "writeConcern": { - "journal": true - } - }, - { - "description": "All options combined", - "uri": "mongodb://localhost/?w=3&wtimeoutMS=500&journal=true", - "valid": true, - "warning": false, - "writeConcern": { - "w": 3, - "wtimeoutMS": 500, - "journal": true - } - }, - { - "description": "Unacknowledged with w", - "uri": "mongodb://localhost/?w=0", - "valid": true, - "warning": false, - "writeConcern": { - "w": 0 - } - }, - { - "description": "Unacknowledged with w and journal", - "uri": "mongodb://localhost/?w=0&journal=false", - "valid": true, - "warning": false, - "writeConcern": { - "w": 0, - "journal": false - } - }, - { - "description": "Unacknowledged with w and wtimeoutMS", - "uri": "mongodb://localhost/?w=0&wtimeoutMS=500", - "valid": true, - "warning": false, - "writeConcern": { - "w": 0, - "wtimeoutMS": 500 - } - }, - { - "description": "Acknowledged with w as 0 and journal true", - "uri": "mongodb://localhost/?w=0&journal=true", - "valid": false, - "warning": false, - "writeConcern": { - "w": 0, - "journal": true - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/read_write_concern/document/read-concern.json b/lib/mongoc/libmongoc/tests/json/read_write_concern/document/read-concern.json deleted file mode 100644 index 187397dae5790709abe93e56b301ff02aa192dee..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/read_write_concern/document/read-concern.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "tests": [ - { - "description": "Default", - "valid": true, - "readConcern": {}, - "readConcernDocument": {}, - "isServerDefault": true - }, - { - "description": "Majority", - "valid": true, - "readConcern": { - "level": "majority" - }, - "readConcernDocument": { - "level": "majority" - }, - "isServerDefault": false - }, - { - "description": "Local", - "valid": true, - "readConcern": { - "level": "local" - }, - "readConcernDocument": { - "level": "local" - }, - "isServerDefault": false - }, - { - "description": "Linearizable", - "valid": true, - "readConcern": { - "level": "linearizable" - }, - "readConcernDocument": { - "level": "linearizable" - }, - "isServerDefault": false - }, - { - "description": "Snapshot", - "valid": true, - "readConcern": { - "level": "snapshot" - }, - "readConcernDocument": { - "level": "snapshot" - }, - "isServerDefault": false - }, - { - "description": "Available", - "valid": true, - "readConcern": { - "level": "available" - }, - "readConcernDocument": { - "level": "available" - }, - "isServerDefault": false - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/read_write_concern/document/write-concern.json b/lib/mongoc/libmongoc/tests/json/read_write_concern/document/write-concern.json deleted file mode 100644 index 64cd5d0eae27f3bd097a6f339081130073d15ec2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/read_write_concern/document/write-concern.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "tests": [ - { - "description": "Default", - "valid": true, - "writeConcern": {}, - "writeConcernDocument": {}, - "isServerDefault": true, - "isAcknowledged": true - }, - { - "description": "W as a number", - "valid": true, - "writeConcern": { - "w": 3 - }, - "writeConcernDocument": { - "w": 3 - }, - "isServerDefault": false, - "isAcknowledged": true - }, - { - "description": "W as an invalid number", - "valid": false, - "writeConcern": { - "w": -3 - }, - "writeConcernDocument": null, - "isServerDefault": null, - "isAcknowledged": null - }, - { - "description": "W as majority", - "valid": true, - "writeConcern": { - "w": "majority" - }, - "writeConcernDocument": { - "w": "majority" - }, - "isServerDefault": false, - "isAcknowledged": true - }, - { - "description": "W as a custom string", - "valid": true, - "writeConcern": { - "w": "my_mode" - }, - "writeConcernDocument": { - "w": "my_mode" - }, - "isServerDefault": false, - "isAcknowledged": true - }, - { - "description": "WTimeoutMS", - "valid": true, - "writeConcern": { - "wtimeoutMS": 1000 - }, - "writeConcernDocument": { - "wtimeout": 1000 - }, - "isServerDefault": false, - "isAcknowledged": true - }, - { - "description": "WTimeoutMS as an invalid number", - "valid": false, - "writeConcern": { - "wtimeoutMS": -1000 - }, - "writeConcernDocument": null, - "isServerDefault": null, - "isAcknowledged": null - }, - { - "description": "Journal as true", - "valid": true, - "writeConcern": { - "journal": true - }, - "writeConcernDocument": { - "j": true - }, - "isServerDefault": false, - "isAcknowledged": true - }, - { - "description": "Journal as false", - "valid": true, - "writeConcern": { - "journal": false - }, - "writeConcernDocument": { - "j": false - }, - "isServerDefault": false, - "isAcknowledged": true - }, - { - "description": "Unacknowledged with only w", - "valid": true, - "writeConcern": { - "w": 0 - }, - "writeConcernDocument": { - "w": 0 - }, - "isServerDefault": false, - "isAcknowledged": false - }, - { - "description": "Unacknowledged with wtimeoutMS", - "valid": true, - "writeConcern": { - "w": 0, - "wtimeoutMS": 500 - }, - "writeConcernDocument": { - "w": 0, - "wtimeout": 500 - }, - "isServerDefault": false, - "isAcknowledged": false - }, - { - "description": "Unacknowledged with journal", - "valid": true, - "writeConcern": { - "w": 0, - "journal": false - }, - "writeConcernDocument": { - "w": 0, - "j": false - }, - "isServerDefault": false, - "isAcknowledged": false - }, - { - "description": "W is 0 with journal true", - "valid": false, - "writeConcern": { - "w": 0, - "journal": true - }, - "writeConcernDocument": { - "w": 0, - "j": true - }, - "isServerDefault": false, - "isAcknowledged": true - }, - { - "description": "Everything", - "valid": true, - "writeConcern": { - "w": 3, - "wtimeoutMS": 1000, - "journal": true - }, - "writeConcernDocument": { - "w": 3, - "wtimeout": 1000, - "j": true - }, - "isServerDefault": false, - "isAcknowledged": true - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/README.rst b/lib/mongoc/libmongoc/tests/json/retryable_reads/README.rst deleted file mode 100644 index 99636fb0413237498f80d83d873e8b8f0e73512d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/README.rst +++ /dev/null @@ -1,167 +0,0 @@ -===================== -Retryable Reads Tests -===================== - -.. contents:: - ----- - -Introduction -============ - -The YAML and JSON files in this directory tree are platform-independent tests -that drivers can use to prove their conformance to the Retryable Reads spec. - -Prose tests, which are not easily expressed in YAML, are also presented -in this file. Those tests will need to be manually implemented by each driver. - -Tests will require a MongoClient created with options defined in the tests. -Integration tests will require a running MongoDB cluster with server versions -4.0 or later. - -N.B. The spec specifies 3.6 as the minimum server version: however, -``failCommand`` is not supported on 3.6, so for now, testing requires MongoDB -4.0. Once `DRIVERS-560`_ is resolved, we will attempt to adapt its live failure -integration tests to test Retryable Reads on MongoDB 3.6. - -.. _DRIVERS-560: https://jira.mongodb.org/browse/DRIVERS-560 - -Server Fail Point -================= - -See: `Server Fail Point`_ in the Transactions spec test suite. - -.. _Server Fail Point: ../../transactions/tests#server-fail-point - -Disabling Fail Point after Test Execution ------------------------------------------ - -After each test that configures a fail point, drivers should disable the -``failCommand`` fail point to avoid spurious failures in -subsequent tests. The fail point may be disabled like so:: - - db.runCommand({ - configureFailPoint: "failCommand", - mode: "off" - }); - -Network Error Tests -=================== - -Network error tests are expressed in YAML and should be run against a standalone, -shard cluster, or single-node replica set. - - -Test Format ------------ - -Each YAML file has the following keys: - -- ``runOn`` (optional): An array of server version and/or topology requirements - for which the tests can be run. If the test environment satisfies one or more - of these requirements, the tests may be executed; otherwise, this file should - be skipped. If this field is omitted, the tests can be assumed to have no - particular requirements and should be executed. Each element will have some or - all of the following fields: - - - ``minServerVersion`` (optional): The minimum server version (inclusive) - required to successfully run the tests. If this field is omitted, it should - be assumed that there is no lower bound on the required server version. - - - ``maxServerVersion`` (optional): The maximum server version (inclusive) - against which the tests can be run successfully. If this field is omitted, - it should be assumed that there is no upper bound on the required server - version. - - - ``topology`` (optional): An array of server topologies against which the - tests can be run successfully. Valid topologies are "single", "replicaset", - and "sharded". If this field is omitted, the default is all topologies (i.e. - ``["single", "replicaset", "sharded"]``). - -- ``database_name`` and ``collection_name``: Optional. The database and - collection to use for testing. - -- ``bucket_name``: Optional. The GridFS bucket name to use for testing. - -- ``data``: The data that should exist in the collection(s) under test before - each test run. - -- ``tests``: An array of tests that are to be run independently of each other. - Each test will have some or all of the following fields: - - - ``description``: The name of the test. - - - ``clientOptions``: Optional, parameters to pass to MongoClient(). - - - ``useMultipleMongoses`` (optional): If ``true``, the MongoClient for this - test should be initialized with multiple mongos seed addresses. If ``false`` - or omitted, only a single mongos address should be specified. This field has - no effect for non-sharded topologies. - - - ``skipReason``: Optional, string describing why this test should be skipped. - - - ``failPoint``: Optional, a server fail point to enable, expressed as the - configureFailPoint command to run on the admin database. - - - ``operations``: An array of documents describing an operation to be - executed. Each document has the following fields: - - - ``name``: The name of the operation on ``object``. - - - ``object``: The name of the object to perform the operation on. Can be - "database", "collection", "client", or "gridfsbucket." - - - ``arguments``: Optional, the names and values of arguments. - - - ``result``: Optional. The return value from the operation, if any. This - field may be a scalar (e.g. in the case of a count), a single document, or - an array of documents in the case of a multi-document read. - - - ``error``: Optional. If ``true``, the test should expect an error or - exception. - - - ``expectations``: Optional list of command-started events. - -GridFS Tests ------------- - -GridFS tests are denoted by when the YAML file contains ``bucket_name``. - -``fs.files`` and ``fs.chunks`` should be created in the database -specified by ``database_name``. This could be done via inserts or by -creating GridFSBuckets—using the GridFS ``bucketName`` (see -`GridFSBucket spec`_) specified by ``bucket_name`` field in the YAML -file—and calling ``upload_from_stream_with_id`` with the appropriate -data. - -``Download`` tests should be tested against ``GridFS.download_to_stream``. -``DownloadByName`` tests should be tested against -``GridFS.download_to_stream_by_name``. - - -.. _GridFSBucket spec: https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst#configurable-gridfsbucket-class - -Speeding Up Tests ------------------ - -Drivers may benefit reducing `minHeartbeatFrequencyMS`_ in order to speed up -tests. Python was able to decrease the run time of the tests greatly by lowering -the SDAM's ``minHeartbeatFrequencyMS`` from 500ms to 50ms, thus decreasing the -waiting time after a "not master" error: - -.. _minHeartbeatFrequencyMS: https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#minheartbeatfrequencyms -Optional Enumeration Commands -============================= - -A driver only needs to test the optional enumeration commands it has chosen to -implement (e.g. ``Database.listCollectionNames()``). - -Changelog -========= - -:2019-03-19: Add top-level ``runOn`` field to denote server version and/or - topology requirements requirements for the test file. Removes the - ``minServerVersion`` and ``topology`` top-level fields, which are - now expressed within ``runOn`` elements. - - Add test-level ``useMultipleMongoses`` field. diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate-merge.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate-merge.json deleted file mode 100644 index b401d741ba551b334d56469c4631fe8fc304bb3e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate-merge.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.11" - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "Aggregate with $merge does not retry", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "object": "collection", - "name": "aggregate", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - }, - { - "$merge": { - "into": "output-collection" - } - } - ] - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - }, - { - "$merge": { - "into": "output-collection" - } - } - ] - }, - "command_name": "aggregate", - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate-serverErrors.json deleted file mode 100644 index 04208bc95b8d3695e1e1f75b0f04d6cc5b013038..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate-serverErrors.json +++ /dev/null @@ -1,1207 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "Aggregate succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate.json deleted file mode 100644 index 30a6e05e69538cece0ac34913450f3cce1900b38..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/aggregate.json +++ /dev/null @@ -1,405 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "Aggregate succeeds on first attempt", - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "result": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Aggregate with $out does not retry", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - }, - { - "$out": "output-collection" - } - ] - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": { - "_id": { - "$gt": 1 - } - } - }, - { - "$sort": { - "x": 1 - } - }, - { - "$out": "output-collection" - } - ] - }, - "command_name": "aggregate", - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-client.watch-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-client.watch-serverErrors.json deleted file mode 100644 index cf6c230ec8f2a4ccc51012d8f547583175f44db8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-client.watch-serverErrors.json +++ /dev/null @@ -1,738 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "client.watch succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-client.watch.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-client.watch.json deleted file mode 100644 index 9a2ccad095038ea5bb08a4114665320a99b3d961..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-client.watch.json +++ /dev/null @@ -1,207 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "tests": [ - { - "description": "client.watch succeeds on first attempt", - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - }, - { - "description": "client.watch fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": { - "allChangesForCluster": true - } - } - ] - }, - "database_name": "admin" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.coll.watch-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.coll.watch-serverErrors.json deleted file mode 100644 index eb7df1e2643d7e23d64abf9b4f30f41d38f23a7d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.coll.watch-serverErrors.json +++ /dev/null @@ -1,688 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "db.coll.watch succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.coll.watch.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.coll.watch.json deleted file mode 100644 index 3408c842362ac962a9c514bc233c1963781eef2d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.coll.watch.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "tests": [ - { - "description": "db.coll.watch succeeds on first attempt", - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.coll.watch fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.watch-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.watch-serverErrors.json deleted file mode 100644 index e070f56a01b98209fc52fb1ca2f72bc5285bc230..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.watch-serverErrors.json +++ /dev/null @@ -1,688 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "db.watch succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "watch", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.watch.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.watch.json deleted file mode 100644 index bec09c49b76a9db01af029b701e35d8daf0a7c71..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/changeStreams-db.watch.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "tests": [ - { - "description": "db.watch succeeds on first attempt", - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "db.watch fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "watch", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": 1, - "cursor": {}, - "pipeline": [ - { - "$changeStream": {} - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/count-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/count-serverErrors.json deleted file mode 100644 index 839680fe59f8694f9ae0e504545608e2ec2bdd96..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/count-serverErrors.json +++ /dev/null @@ -1,585 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "Count succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/count.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/count.json deleted file mode 100644 index 0ccf4982ba6299d96ba64c28bb9490a1e7a40b49..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/count.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "Count succeeds on first attempt", - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Count fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "count" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "count", - "object": "collection", - "arguments": { - "filter": {} - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/countDocuments-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/countDocuments-serverErrors.json deleted file mode 100644 index f45eadfa0c209d5e6b0a03aeba38c9fb19d5b1f5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/countDocuments-serverErrors.json +++ /dev/null @@ -1,910 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "CountDocuments succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/countDocuments.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/countDocuments.json deleted file mode 100644 index b4ccf36684dec4337eeaa2c7a5df86507cc8b5a2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/countDocuments.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "CountDocuments succeeds on first attempt", - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "CountDocuments fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": {} - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "coll", - "pipeline": [ - { - "$match": {} - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ] - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/distinct-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/distinct-serverErrors.json deleted file mode 100644 index 50fd6a55051288d787a21fb2e92999f2cadfb11e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/distinct-serverErrors.json +++ /dev/null @@ -1,837 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "Distinct succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/distinct.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/distinct.json deleted file mode 100644 index b5885e27eb732ea1f783fa4ac00f98ea4f6fc6ed..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/distinct.json +++ /dev/null @@ -1,244 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "tests": [ - { - "description": "Distinct succeeds on first attempt", - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "result": [ - 22, - 33 - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Distinct fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "distinct" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "x", - "filter": { - "_id": { - "$gt": 1 - } - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "coll", - "key": "x", - "query": { - "_id": { - "$gt": 1 - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/estimatedDocumentCount-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/estimatedDocumentCount-serverErrors.json deleted file mode 100644 index 1af21d1fe9247904a4ccc61a679b0d68c4984247..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/estimatedDocumentCount-serverErrors.json +++ /dev/null @@ -1,546 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "EstimatedDocumentCount succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/estimatedDocumentCount.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/estimatedDocumentCount.json deleted file mode 100644 index 8dfa15a2cdb3ec5e5c00e37c17c6282b8966ed37..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/estimatedDocumentCount.json +++ /dev/null @@ -1,166 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "EstimatedDocumentCount succeeds on first attempt", - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "result": 2 - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "count" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "EstimatedDocumentCount fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "count" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "estimatedDocumentCount", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "count": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/find-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/find-serverErrors.json deleted file mode 100644 index 44ecf34d2fbc288a3ac0bc5612e072dd9bcf8ae5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/find-serverErrors.json +++ /dev/null @@ -1,961 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - }, - { - "_id": 5, - "x": 55 - } - ], - "tests": [ - { - "description": "Find succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/find.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/find.json deleted file mode 100644 index 56479ff1d8711da8f9df1bada7c753f5fd2ad69e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/find.json +++ /dev/null @@ -1,347 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - }, - { - "_id": 5, - "x": 55 - } - ], - "tests": [ - { - "description": "Find succeeds on first attempt", - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds on second attempt with explicit clientOptions", - "clientOptions": { - "retryReads": true - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "result": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Find fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": {}, - "sort": { - "_id": 1 - }, - "limit": 4 - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/findOne-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/findOne-serverErrors.json deleted file mode 100644 index b8229483d2444aa984ef0bcb2d78d738fc0147c1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/findOne-serverErrors.json +++ /dev/null @@ -1,731 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - }, - { - "_id": 5, - "x": 55 - } - ], - "tests": [ - { - "description": "FindOne succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/findOne.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/findOne.json deleted file mode 100644 index d296a9cdb5e80eaa1d0efd54a4e7a28fcb2cf806..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/findOne.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - }, - { - "_id": 5, - "x": 55 - } - ], - "tests": [ - { - "description": "FindOne succeeds on first attempt", - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": { - "_id": 1, - "x": 11 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "FindOne fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "findOne", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "coll", - "filter": { - "_id": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-download-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-download-serverErrors.json deleted file mode 100644 index 84e50e370c43323dd32724bf301285be2e8cd6a3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-download-serverErrors.json +++ /dev/null @@ -1,924 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "bucket_name": "fs", - "data": { - "fs.files": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "filename": "abc", - "metadata": {} - } - ], - "fs.chunks": [ - { - "_id": { - "$oid": "000000000000000000000002" - }, - "files_id": { - "$oid": "000000000000000000000001" - }, - "n": 0, - "data": { - "$binary": { - "base64": "EQ==", - "subType": "00" - } - } - } - ] - }, - "tests": [ - { - "description": "Download succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-download.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-download.json deleted file mode 100644 index a5c5ef4d5593b80be8191d6066d7306c9fff836c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-download.json +++ /dev/null @@ -1,269 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "bucket_name": "fs", - "data": { - "fs.files": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "filename": "abc", - "metadata": {} - } - ], - "fs.chunks": [ - { - "_id": { - "$oid": "000000000000000000000002" - }, - "files_id": { - "$oid": "000000000000000000000001" - }, - "n": 0, - "data": { - "$binary": { - "base64": "EQ==", - "subType": "00" - } - } - } - ] - }, - "tests": [ - { - "description": "Download succeeds on first attempt", - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "Download fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "download", - "object": "gridfsbucket", - "arguments": { - "id": { - "$oid": "000000000000000000000001" - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "_id": { - "$oid": "000000000000000000000001" - } - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-downloadByName-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-downloadByName-serverErrors.json deleted file mode 100644 index de439ce4b203001936f257eb968842a29f5148ca..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-downloadByName-serverErrors.json +++ /dev/null @@ -1,848 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "bucket_name": "fs", - "data": { - "fs.files": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "filename": "abc", - "metadata": {} - } - ], - "fs.chunks": [ - { - "_id": { - "$oid": "000000000000000000000002" - }, - "files_id": { - "$oid": "000000000000000000000001" - }, - "n": 0, - "data": { - "$binary": { - "base64": "EQ==", - "subType": "00" - } - } - } - ] - }, - "tests": [ - { - "description": "DownloadByName succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-downloadByName.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-downloadByName.json deleted file mode 100644 index 0634a09bff4f210dd2f448ac22c1b7fe6c34c50e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/gridfs-downloadByName.json +++ /dev/null @@ -1,249 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "bucket_name": "fs", - "data": { - "fs.files": [ - { - "_id": { - "$oid": "000000000000000000000001" - }, - "length": 1, - "chunkSize": 4, - "uploadDate": { - "$date": "1970-01-01T00:00:00.000Z" - }, - "filename": "abc", - "metadata": {} - } - ], - "fs.chunks": [ - { - "_id": { - "$oid": "000000000000000000000002" - }, - "files_id": { - "$oid": "000000000000000000000001" - }, - "n": 0, - "data": { - "$binary": { - "base64": "EQ==", - "subType": "00" - } - } - } - ] - }, - "tests": [ - { - "description": "DownloadByName succeeds on first attempt", - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.chunks", - "filter": { - "files_id": { - "$oid": "000000000000000000000001" - } - }, - "sort": { - "n": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "DownloadByName fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "download_by_name", - "object": "gridfsbucket", - "arguments": { - "filename": "abc" - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "fs.files", - "filter": { - "filename": "abc" - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionNames-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionNames-serverErrors.json deleted file mode 100644 index 27c13d6301c144e16444d413caebb3d867cc477b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionNames-serverErrors.json +++ /dev/null @@ -1,501 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListCollectionNames succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionNames.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionNames.json deleted file mode 100644 index 437fc36a40e762353a0afe0e4bb4df3d252c14d1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionNames.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListCollectionNames succeeds on first attempt", - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionNames fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollectionNames", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionObjects-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionObjects-serverErrors.json deleted file mode 100644 index 3922713df9cebc1be0a087312f5079f784966cec..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionObjects-serverErrors.json +++ /dev/null @@ -1,501 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListCollectionObjects succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionObjects.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionObjects.json deleted file mode 100644 index 1f537b743f07b7e4a2eba4a4c17e0e54cbc83853..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollectionObjects.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListCollectionObjects succeeds on first attempt", - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollectionObjects fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollectionObjects", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollections-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollections-serverErrors.json deleted file mode 100644 index 6972073b181afaa7f0238e0ae58474c4968fd65c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollections-serverErrors.json +++ /dev/null @@ -1,501 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListCollections succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollections.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollections.json deleted file mode 100644 index a6b452e64f086775ec9f6a119e3f1416e1a2282b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listCollections.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListCollections succeeds on first attempt", - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - }, - { - "description": "ListCollections fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listCollections" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listCollections", - "object": "database", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listCollections": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseNames-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseNames-serverErrors.json deleted file mode 100644 index 11faf58bf0439ff3616b5683f5a4af5c3a7413d2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseNames-serverErrors.json +++ /dev/null @@ -1,501 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListDatabaseNames succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseNames.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseNames.json deleted file mode 100644 index b35f7ab185f4a16366494b541a61956cb4482288..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseNames.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListDatabaseNames succeeds on first attempt", - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseNames fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabaseNames", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseObjects-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseObjects-serverErrors.json deleted file mode 100644 index 38082f2e28b06a8473138e80d087be0a9085e5ac..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseObjects-serverErrors.json +++ /dev/null @@ -1,501 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListDatabaseObjects succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseObjects.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseObjects.json deleted file mode 100644 index cbd2c6763a3beaeabec0696ceaecc623eb28aa8f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabaseObjects.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListDatabaseObjects succeeds on first attempt", - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabaseObjects fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabaseObjects", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabases-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabases-serverErrors.json deleted file mode 100644 index 4047f749ffcece26e15454cafda24f7bf7936ee6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabases-serverErrors.json +++ /dev/null @@ -1,501 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListDatabases succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabases.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabases.json deleted file mode 100644 index 3cb8bbd083cc40092321fcd7fb63082a5a720049..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listDatabases.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListDatabases succeeds on first attempt", - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - }, - { - "description": "ListDatabases fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listDatabases" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listDatabases", - "object": "client", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - }, - { - "command_started_event": { - "command": { - "listDatabases": 1 - } - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexNames-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexNames-serverErrors.json deleted file mode 100644 index 1a9ba83bc699c278234e5061509e668c2688afbf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexNames-serverErrors.json +++ /dev/null @@ -1,526 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListIndexNames succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexNames.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexNames.json deleted file mode 100644 index ef2a6d73065b0b8d6ce14e09cd8c1dbc66aa3d10..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexNames.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListIndexNames succeeds on first attempt", - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexNames": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexNames": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexNames": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexNames": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexNames fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listIndexNames", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexNames": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexNames": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexes-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexes-serverErrors.json deleted file mode 100644 index 16b61d535d62d04fee9cfec35710e17e38120a1f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexes-serverErrors.json +++ /dev/null @@ -1,526 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListIndexes succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 11600 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 13435 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 13436 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 189 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 91 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 7 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 6 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 89 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 9001 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes fails after two NotMaster errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes fails after NotMaster when retryReads is false", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexes.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexes.json deleted file mode 100644 index f460ea7684fd8ba84549a69b5903bcf57c378cf7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/listIndexes.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [], - "tests": [ - { - "description": "ListIndexes succeeds on first attempt", - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes succeeds on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes fails on first attempt", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "ListIndexes fails on second attempt", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "listIndexes" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "listIndexes", - "object": "collection", - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - }, - { - "command_started_event": { - "command": { - "listIndexes": "coll" - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_reads/mapReduce.json b/lib/mongoc/libmongoc/tests/json/retryable_reads/mapReduce.json deleted file mode 100644 index 9dc7a56f3c2d0f4091b4dd589bef842489357d2f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_reads/mapReduce.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "single", - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "database_name": "retryable-reads-tests", - "collection_name": "coll", - "data": [ - { - "_id": 1, - "x": 0 - }, - { - "_id": 2, - "x": 1 - }, - { - "_id": 3, - "x": 2 - } - ], - "tests": [ - { - "description": "MapReduce succeeds with retry on", - "operations": [ - { - "name": "mapReduce", - "object": "collection", - "arguments": { - "map": { - "$code": "function inc() { return emit(0, this.x + 1) }" - }, - "reduce": { - "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }" - }, - "out": { - "inline": 1 - } - }, - "result": [ - { - "_id": 0, - "value": 6 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "mapReduce": "coll", - "map": { - "$code": "function inc() { return emit(0, this.x + 1) }" - }, - "reduce": { - "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }" - }, - "out": { - "inline": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "MapReduce fails with retry on", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "mapReduce" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "mapReduce", - "object": "collection", - "arguments": { - "map": { - "$code": "function inc() { return emit(0, this.x + 1) }" - }, - "reduce": { - "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }" - }, - "out": { - "inline": 1 - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "mapReduce": "coll", - "map": { - "$code": "function inc() { return emit(0, this.x + 1) }" - }, - "reduce": { - "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }" - }, - "out": { - "inline": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - }, - { - "description": "MapReduce fails with retry off", - "clientOptions": { - "retryReads": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "mapReduce" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "mapReduce", - "object": "collection", - "arguments": { - "map": { - "$code": "function inc() { return emit(0, this.x + 1) }" - }, - "reduce": { - "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }" - }, - "out": { - "inline": 1 - } - }, - "error": true - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "mapReduce": "coll", - "map": { - "$code": "function inc() { return emit(0, this.x + 1) }" - }, - "reduce": { - "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }" - }, - "out": { - "inline": 1 - } - }, - "database_name": "retryable-reads-tests" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/bulkWrite-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/bulkWrite-serverErrors.json deleted file mode 100644 index 79c81a583bb1104160a6e2730242893f520bf3fd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/bulkWrite-serverErrors.json +++ /dev/null @@ -1,191 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "BulkWrite succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 189 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 1, - "insertedCount": 1, - "insertedIds": { - "1": 3 - }, - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "BulkWrite succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 1, - "insertedCount": 1, - "insertedIds": { - "1": 3 - }, - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/bulkWrite.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/bulkWrite.json deleted file mode 100644 index 72a8d0189397b0d016f025088bdbc3908bc7a122..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/bulkWrite.json +++ /dev/null @@ -1,806 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "tests": [ - { - "description": "First command is retried", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 1, - "insertedCount": 1, - "insertedIds": { - "0": 2 - }, - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 23 - } - ] - } - } - }, - { - "description": "All commands are retried", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 7 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 4, - "x": 44 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 5, - "x": 55 - } - } - }, - { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 3 - }, - "replacement": { - "_id": 3, - "x": 333 - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 1, - "insertedCount": 3, - "insertedIds": { - "0": 2, - "2": 3, - "4": 5 - }, - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 1, - "upsertedIds": { - "3": 4 - } - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 23 - }, - { - "_id": 3, - "x": 333 - }, - { - "_id": 4, - "x": 45 - }, - { - "_id": 5, - "x": 55 - } - ] - } - } - }, - { - "description": "Both commands are retried after their first statement fails", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 1, - "insertedIds": { - "0": 2 - }, - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 23 - } - ] - } - } - }, - { - "description": "Second command is retried after its second statement fails", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "skip": 2 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 1, - "insertedIds": { - "0": 2 - }, - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 23 - } - ] - } - } - }, - { - "description": "BulkWrite with unordered execution", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - } - ], - "options": { - "ordered": false - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 2, - "insertedIds": { - "0": 2, - "1": 3 - }, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "First insertOne is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "error": true, - "result": { - "deletedCount": 0, - "insertedCount": 0, - "insertedIds": {}, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - } - ] - } - } - }, - { - "description": "Second updateOne is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "skip": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "error": true, - "result": { - "deletedCount": 0, - "insertedCount": 1, - "insertedIds": { - "0": 2 - }, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "Third updateOne is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "skip": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "error": true, - "result": { - "deletedCount": 0, - "insertedCount": 1, - "insertedIds": { - "1": 2 - }, - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "Single-document write following deleteMany is retried", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "deleteMany", - "arguments": { - "filter": { - "x": 11 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 1, - "insertedCount": 1, - "insertedIds": { - "1": 2 - }, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "Single-document write following updateMany is retried", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "bulkWrite", - "arguments": { - "requests": [ - { - "name": "updateMany", - "arguments": { - "filter": { - "x": 11 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 2, - "x": 22 - } - } - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "deletedCount": 0, - "insertedCount": 1, - "insertedIds": { - "1": 2 - }, - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0, - "upsertedIds": {} - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteMany.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteMany.json deleted file mode 100644 index 642ad11fb47fe27c9c6348a6c4ab99456aff9d31..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteMany.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset", - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "DeleteMany ignores retryWrites", - "useMultipleMongoses": true, - "operation": { - "name": "deleteMany", - "arguments": { - "filter": {} - } - }, - "outcome": { - "result": { - "deletedCount": 2 - }, - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteOne-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteOne-serverErrors.json deleted file mode 100644 index 9ef2bf2f2973243558c9c676637e977f1015bc50..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteOne-serverErrors.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "DeleteOne succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "errorCode": 189 - } - }, - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - "outcome": { - "result": { - "deletedCount": 1 - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "DeleteOne succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - "outcome": { - "result": { - "deletedCount": 1 - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteOne.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteOne.json deleted file mode 100644 index 592937acedd50938c6efffafcce00929237e647f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/deleteOne.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "DeleteOne is committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - "outcome": { - "result": { - "deletedCount": 1 - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "DeleteOne is not committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - "outcome": { - "result": { - "deletedCount": 1 - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "DeleteOne is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndDelete-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndDelete-serverErrors.json deleted file mode 100644 index d72d1a05baa433f852af1e99f3f78bac21623921..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndDelete-serverErrors.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "FindOneAndDelete succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 189 - } - }, - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "x": { - "$gte": 11 - } - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndDelete succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "x": { - "$gte": 11 - } - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndDelete.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndDelete.json deleted file mode 100644 index 0cbe18108bd2a8df10d6482f9a7f47e99c620cf6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndDelete.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "FindOneAndDelete is committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "x": { - "$gte": 11 - } - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndDelete is not committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "x": { - "$gte": 11 - } - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndDelete is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "findOneAndDelete", - "arguments": { - "filter": { - "x": { - "$gte": 11 - } - }, - "sort": { - "x": 1 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndReplace-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndReplace-serverErrors.json deleted file mode 100644 index d5d25e1d78c6d616aada524bbde40aa56d62ed1a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndReplace-serverErrors.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "FindOneAndReplace succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 189 - } - }, - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - }, - "returnDocument": "Before" - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndReplace succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - }, - "returnDocument": "Before" - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndReplace.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndReplace.json deleted file mode 100644 index e1f9ab7f8c345a7d73f41b5a487498de84d958b4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndReplace.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "FindOneAndReplace is committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - }, - "returnDocument": "Before" - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndReplace is not committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - }, - "returnDocument": "Before" - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndReplace is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "findOneAndReplace", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - }, - "returnDocument": "Before" - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndUpdate-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndUpdate-serverErrors.json deleted file mode 100644 index b9f57cd825becb12248df78a60a40a0d5d749ad7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndUpdate-serverErrors.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "FindOneAndUpdate succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 189 - } - }, - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndUpdate.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndUpdate.json deleted file mode 100644 index 9ae2d87d82103d19530c5505dd8e0b39f8261287..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/findOneAndUpdate.json +++ /dev/null @@ -1,147 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "FindOneAndUpdate is committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate is not committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - } - }, - "outcome": { - "result": { - "_id": 1, - "x": 11 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "FindOneAndUpdate is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "findOneAndUpdate", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/insertMany-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/insertMany-serverErrors.json deleted file mode 100644 index 773ad9307f148dd563d1c42000d534831b5b1301..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/insertMany-serverErrors.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "tests": [ - { - "description": "InsertMany succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 189 - } - }, - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "insertedIds": { - "0": 2, - "1": 3 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertMany succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "insertedIds": { - "0": 2, - "1": 3 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/insertMany.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/insertMany.json deleted file mode 100644 index 0ad326e2dc9ac6f16b2b3f11e16d063f909c6601..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/insertMany.json +++ /dev/null @@ -1,163 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - } - ], - "tests": [ - { - "description": "InsertMany succeeds after one network error", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "result": { - "insertedIds": { - "0": 2, - "1": 3 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertMany with unordered execution", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ], - "options": { - "ordered": false - } - } - }, - "outcome": { - "result": { - "insertedIds": { - "0": 2, - "1": 3 - } - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertMany fails after multiple network errors", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": "alwaysOn", - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "insertMany", - "arguments": { - "documents": [ - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - }, - { - "_id": 4, - "x": 44 - } - ], - "options": { - "ordered": true - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/insertOne-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/insertOne-serverErrors.json deleted file mode 100644 index 3c3c5b1dc3673030229fd64677b9dfa746b39477..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/insertOne-serverErrors.json +++ /dev/null @@ -1,953 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "InsertOne succeeds after connection failure", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 10107, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 13436, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 13435, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11602, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11600, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 189, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 91, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 7, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 6, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 9001, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 89, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne fails after Interrupted", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11601, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after WriteConcernError InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 11600, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after WriteConcernError InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 11602, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after WriteConcernError PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 189, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne fails after multiple retryable writeConcernErrors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne fails after WriteConcernError Interrupted", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 11601, - "errmsg": "operation was interrupted" - } - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne fails after WriteConcernError WriteConcernFailed", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "writeConcernError": { - "code": 64, - "codeName": "WriteConcernFailed", - "errmsg": "waiting for replication timed out", - "errInfo": { - "wtimeout": true - } - } - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/insertOne.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/insertOne.json deleted file mode 100644 index 04dee6dd68acbcf57c83387f44db61b81d8303e0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/insertOne.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "InsertOne is committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne is not committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/replaceOne-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/replaceOne-serverErrors.json deleted file mode 100644 index aac7b2f39422eddec09536a9e66787ec7e5abebb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/replaceOne-serverErrors.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "ReplaceOne succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 189 - } - }, - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "ReplaceOne succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/replaceOne.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/replaceOne.json deleted file mode 100644 index e5b8cf8eabbed381690af11437ab438d39fb587b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/replaceOne.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "ReplaceOne is committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "ReplaceOne is not committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 111 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "ReplaceOne is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "_id": 1, - "x": 111 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/retryableErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/retryableErrors.json deleted file mode 100644 index e269e6db20a675eba35583f6a6220638aaf30372..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/retryableErrors.json +++ /dev/null @@ -1,606 +0,0 @@ -{ - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "minServerVersion": "4.1.0", - "tests": [ - { - "description": "InsertOne succeeds after connection failure", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 10107, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 13436, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 13435, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11602, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11600, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 189, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 91, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 7, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 6, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 9001, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 89, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "result": { - "insertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 33 - } - ] - } - } - }, - { - "description": "InsertOne fails after Interrupted", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11601, - "closeConnection": false - } - }, - "operation": { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3, - "x": 33 - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/updateMany.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/updateMany.json deleted file mode 100644 index 14288c2860dcf99738ff999755bc4e5d2ceb4d0f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/updateMany.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset", - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "UpdateMany ignores retryWrites", - "useMultipleMongoses": true, - "operation": { - "name": "updateMany", - "arguments": { - "filter": {}, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 23 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/updateOne-serverErrors.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/updateOne-serverErrors.json deleted file mode 100644 index 6f6c55dd51d052a529edee009e44808e7b3d2eb4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/updateOne-serverErrors.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.7", - "topology": [ - "sharded" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "UpdateOne succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 189 - } - }, - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "UpdateOne succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/retryable_writes/updateOne.json b/lib/mongoc/libmongoc/tests/json/retryable_writes/updateOne.json deleted file mode 100644 index 0f806dc3d8485291e5a073c89bb278cf324f764e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/retryable_writes/updateOne.json +++ /dev/null @@ -1,288 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "3.6", - "topology": [ - "replicaset" - ] - } - ], - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ], - "tests": [ - { - "description": "UpdateOne is committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "UpdateOne is not committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 12 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "UpdateOne is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - }, - { - "description": "UpdateOne with upsert is committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - } - }, - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 3, - "x": 33 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 1, - "upsertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 34 - } - ] - } - } - }, - { - "description": "UpdateOne with upsert is not committed on first attempt", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 1 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 3, - "x": 33 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - } - }, - "outcome": { - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 1, - "upsertedId": 3 - }, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - }, - { - "_id": 3, - "x": 34 - } - ] - } - } - }, - { - "description": "UpdateOne with upsert is never committed", - "failPoint": { - "configureFailPoint": "onPrimaryTransactionalWrite", - "mode": { - "times": 2 - }, - "data": { - "failBeforeCommitExceptionCode": 1 - } - }, - "operation": { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 3, - "x": 33 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - } - }, - "outcome": { - "error": true, - "collection": { - "data": [ - { - "_id": 1, - "x": 11 - }, - { - "_id": 2, - "x": 22 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_no_primary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_no_primary.json deleted file mode 100644 index 33010d49fb9d4a18ed26f7c7d77dfa0c188bbf46..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_no_primary.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "description": "Monitoring a topology that is a replica set with no primary connected", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "setVersion": 1, - "primary": "b:27017", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 4 - } - ] - ], - "outcome": { - "events": [ - { - "topology_opening_event": { - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Unknown", - "servers": [] - }, - "newDescription": { - "topologyType": "Unknown", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - } - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "a:27017" - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "b:27017" - } - }, - { - "server_description_changed_event": { - "topologyId": "42", - "address": "a:27017", - "previousDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - "newDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017", - "b:27017" - ], - "passives": [], - "primary": "b:27017", - "setName": "rs", - "type": "RSSecondary" - } - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Unknown", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - }, - "newDescription": { - "topologyType": "ReplicaSetNoPrimary", - "setName": "rs", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017", - "b:27017" - ], - "passives": [], - "primary": "b:27017", - "setName": "rs", - "type": "RSSecondary" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "PossiblePrimary" - } - ] - } - } - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_primary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_primary.json deleted file mode 100644 index 04caeba652ed3628c31718b5c3eb398fb909fb6f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_primary.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "description": "Monitoring a topology that is a replica set with a primary connected", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "setVersion": 1, - "primary": "a:27017", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 4 - } - ] - ], - "outcome": { - "events": [ - { - "topology_opening_event": { - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Unknown", - "servers": [] - }, - "newDescription": { - "topologyType": "Unknown", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - } - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "a:27017" - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "b:27017" - } - }, - { - "server_description_changed_event": { - "topologyId": "42", - "address": "a:27017", - "previousDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - "newDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017", - "b:27017" - ], - "passives": [], - "primary": "a:27017", - "setName": "rs", - "type": "RSPrimary" - } - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Unknown", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - }, - "newDescription": { - "topologyType": "ReplicaSetWithPrimary", - "setName": "rs", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017", - "b:27017" - ], - "passives": [], - "primary": "a:27017", - "setName": "rs", - "type": "RSPrimary" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - } - } - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_removal.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_removal.json deleted file mode 100644 index a14456cdba9cf5e31e1d8e5674fc2e67a56f4e38..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/replica_set_with_removal.json +++ /dev/null @@ -1,152 +0,0 @@ -{ - "description": "Monitoring a replica set with non member", - "uri": "mongodb://a,b/", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "setVersion": 1, - "primary": "a:27017", - "hosts": [ - "a:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 4 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true - } - ] - ], - "outcome": { - "events": [ - { - "topology_opening_event": { - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Unknown", - "servers": [] - }, - "newDescription": { - "topologyType": "Unknown", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - } - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "a:27017" - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "b:27017" - } - }, - { - "server_description_changed_event": { - "topologyId": "42", - "address": "a:27017", - "previousDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - "newDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017" - ], - "passives": [], - "primary": "a:27017", - "setName": "rs", - "type": "RSPrimary" - } - } - }, - { - "server_closed_event": { - "topologyId": "42", - "address": "b:27017" - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Unknown", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - }, - "newDescription": { - "topologyType": "ReplicaSetWithPrimary", - "setName": "rs", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017" - ], - "passives": [], - "primary": "a:27017", - "setName": "rs", - "type": "RSPrimary" - } - ] - } - } - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/required_replica_set.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/required_replica_set.json deleted file mode 100644 index 5cc4fa818a9d05d0f2b7861d49db5631fc3d96aa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/required_replica_set.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "description": "Monitoring a topology that is required to be a replica set", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "setVersion": 1, - "primary": "a:27017", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 4 - } - ] - ], - "outcome": { - "events": [ - { - "topology_opening_event": { - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Unknown", - "servers": [] - }, - "newDescription": { - "topologyType": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - } - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "a:27017" - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "b:27017" - } - }, - { - "server_description_changed_event": { - "topologyId": "42", - "address": "a:27017", - "previousDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - "newDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017", - "b:27017" - ], - "passives": [], - "primary": "a:27017", - "setName": "rs", - "type": "RSPrimary" - } - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - }, - "newDescription": { - "topologyType": "ReplicaSetWithPrimary", - "setName": "rs", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017", - "b:27017" - ], - "passives": [], - "primary": "a:27017", - "setName": "rs", - "type": "RSPrimary" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - } - } - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/standalone.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/standalone.json deleted file mode 100644 index 5d40286c97359a67beffb0be77cdcfa85d3c68fc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/monitoring/standalone.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "description": "Monitoring a standalone connection", - "uri": "mongodb://a:27017", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "minWireVersion": 0, - "maxWireVersion": 4 - } - ] - ], - "outcome": { - "events": [ - { - "topology_opening_event": { - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Unknown", - "servers": [] - }, - "newDescription": { - "topologyType": "Single", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - } - } - }, - { - "server_opening_event": { - "topologyId": "42", - "address": "a:27017" - } - }, - { - "server_description_changed_event": { - "topologyId": "42", - "address": "a:27017", - "previousDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - "newDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Standalone" - } - } - }, - { - "topology_description_changed_event": { - "topologyId": "42", - "previousDescription": { - "topologyType": "Single", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ] - }, - "newDescription": { - "topologyType": "Single", - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Standalone" - } - ] - } - } - } - ] - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/compatible.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/compatible.json deleted file mode 100644 index d670770f6d1ee2558b17469432de6b5c2367e243..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/compatible.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "description": "Replica set member with large maxWireVersion", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 1000 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "setName": "rs", - "logicalSessionTimeoutMinutes": null, - "compatible": true - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_arbiters.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_arbiters.json deleted file mode 100644 index ced7baeb6539edcefe855aa5f838a37ae08ae15e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_arbiters.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "description": "Discover arbiters", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "arbiters": [ - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_passives.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_passives.json deleted file mode 100644 index e46249d6686b1ce8065749b63fd840119ab36e02..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_passives.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "description": "Discover passives", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "passives": [ - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "passive": true, - "hosts": [ - "a:27017" - ], - "passives": [ - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_primary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_primary.json deleted file mode 100644 index ea2cce9b72b081e7a1c0039a66d1a108b0ce8720..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_primary.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "description": "Replica set discovery from primary", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_secondary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_secondary.json deleted file mode 100644 index 7210b3845c782fe3846f9ff48c2ac1815accf086..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discover_secondary.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "description": "Replica set discovery from secondary", - "uri": "mongodb://b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discovery.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discovery.json deleted file mode 100644 index 57ed568e3b0c35f2e329b8f01143184d704c4127..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/discovery.json +++ /dev/null @@ -1,175 +0,0 @@ -{ - "description": "Replica set discovery", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017", - "c:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - }, - "c:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "primary": "d:27017", - "hosts": [ - "b:27017", - "c:27017", - "d:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "c:27017": { - "type": "Unknown", - "setName": null - }, - "d:27017": { - "type": "PossiblePrimary", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "d:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "b:27017", - "c:27017", - "d:27017", - "e:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "c:27017": { - "type": "Unknown", - "setName": null - }, - "d:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "e:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "c:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017", - "c:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "c:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "d:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "e:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/equal_electionids.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/equal_electionids.json deleted file mode 100644 index 8a5aa8cd67bbbfbbc40f1677b0a804f39651b8f5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/equal_electionids.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "description": "New primary with equal electionId", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "setVersion": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - } - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/ghost_discovered.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/ghost_discovered.json deleted file mode 100644 index bf22cbb0eb5efc40e0311f98560d2976cfd74d1c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/ghost_discovered.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "description": "Ghost discovered", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "isreplicaset": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - }, - "b:27017": { - "type": "RSGhost", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/hosts_differ_from_seeds.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/hosts_differ_from_seeds.json deleted file mode 100644 index a67db57d0cbcc005114962bf0f9d6d796ff6aa16..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/hosts_differ_from_seeds.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "description": "Host list differs from seeds", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/ls_timeout.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/ls_timeout.json deleted file mode 100644 index 6860742c9e99e792936a923a2d9a4609ab03e7d4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/ls_timeout.json +++ /dev/null @@ -1,273 +0,0 @@ -{ - "description": "Parse logicalSessionTimeoutMinutes from replica set", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017", - "c:27017", - "d:27017", - "e:27017" - ], - "setName": "rs", - "logicalSessionTimeoutMinutes": 3, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown" - }, - "c:27017": { - "type": "Unknown" - }, - "d:27017": { - "type": "Unknown" - }, - "e:27017": { - "type": "Unknown" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": 3, - "setName": "rs" - } - }, - { - "responses": [ - [ - "d:27017", - { - "ok": 1, - "ismaster": false, - "isreplicaset": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown" - }, - "c:27017": { - "type": "Unknown" - }, - "d:27017": { - "type": "RSGhost" - }, - "e:27017": { - "type": "Unknown" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": 3, - "setName": "rs" - } - }, - { - "responses": [ - [ - "e:27017", - { - "ok": 1, - "ismaster": false, - "hosts": [ - "a:27017", - "b:27017", - "c:27017", - "d:27017", - "e:27017" - ], - "setName": "rs", - "arbiterOnly": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown" - }, - "c:27017": { - "type": "Unknown" - }, - "d:27017": { - "type": "RSGhost" - }, - "e:27017": { - "type": "RSArbiter", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": 3, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "a:27017", - "b:27017", - "c:27017", - "d:27017", - "e:27017" - ], - "setName": "rs", - "logicalSessionTimeoutMinutes": 2, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "c:27017": { - "type": "Unknown" - }, - "d:27017": { - "type": "RSGhost" - }, - "e:27017": { - "type": "RSArbiter", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": 2, - "setName": "rs" - } - }, - { - "responses": [ - [ - "c:27017", - { - "ok": 1, - "ismaster": false, - "setName": "rs", - "hidden": true, - "logicalSessionTimeoutMinutes": 1, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "c:27017": { - "type": "RSOther", - "setName": "rs" - }, - "d:27017": { - "type": "RSGhost" - }, - "e:27017": { - "type": "RSArbiter", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": 2, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "a:27017", - "b:27017", - "c:27017", - "d:27017", - "e:27017" - ], - "setName": "rs", - "logicalSessionTimeoutMinutes": null, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "c:27017": { - "type": "RSOther", - "setName": "rs" - }, - "d:27017": { - "type": "RSGhost" - }, - "e:27017": { - "type": "RSArbiter", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/member_reconfig.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/member_reconfig.json deleted file mode 100644 index 336acff0236fc433cefee4da5cb9015cd52dbae8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/member_reconfig.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "description": "Member removed by reconfig", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/member_standalone.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/member_standalone.json deleted file mode 100644 index a97dfabf52e32190ae02dff4307c3df5a4acbff2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/member_standalone.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "description": "Member brought up as standalone", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "Unknown", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary.json deleted file mode 100644 index eb73b304bd9c6aaa4553f4e2ba3581933425cfe7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "description": "New primary", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_new_electionid.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_new_electionid.json deleted file mode 100644 index cd6c37cef788e2a8ca15a9b3cf70fc7d8c3b86f1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_new_electionid.json +++ /dev/null @@ -1,132 +0,0 @@ -{ - "description": "New primary with greater setVersion and electionId", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - } - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000002" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000002" - } - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000002" - } - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_new_setversion.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_new_setversion.json deleted file mode 100644 index c5828171d41347122fcdef1107656213bcb263eb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_new_setversion.json +++ /dev/null @@ -1,132 +0,0 @@ -{ - "description": "New primary with greater setVersion", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - } - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 2, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 2, - "electionId": { - "$oid": "000000000000000000000001" - } - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 2, - "electionId": { - "$oid": "000000000000000000000001" - } - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_wrong_set_name.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_wrong_set_name.json deleted file mode 100644 index 7be79d2d3c9b8fa432cc79f8ec52d83a603a2166..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/new_primary_wrong_set_name.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "description": "New primary with wrong setName", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "wrong", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/non_rs_member.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/non_rs_member.json deleted file mode 100644 index 907c1651e02c2b06425b284bfc75cb643dd2df38..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/non_rs_member.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "description": "Non replicaSet member responds", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/normalize_case.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/normalize_case.json deleted file mode 100644 index 4d0b0ae629b08e8b4e5aa5ce60a877e773dcbbed..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/normalize_case.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "description": "Replica set case normalization", - "uri": "mongodb://A/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "A:27017" - ], - "passives": [ - "B:27017" - ], - "arbiters": [ - "C:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - }, - "c:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/normalize_case_me.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/normalize_case_me.json deleted file mode 100644 index e854e7fb432e28fb48c0d96722b09b2a9b464cd0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/normalize_case_me.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "description": "Replica set mixed case normalization", - "uri": "mongodb://A/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "me": "A:27017", - "hosts": [ - "A:27017" - ], - "passives": [ - "B:27017" - ], - "arbiters": [ - "C:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - }, - "c:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "me": "B:27017", - "hosts": [ - "A:27017" - ], - "passives": [ - "B:27017" - ], - "arbiters": [ - "C:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "c:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/null_election_id.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/null_election_id.json deleted file mode 100644 index d4348df442d87fa4b24399fcefa7b34f45aa0974..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/null_election_id.json +++ /dev/null @@ -1,186 +0,0 @@ -{ - "description": "Primaries with and without electionIds", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017", - "c:27017" - ], - "setVersion": 1, - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": null - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "c:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017", - "c:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000002" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000002" - } - }, - "c:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017", - "c:27017" - ], - "setVersion": 1, - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": null - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "c:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "c:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017", - "c:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": null - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "c:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_ghost.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_ghost.json deleted file mode 100644 index 897120f1fbc619a2f31fbe6208113e01a7956a4d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_ghost.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "description": "Primary becomes ghost", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "isreplicaset": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSGhost", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_mongos.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_mongos.json deleted file mode 100644 index 8d4967b7ddb077ea3b0bed66e4ceb9545118d66c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_mongos.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "description": "Primary becomes mongos", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": {}, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_standalone.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_standalone.json deleted file mode 100644 index e35c75f4bc02f7bdae0d93cfcc3ebbe2433a5d35..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_becomes_standalone.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "description": "Primary becomes standalone", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": {}, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_changes_set_name.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_changes_set_name.json deleted file mode 100644 index d008326123bbcb78e8662e832008d18efb7b9017..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_changes_set_name.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "description": "Primary changes setName", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "wrong", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": {}, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect.json deleted file mode 100644 index 271ca5874e571a68bfbd320a7d9abff4178ac36e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "description": "Disconnected from primary", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - {} - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect_electionid.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect_electionid.json deleted file mode 100644 index e81f2990861e211f7a0afb813f73684b7f671cb6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect_electionid.json +++ /dev/null @@ -1,210 +0,0 @@ -{ - "description": "Disconnected from primary, reject primary with stale electionId", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000002" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000002" - } - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - {} - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000003" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000003" - } - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000003" - } - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect_setversion.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect_setversion.json deleted file mode 100644 index d0e55c545a06481033349085da79436426a5dd06..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_disconnect_setversion.json +++ /dev/null @@ -1,210 +0,0 @@ -{ - "description": "Disconnected from primary, reject primary with stale setVersion", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 2, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 2, - "electionId": { - "$oid": "000000000000000000000001" - } - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - {} - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 2, - "electionId": { - "$oid": "000000000000000000000002" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 2, - "electionId": { - "$oid": "000000000000000000000002" - } - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 2, - "electionId": { - "$oid": "000000000000000000000002" - } - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_hint_from_secondary_with_mismatched_me.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_hint_from_secondary_with_mismatched_me.json deleted file mode 100644 index 806fda37c3bbd33b95198abe4d2ea2603d58617c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_hint_from_secondary_with_mismatched_me.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "description": "Secondary with mismatched 'me' tells us who the primary is", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "me": "c:27017", - "hosts": [ - "b:27017" - ], - "setName": "rs", - "primary": "b:27017", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "b:27017": { - "type": "PossiblePrimary", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "me": "b:27017", - "hosts": [ - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "b:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_mismatched_me.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_mismatched_me.json deleted file mode 100644 index 8d18a6971f5433c715d327d53d97dea34013d396..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_mismatched_me.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "description": "Primary mismatched me", - "phases": [ - { - "outcome": { - "servers": { - "a:27017": { - "setName": null, - "type": "Unknown" - }, - "b:27017": { - "setName": null, - "type": "Unknown" - } - }, - "setName": "rs", - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null - }, - "responses": [ - [ - "localhost:27017", - { - "me": "a:27017", - "hosts": [ - "a:27017", - "b:27017" - ], - "ismaster": true, - "ok": 1, - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ] - } - ], - "uri": "mongodb://localhost:27017/?replicaSet=rs" -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_reports_new_member.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_reports_new_member.json deleted file mode 100644 index 6ed55ab3d196eecc31bfbf9c72873879c6267509..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_reports_new_member.json +++ /dev/null @@ -1,151 +0,0 @@ -{ - "description": "Primary reports a new member", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017", - "c:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "c:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "c:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "primary": "b:27017", - "hosts": [ - "a:27017", - "b:27017", - "c:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSSecondary", - "setName": "rs" - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "c:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_to_no_primary_mismatched_me.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_to_no_primary_mismatched_me.json deleted file mode 100644 index fdb250ffef43aa7690606fa01e739971e967c3f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_to_no_primary_mismatched_me.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "description": "Primary to no primary with mismatched me", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "me": "a:27017", - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "c:27017", - "d:27017" - ], - "me": "c:27017", - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "c:27017": { - "type": "Unknown", - "setName": null - }, - "d:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_wrong_set_name.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_wrong_set_name.json deleted file mode 100644 index eda4787173085b262014fc01cd316b8fe96e8cf5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/primary_wrong_set_name.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "description": "Primary wrong setName", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "wrong", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": {}, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/response_from_removed.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/response_from_removed.json deleted file mode 100644 index dd3562d7fc9d03f6bf8f7c936205be2bda096574..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/response_from_removed.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "description": "Response from removed server", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/rsother_discovered.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/rsother_discovered.json deleted file mode 100644 index c575501d80388349acec9b7773c1681cb6a1ae38..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/rsother_discovered.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "description": "RSOther discovered", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hidden": true, - "hosts": [ - "c:27017", - "d:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": false, - "hosts": [ - "c:27017", - "d:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSOther", - "setName": "rs" - }, - "b:27017": { - "type": "RSOther", - "setName": "rs" - }, - "c:27017": { - "type": "Unknown", - "setName": null - }, - "d:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/sec_not_auth.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/sec_not_auth.json deleted file mode 100644 index 7d5e7000357ba2a40befccdd5a581d21b2f3954e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/sec_not_auth.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "description": "Secondary's host list is not authoritative", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "b:27017", - "c:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_ignore_ok_0.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_ignore_ok_0.json deleted file mode 100644 index 6d3033eeeee83116b4a58f440e48925d25e325fc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_ignore_ok_0.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "description": "New primary", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 0, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_mismatched_me.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_mismatched_me.json deleted file mode 100644 index d2a70f67889abfe5c4f9713b87366cc6c1311c13..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_mismatched_me.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "description": "Secondary mismatched me", - "phases": [ - { - "outcome": { - "servers": { - "a:27017": { - "setName": null, - "type": "Unknown" - }, - "b:27017": { - "setName": null, - "type": "Unknown" - } - }, - "setName": "rs", - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null - }, - "responses": [ - [ - "localhost:27017", - { - "me": "a:27017", - "hosts": [ - "a:27017", - "b:27017" - ], - "ismaster": false, - "ok": 1, - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ] - } - ], - "uri": "mongodb://localhost:27017/?replicaSet=rs" -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_wrong_set_name.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_wrong_set_name.json deleted file mode 100644 index 4c132b633e19beaac4bce96d58ff3465988ffd42..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_wrong_set_name.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "description": "Secondary wrong setName", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "a:27017" - ], - "setName": "wrong", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": {}, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_wrong_set_name_with_primary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_wrong_set_name_with_primary.json deleted file mode 100644 index 73cbab7c5d54f1befcd120aa6be1420f843e0ec6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/secondary_wrong_set_name_with_primary.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "description": "Secondary wrong setName with primary", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "wrong", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/setversion_without_electionid.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/setversion_without_electionid.json deleted file mode 100644 index dbd9765d2f0dd46808abf8c30bf8fdd23010adb5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/setversion_without_electionid.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "description": "setVersion is ignored if there is no electionId", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 2, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 2, - "electionId": null - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/stepdown_change_set_name.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/stepdown_change_set_name.json deleted file mode 100644 index 39a4f532ddbc1f7c3e7fa1d9e7d2bf67bbcd8cd0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/stepdown_change_set_name.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "description": "Primary becomes a secondary with wrong setName", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "a:27017" - ], - "setName": "wrong", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": {}, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/too_new.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/too_new.json deleted file mode 100644 index 945145af88569e84a4a6c0432b2affa37ef48ac6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/too_new.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "description": "Replica set member with large minWireVersion", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 999, - "maxWireVersion": 1000 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "setName": "rs", - "logicalSessionTimeoutMinutes": null, - "compatible": false - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/too_old.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/too_old.json deleted file mode 100644 index 3f9eadc4bca0480f82859b4369e700bef3096a95..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/too_old.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "description": "Replica set member with default maxWireVersion of 0", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "setName": "rs", - "hosts": [ - "a:27017", - "b:27017" - ] - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - }, - "b:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "ReplicaSetWithPrimary", - "setName": "rs", - "logicalSessionTimeoutMinutes": null, - "compatible": false - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/unexpected_mongos.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/unexpected_mongos.json deleted file mode 100644 index 95c7aa9dce27249d9bbf03f81299ac649a1c5dae..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/unexpected_mongos.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "description": "Unexpected mongos", - "uri": "mongodb://b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": {}, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/use_setversion_without_electionid.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/use_setversion_without_electionid.json deleted file mode 100644 index 19e1727bf39dc8cdc5e372a147b2c0e9c4818ff5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/use_setversion_without_electionid.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "description": "Record max setVersion, even from primary without electionId", - "uri": "mongodb://a/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000001" - } - }, - "b:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 2, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 2 - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "setVersion": 1, - "electionId": { - "$oid": "000000000000000000000002" - }, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null, - "electionId": null - }, - "b:27017": { - "type": "RSPrimary", - "setName": "rs", - "setVersion": 2 - } - }, - "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/wrong_set_name.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/wrong_set_name.json deleted file mode 100644 index 45be2f502b2014ff37c9a0df06c2107e171ff71f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/rs/wrong_set_name.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "description": "Wrong setName", - "uri": "mongodb://a,b/?replicaSet=rs", - "phases": [ - { - "responses": [ - [ - "b:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "b:27017", - "c:27017" - ], - "setName": "wrong", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "ReplicaSetNoPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/compatible.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/compatible.json deleted file mode 100644 index 3dae1f7ea1e393ed8e010b0c56abac959c8fd3fb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/compatible.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "description": "Multiple mongoses with large maxWireVersion", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 1000 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null, - "compatible": true - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/ls_timeout_mongos.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/ls_timeout_mongos.json deleted file mode 100644 index 96f8dec17ac61952cb60a192f83ed21d56f26cbd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/ls_timeout_mongos.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "description": "Parse logicalSessionTimeoutMinutes from mongoses", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "logicalSessionTimeoutMinutes": 1, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "logicalSessionTimeoutMinutes": 2, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": 1, - "setName": null - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "logicalSessionTimeoutMinutes": 1, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/mongos_disconnect.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/mongos_disconnect.json deleted file mode 100644 index 04015694a8d06e53bdc269730cc3d7743288e7be..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/mongos_disconnect.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "description": "Mongos disconnect", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - }, - { - "responses": [ - [ - "a:27017", - {} - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - }, - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/multiple_mongoses.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/multiple_mongoses.json deleted file mode 100644 index 6e60fd05c7d92e418b9f3cb7b5dc4cf1c0b20c80..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/multiple_mongoses.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "description": "Multiple mongoses", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/non_mongos_removed.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/non_mongos_removed.json deleted file mode 100644 index 58cf7c07d78452325745ac98bffb5435aa7e9813..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/non_mongos_removed.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "description": "Non-Mongos server in sharded cluster", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/normalize_uri_case.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/normalize_uri_case.json deleted file mode 100644 index 4aa7cb08b611a83e6c224f01bd6106009b396b48..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/normalize_uri_case.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "description": "Normalize URI case", - "uri": "mongodb://A,B", - "phases": [ - { - "responses": [], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - }, - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "Unknown", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/too_new.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/too_new.json deleted file mode 100644 index 9521e1178991830167427966bdba1569c67b3aee..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/too_new.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "description": "Multiple mongoses with large minWireVersion", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 999, - "maxWireVersion": 1000 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid" - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null, - "compatible": false - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/too_old.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/too_old.json deleted file mode 100644 index 6bd187f61dba67ed86e0e98aa4b2f7f6ca53bad2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/sharded/too_old.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "description": "Multiple mongoses with default maxWireVersion of 0", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 2, - "maxWireVersion": 6 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid" - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - }, - "b:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Sharded", - "logicalSessionTimeoutMinutes": null, - "setName": null, - "compatible": false - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/compatible.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/compatible.json deleted file mode 100644 index ee6b847ade773ff9b4021f973792ad0501221e70..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/compatible.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "description": "Standalone with large maxWireVersion", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Standalone", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null, - "compatible": true - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_external_ip.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_external_ip.json deleted file mode 100644 index 44581501862f2a8a7f50f25ef158540933885701..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_external_ip.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "description": "Direct connection to RSPrimary via external IP", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_mongos.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_mongos.json deleted file mode 100644 index a7fa0794901e81ee83cfd3d6f41566ad8df1fb93..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_mongos.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "description": "Connect to mongos", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "msg": "isdbgrid", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Mongos", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rsarbiter.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rsarbiter.json deleted file mode 100644 index 3ef374d6f1e6443302519f58f6437bf43b8116f5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rsarbiter.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "description": "Connect to RSArbiter", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "arbiterOnly": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSArbiter", - "setName": "rs" - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rsprimary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rsprimary.json deleted file mode 100644 index bd5aaf7f044fc8c2634cffec170ec56c463e392e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rsprimary.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "description": "Connect to RSPrimary", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSPrimary", - "setName": "rs" - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rssecondary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rssecondary.json deleted file mode 100644 index 3b4f3c8c5adb96b804cd7c16e9d13fc991a48f44..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_rssecondary.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "description": "Connect to RSSecondary", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "secondary": true, - "hosts": [ - "a:27017", - "b:27017" - ], - "setName": "rs", - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "RSSecondary", - "setName": "rs" - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_slave.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_slave.json deleted file mode 100644 index a40debd1838ab31ff5783e1b5463da478760af67..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_slave.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "description": "Direct connection to slave", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": false, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Standalone", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_standalone.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_standalone.json deleted file mode 100644 index 2ecff9b9ae2a11acd6a8f521c44c5f7f9e59dee5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/direct_connection_standalone.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "description": "Connect to standalone", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Standalone", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/ls_timeout_standalone.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/ls_timeout_standalone.json deleted file mode 100644 index ae6c8ba11beaa76b8d4f947cc6694f3559e63683..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/ls_timeout_standalone.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "description": "Parse logicalSessionTimeoutMinutes from standalone", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "logicalSessionTimeoutMinutes": 7, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Standalone", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": 7, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/not_ok_response.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/not_ok_response.json deleted file mode 100644 index 06f71305dc01437ff63fad7ca9c1a08f0e2d6217..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/not_ok_response.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "description": "Handle a not-ok ismaster response", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ], - [ - "a:27017", - { - "ok": 0, - "ismaster": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/standalone_removed.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/standalone_removed.json deleted file mode 100644 index 4c363ffffb820a434618870b133b3dc351dc71db..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/standalone_removed.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "description": "Standalone removed from multi-server topology", - "uri": "mongodb://a,b", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "minWireVersion": 0, - "maxWireVersion": 6 - } - ] - ], - "outcome": { - "servers": { - "b:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "Unknown", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/too_new.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/too_new.json deleted file mode 100644 index 38e4621d60fd9d053db88000c87beac223d5eed0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/too_new.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "description": "Standalone with large minWireVersion", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "minWireVersion": 999, - "maxWireVersion": 1000 - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Standalone", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null, - "compatible": false - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/too_old.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/too_old.json deleted file mode 100644 index fbf68262c02f26b089e2f3dfd6d8764c0eebe128..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/too_old.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "description": "Standalone with default maxWireVersion of 0", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true - } - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Standalone", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null, - "compatible": false - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/unavailable_seed.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/unavailable_seed.json deleted file mode 100644 index e9cce02ebfd63cd5808643ecdac2c041c92c85b7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/single/unavailable_seed.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "description": "Unavailable seed", - "uri": "mongodb://a", - "phases": [ - { - "responses": [ - [ - "a:27017", - {} - ] - ], - "outcome": { - "servers": { - "a:27017": { - "type": "Unknown", - "setName": null - } - }, - "topologyType": "Single", - "logicalSessionTimeoutMinutes": null, - "setName": null - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name.json deleted file mode 100644 index 98a475e9a0ab178c04b2c86ab8df07b4ace4339a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "description": "Discover replica set name", - "phases": [ - { - "outcome": { - "servers": { - "a:27017": { - "setName": "rs", - "type": "RSPrimary" - } - }, - "setName": "rs", - "topologyType": "ReplicaSetWithPrimary" - }, - "responses": [ - [ - "a:27017", - { - "hosts": [ - "a:27017", - "b:27017" - ], - "ismaster": true, - "ok": 1, - "setName": "rs" - } - ], - [ - "b:27017", - { - "hosts": [ - "a:27017", - "b:27017" - ], - "ismaster": true, - "ok": 1, - "setName": "wrong" - } - ] - ] - } - ], - "uri": "mongodb://a,b" -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name_from_primary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name_from_primary.json deleted file mode 100644 index 00b1828f227fc56d270f1a4951d8ae1ae8d7833d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name_from_primary.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "description": "Discover replica set name from primary", - "phases": [ - { - "outcome": { - "servers": { - "b:27017": { - "setName": "rs", - "type": "RSPrimary" - } - }, - "setName": "rs", - "topologyType": "ReplicaSetWithPrimary" - }, - "responses": [ - [ - "b:27017", - { - "hosts": [ - "b:27017" - ], - "ismaster": true, - "ok": 1, - "setName": "rs" - } - ], - [ - "a:27017", - { - "ismaster": true, - "msg": "isdbgrid", - "ok": 1 - } - ] - ] - } - ], - "uri": "mongodb://a,b" -} diff --git a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name_from_secondary.json b/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name_from_secondary.json deleted file mode 100644 index ea1892cdbb67893febdb938610c63432e8052ec8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_discovery_and_monitoring/supplemental/discover_rs_name_from_secondary.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "description": "Discover replica set name from secondary", - "phases": [ - { - "outcome": { - "servers": { - "b:27017": { - "setName": "rs", - "type": "RSSecondary" - } - }, - "setName": "rs", - "topologyType": "ReplicaSetNoPrimary" - }, - "responses": [ - [ - "b:27017", - { - "hosts": [ - "b:27017" - ], - "ismaster": false, - "ok": 1, - "secondary": true, - "setName": "rs" - } - ], - [ - "a:27017", - { - "ismaster": true, - "msg": "isdbgrid", - "ok": 1 - } - ] - ] - } - ], - "uri": "mongodb://a,b" -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/first_value.json b/lib/mongoc/libmongoc/tests/json/server_selection/rtt/first_value.json deleted file mode 100644 index 421944da3660a4aceafc8a4f8bfb16cdaa227258..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/first_value.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "avg_rtt_ms": "NULL", - "new_rtt_ms": 10, - "new_avg_rtt": 10 -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/first_value_zero.json b/lib/mongoc/libmongoc/tests/json/server_selection/rtt/first_value_zero.json deleted file mode 100644 index d5bfc41b25dea7e0e24829f422f5e58af4c13c62..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/first_value_zero.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "avg_rtt_ms": "NULL", - "new_rtt_ms": 0, - "new_avg_rtt": 0 -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_1.json b/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_1.json deleted file mode 100644 index ed6a80ce29b8509a2229eb947d8ec7522c054367..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_1.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "avg_rtt_ms": 0, - "new_rtt_ms": 5, - "new_avg_rtt": 1 -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_2.json b/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_2.json deleted file mode 100644 index ccb5a0173b645a1628a3ba0ac35263ef78df7517..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_2.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "avg_rtt_ms": 3.1, - "new_rtt_ms": 36, - "new_avg_rtt": 9.68 -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_3.json b/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_3.json deleted file mode 100644 index 6921c94d36c047ec8f270853cf8890052db24dca..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_3.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "avg_rtt_ms": 9.12, - "new_rtt_ms": 9.12, - "new_avg_rtt": 9.12 -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_4.json b/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_4.json deleted file mode 100644 index d9ce3800b826cca216f82657878ce897e5464215..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_4.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "avg_rtt_ms": 1, - "new_rtt_ms": 1000, - "new_avg_rtt": 200.8 -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_5.json b/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_5.json deleted file mode 100644 index 9ae33bc1434cd7509a25c77263d81ebf99888be0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/rtt/value_test_5.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "avg_rtt_ms": 0, - "new_rtt_ms": 0.25, - "new_avg_rtt": 0.05 -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest.json deleted file mode 100644 index aa48679e866339dd5680a566ee4adbc350e7ed27..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest_multiple.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest_multiple.json deleted file mode 100644 index 1fcfd52a477a936456abcdf33bd3d0cfc390fde8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest_multiple.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 10, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 20, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 10, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 20, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 10, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 20, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest_non_matching.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest_non_matching.json deleted file mode 100644 index b72895d8a83692b7ea24e2fe5f35bec96d8a7076..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Nearest_non_matching.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - { - "data_center": "sf" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimary.json deleted file mode 100644 index 4d286af830f1e76351686b2cc1d71fb11b43173d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimary.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "PossiblePrimary" - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Primary", - "tag_sets": [ - {} - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimaryNearest.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimaryNearest.json deleted file mode 100644 index bf9c70b420e531ddcda15decd92c202b08190340..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimaryNearest.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "PossiblePrimary" - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - {} - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Primary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Primary.json deleted file mode 100644 index f0f3fa9ea15500c6d376a49226c3a6e49e8f8f5e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Primary.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Primary" - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred.json deleted file mode 100644 index f87ef4f6170c5e1f6290bb4b2b7c45f93d818cdb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "PrimaryPreferred", - "tag_sets": [ - {} - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.json deleted file mode 100644 index ee962299270be106e648a9fab68a0441c0faa032..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "PrimaryPreferred", - "tag_sets": [ - { - "data_center": "sf" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary.json deleted file mode 100644 index 3b8f1e97cd6daf818152645a15dede1780dca3aa..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Secondary", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred.json deleted file mode 100644 index c3142ec1154f03c42be548beeea7965cd9f592ef..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.json deleted file mode 100644 index a2c18bb7d2246c13b40f18f49c44588da1cfb4ca..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "sf" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags.json deleted file mode 100644 index b319918e9265a3bedf1554b98bb3bda1c4b562a4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "rack": "one", - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "rack": "two", - "data_center": "sf" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Secondary", - "tag_sets": [ - { - "data_center": "nyc", - "rack": "one" - }, - { - "other_tag": "doesntexist" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "rack": "one", - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "rack": "one", - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags2.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags2.json deleted file mode 100644 index 8f64d95ecb8ad01ea27f3a758ef263d56c0930d5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags2.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "rack": "one", - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "rack": "two", - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Secondary", - "tag_sets": [ - { - "data_center": "nyc", - "rack": "one" - }, - { - "other_tag": "doesntexist" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "rack": "one", - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "rack": "one", - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_non_matching.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_non_matching.json deleted file mode 100644 index 4931e1019a421d08546c606183ea9f430f725f16..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/read/Secondary_non_matching.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Secondary", - "tag_sets": [ - { - "data_center": "sf" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/write/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/write/SecondaryPreferred.json deleted file mode 100644 index e136cf12a4f09a372535af4020a68561097f5b9c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetNoPrimary/write/SecondaryPreferred.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetNoPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "write", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest.json deleted file mode 100644 index cfe4965938d7b42aa9ebd91e357b5371c75e877e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest_multiple.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest_multiple.json deleted file mode 100644 index 67296d434fecca53e9e11a1517dc187a751ae218..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest_multiple.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 10, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 20, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 10, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 20, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 10, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 20, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest_non_matching.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest_non_matching.json deleted file mode 100644 index a3a85c9a83e8b4d9dd0b47caedec6a30d02bd31e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Nearest_non_matching.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - { - "data_center": "sf" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Primary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Primary.json deleted file mode 100644 index 8da1482e96726ec08bc0e765f0e655d75221b4a7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Primary.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Primary" - }, - "suitable_servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred.json deleted file mode 100644 index 306171f3a20aabcd45322c8006831740ac2ba605..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "PrimaryPreferred", - "tag_sets": [ - {} - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.json deleted file mode 100644 index 722f1cfb1a99c3917c47474c0d34186bc42e4ff8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "PrimaryPreferred", - "tag_sets": [ - { - "data_center": "sf" - } - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Secondary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Secondary.json deleted file mode 100644 index 23864a278c418a992631a94011370de9a96a3d38..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Secondary.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Secondary", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred.json deleted file mode 100644 index d07c24218d399b9fa99a14d80e1787ea12612c09..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.json deleted file mode 100644 index f893cc9f828e2b6e09e7f45ff3a346a04d81f9c0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "sf" - } - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.json deleted file mode 100644 index a74a2dbf33beef5dcf19318a1f90ec0a7d5914fd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "sf" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Secondary_non_matching.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Secondary_non_matching.json deleted file mode 100644 index 12721806665bf66e73ced850ce10de0e1dd89a3c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/read/Secondary_non_matching.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Secondary", - "tag_sets": [ - { - "data_center": "sf" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/write/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/write/SecondaryPreferred.json deleted file mode 100644 index 65ab3dc64048376f1461dcffb6228d9b199e8e67..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/ReplicaSetWithPrimary/write/SecondaryPreferred.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "topology_description": { - "type": "ReplicaSetWithPrimary", - "servers": [ - { - "address": "b:27017", - "avg_rtt_ms": 5, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "c:27017", - "avg_rtt_ms": 100, - "type": "RSSecondary", - "tags": { - "data_center": "nyc" - } - }, - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] - }, - "operation": "write", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "avg_rtt_ms": 26, - "type": "RSPrimary", - "tags": { - "data_center": "nyc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Nearest.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Nearest.json deleted file mode 100644 index 705a784a0b1c2286505bdab1a8ec6a91f9eda811..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Nearest.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Primary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Primary.json deleted file mode 100644 index 7a321be2bbde9892bcde532fe5f146c696b62ced..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Primary.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Primary" - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/PrimaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/PrimaryPreferred.json deleted file mode 100644 index e9bc1421f955def5a4c33feaaf6de87768f525a8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/PrimaryPreferred.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "PrimaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Secondary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Secondary.json deleted file mode 100644 index 49813f7b9e36983043d75ee39a20b766577d522d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/Secondary.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "Secondary", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/SecondaryPreferred.json deleted file mode 100644 index 62fa13f297d4612e0ff33c2884988fc36393dd21..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/read/SecondaryPreferred.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Nearest.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Nearest.json deleted file mode 100644 index aef7f02ec7046b2bbf2aec9d0fa53fd726064ae8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Nearest.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "write", - "read_preference": { - "mode": "Nearest", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Primary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Primary.json deleted file mode 100644 index f6ce2e75c1b661f58d3be4520192dbcef2b04113..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Primary.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "write", - "read_preference": { - "mode": "Primary" - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/PrimaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/PrimaryPreferred.json deleted file mode 100644 index 25f56a53596cd0b46353cbe0ced0246920c27318..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/PrimaryPreferred.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "write", - "read_preference": { - "mode": "PrimaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Secondary.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Secondary.json deleted file mode 100644 index 1fa026f716f5e90af57afb4269e5ee9f4f3d9ee3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/Secondary.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "write", - "read_preference": { - "mode": "Secondary", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/SecondaryPreferred.json deleted file mode 100644 index f9467472aa82cf30dc8a14154c0da23aa029c13f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Sharded/write/SecondaryPreferred.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "topology_description": { - "type": "Sharded", - "servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ] - }, - "operation": "write", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - }, - { - "address": "h:27017", - "avg_rtt_ms": 35, - "type": "Mongos" - } - ], - "in_latency_window": [ - { - "address": "g:27017", - "avg_rtt_ms": 5, - "type": "Mongos" - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Single/read/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Single/read/SecondaryPreferred.json deleted file mode 100644 index e60496dfdfe7bf988125c8802bc3afbb4058bc37..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Single/read/SecondaryPreferred.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "topology_description": { - "type": "Single", - "servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "Standalone", - "tags": { - "data_center": "dc" - } - } - ] - }, - "operation": "read", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "Standalone", - "tags": { - "data_center": "dc" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "Standalone", - "tags": { - "data_center": "dc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Single/write/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Single/write/SecondaryPreferred.json deleted file mode 100644 index 34fe91d5a21f89629b7af5fe2a7222aad68b5ebe..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Single/write/SecondaryPreferred.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "topology_description": { - "type": "Single", - "servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "Standalone", - "tags": { - "data_center": "dc" - } - } - ] - }, - "operation": "write", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "Standalone", - "tags": { - "data_center": "dc" - } - } - ], - "in_latency_window": [ - { - "address": "a:27017", - "avg_rtt_ms": 5, - "type": "Standalone", - "tags": { - "data_center": "dc" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Unknown/read/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Unknown/read/SecondaryPreferred.json deleted file mode 100644 index 0ae8075fba386bb0e1bf9c84c90ca9d85a21f077..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Unknown/read/SecondaryPreferred.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "topology_description": { - "type": "Unknown", - "servers": [] - }, - "operation": "read", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Unknown/write/SecondaryPreferred.json b/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Unknown/write/SecondaryPreferred.json deleted file mode 100644 index a70eece62cd14652de9a979e6ded6151fe58f70c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/server_selection/server_selection/Unknown/write/SecondaryPreferred.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "topology_description": { - "type": "Unknown", - "servers": [] - }, - "operation": "write", - "read_preference": { - "mode": "SecondaryPreferred", - "tag_sets": [ - { - "data_center": "nyc" - } - ] - }, - "suitable_servers": [], - "in_latency_window": [] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/abort.json b/lib/mongoc/libmongoc/tests/json/transactions/abort.json deleted file mode 100644 index 821a15afbe1fc14b0f18d994a7eff035f900f5ae..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/abort.json +++ /dev/null @@ -1,620 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "abort", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": { - "afterClusterTime": 42 - }, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "implicit abort", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "two aborts", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "abortTransaction", - "object": "session0", - "result": { - "errorContains": "cannot call abortTransaction twice" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abort without start", - "operations": [ - { - "name": "abortTransaction", - "object": "session0", - "result": { - "errorContains": "no transaction started" - } - } - ], - "expectations": [], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abort directly after no-op commit", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "abortTransaction", - "object": "session0", - "result": { - "errorContains": "Cannot call abortTransaction after calling commitTransaction" - } - } - ], - "expectations": [], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abort directly after commit", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "abortTransaction", - "object": "session0", - "result": { - "errorContains": "Cannot call abortTransaction after calling commitTransaction" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "abort ignores TransactionAborted", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorCodeName": "NoSuchTransaction", - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abort does not apply writeConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": 10 - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/bulk.json b/lib/mongoc/libmongoc/tests/json/transactions/bulk.json deleted file mode 100644 index ea4571c1d50b12a38b5006cdfb230cc604a2b9d3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/bulk.json +++ /dev/null @@ -1,539 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "bulk", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "deleteOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "deletedCount": 1 - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$set": { - "x": 1 - } - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 2 - }, - "update": { - "$set": { - "x": 2 - } - }, - "upsert": true - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 3 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 4 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 5 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 6 - } - } - }, - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 7 - } - } - }, - { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 1 - }, - "replacement": { - "y": 1 - } - } - }, - { - "name": "replaceOne", - "arguments": { - "filter": { - "_id": 2 - }, - "replacement": { - "y": 2 - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 3 - } - } - }, - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 4 - } - } - }, - { - "name": "updateMany", - "arguments": { - "filter": { - "_id": { - "$gte": 2 - } - }, - "update": { - "$set": { - "z": 1 - } - } - } - }, - { - "name": "deleteMany", - "arguments": { - "filter": { - "_id": { - "$gte": 6 - } - } - } - } - ] - }, - "result": { - "deletedCount": 4, - "insertedCount": 6, - "insertedIds": { - "0": 1, - "3": 3, - "4": 4, - "5": 5, - "6": 6, - "7": 7 - }, - "matchedCount": 7, - "modifiedCount": 7, - "upsertedCount": 1, - "upsertedIds": { - "2": 2 - } - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": 1 - }, - "limit": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 1 - }, - "u": { - "$set": { - "x": 1 - } - }, - "multi": false, - "upsert": false - }, - { - "q": { - "_id": 2 - }, - "u": { - "$set": { - "x": 2 - } - }, - "multi": false, - "upsert": true - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - }, - { - "_id": 5 - }, - { - "_id": 6 - }, - { - "_id": 7 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 1 - }, - "u": { - "y": 1 - }, - "multi": false, - "upsert": false - }, - { - "q": { - "_id": 2 - }, - "u": { - "y": 2 - }, - "multi": false, - "upsert": false - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": 3 - }, - "limit": 1 - }, - { - "q": { - "_id": 4 - }, - "limit": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": { - "$gte": 2 - } - }, - "u": { - "$set": { - "z": 1 - } - }, - "multi": true, - "upsert": false - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": { - "$gte": 6 - } - }, - "limit": 0 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "y": 1 - }, - { - "_id": 2, - "y": 2, - "z": 1 - }, - { - "_id": 5, - "z": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/causal-consistency.json b/lib/mongoc/libmongoc/tests/json/transactions/causal-consistency.json deleted file mode 100644 index f1ca3d83a8d09c3a94b23a0ec28dc3543bddc25a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/causal-consistency.json +++ /dev/null @@ -1,314 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1, - "count": 0 - } - ], - "tests": [ - { - "description": "causal consistency", - "clientOptions": { - "retryWrites": false - }, - "operations": [ - { - "name": "updateOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "count": 1 - } - }, - "upsert": false - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "updateOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "count": 1 - } - }, - "upsert": false - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 1 - }, - "u": { - "$inc": { - "count": 1 - } - }, - "multi": false, - "upsert": false - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": null, - "txnNumber": null, - "startTransaction": null, - "autocommit": null, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 1 - }, - "u": { - "$inc": { - "count": 1 - } - }, - "multi": false, - "upsert": false - } - ], - "ordered": true, - "readConcern": { - "afterClusterTime": 42 - }, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "count": 2 - } - ] - } - } - }, - { - "description": "causal consistency disabled", - "clientOptions": { - "retryWrites": false - }, - "sessionOptions": { - "session0": { - "causalConsistency": false - } - }, - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "updateOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "count": 1 - } - }, - "upsert": false - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": null, - "autocommit": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 1 - }, - "u": { - "$inc": { - "count": 1 - } - }, - "multi": false, - "upsert": false - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1, - "count": 1 - }, - { - "_id": 2 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/commit.json b/lib/mongoc/libmongoc/tests/json/transactions/commit.json deleted file mode 100644 index faa39a65f1890b1f11dbb3b46d20eeb2754d8e2f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/commit.json +++ /dev/null @@ -1,925 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "commit", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "readConcern": { - "afterClusterTime": 42 - }, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "rerun commit after empty transaction", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "multiple commits in a row", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "write concern error on commit", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": 10 - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commit without start", - "operations": [ - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorContains": "no transaction started" - } - } - ], - "expectations": [], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "commit after no-op abort", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorContains": "Cannot call commitTransaction after calling abortTransaction" - } - } - ], - "expectations": [], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "commit after abort", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorContains": "Cannot call commitTransaction after calling abortTransaction" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ] - }, - { - "description": "multiple commits after empty transaction", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": { - "afterClusterTime": 42 - }, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "reset session state commit", - "clientOptions": { - "retryWrites": false - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorContains": "no transaction started" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": null, - "startTransaction": null, - "autocommit": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "reset session state abort", - "clientOptions": { - "retryWrites": false - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0", - "result": { - "errorContains": "no transaction started" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": null, - "startTransaction": null, - "autocommit": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 2 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/count.json b/lib/mongoc/libmongoc/tests/json/transactions/count.json deleted file mode 100644 index 169296416a4f38ab85f1d61c448e4aef7f80f71f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/count.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0.2", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "tests": [ - { - "description": "count", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "count", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorCodeName": "OperationNotSupportedInTransaction", - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "count": "test", - "query": { - "_id": 1 - }, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "count", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/delete.json b/lib/mongoc/libmongoc/tests/json/transactions/delete.json deleted file mode 100644 index 65b83270392bb9d985dc5d269ed1bb23f02ba61c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/delete.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - }, - { - "_id": 5 - } - ], - "tests": [ - { - "description": "delete", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "deleteOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "deletedCount": 1 - } - }, - { - "name": "deleteMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$lte": 3 - } - } - }, - "result": { - "deletedCount": 2 - } - }, - { - "name": "deleteOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 4 - } - }, - "result": { - "deletedCount": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": 1 - }, - "limit": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": { - "$lte": 3 - } - }, - "limit": 0 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": 4 - }, - "limit": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 5 - } - ] - } - } - }, - { - "description": "collection writeConcern ignored for delete", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "deleteOne", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "deletedCount": 1 - } - }, - { - "name": "deleteMany", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$lte": 3 - } - } - }, - "result": { - "deletedCount": 2 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": 1 - }, - "limit": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": { - "$lte": 3 - } - }, - "limit": 0 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/error-labels.json b/lib/mongoc/libmongoc/tests/json/transactions/error-labels.json deleted file mode 100644 index 3e2451ade8963886a650083c2a61ab51513af0e1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/error-labels.json +++ /dev/null @@ -1,1963 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "DuplicateKey errors do not contain transient label", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "session": "session0", - "documents": [ - { - "_id": 1 - }, - { - "_id": 1 - } - ] - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - }, - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "NotMaster errors contain transient label", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 10107 - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "WriteConflict errors contain transient label", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 112 - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "NoSuchTransaction errors contain transient label", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 251 - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "NoSuchTransaction errors on commit contain transient label", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 251 - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "add transient label to connection errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 4 - }, - "data": { - "failCommands": [ - "insert", - "find", - "aggregate", - "distinct" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "session": "session0" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "test", - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "cursor": {}, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "test", - "key": "_id", - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "distinct", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "add unknown commit label to connection errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "add unknown commit label to retryable commit errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 11602 - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "add unknown commit label to writeConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "add unknown commit label to writeConcernError WriteConcernFailed", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 64, - "errmsg": "multiple errors reported" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "add unknown commit label to writeConcernError WriteConcernFailed with wtimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 64, - "codeName": "WriteConcernFailed", - "errmsg": "waiting for replication timed out", - "errInfo": { - "wtimeout": true - } - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "omit unknown commit label to writeConcernError UnsatisfiableWriteConcern", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 100, - "errmsg": "Not enough data-bearing nodes" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "omit unknown commit label to writeConcernError UnknownReplWriteConcern", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 79, - "errmsg": "No write concern mode named 'blah' found in replica set configuration" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "do not add unknown commit label to MaxTimeMSExpired inside transactions", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 50 - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "maxTimeMS": 60000, - "session": "session0" - }, - "result": { - "errorLabelsOmit": [ - "UnknownTransactionCommitResult", - "TransientTransactionError" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "cursor": {}, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "maxTimeMS": 60000 - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "add unknown commit label to MaxTimeMSExpired", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 50 - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - }, - "maxCommitTimeMS": 60000 - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - }, - "maxTimeMS": 60000 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "maxTimeMS": 60000 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "add unknown commit label to writeConcernError MaxTimeMSExpired", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 50, - "errmsg": "operation exceeded time limit" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - }, - "maxCommitTimeMS": 60000 - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - }, - "maxTimeMS": 60000 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "maxTimeMS": 60000 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/errors.json b/lib/mongoc/libmongoc/tests/json/transactions/errors.json deleted file mode 100644 index 5fc4905e8c32edac6ab467c0cccd3a26e443766b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/errors.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "start insert start", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "startTransaction", - "object": "session0", - "result": { - "errorContains": "transaction already in progress" - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ] - }, - { - "description": "start twice", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0", - "result": { - "errorContains": "transaction already in progress" - } - } - ] - }, - { - "description": "commit and start twice", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0", - "result": { - "errorContains": "transaction already in progress" - } - } - ] - }, - { - "description": "write conflict commit", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "startTransaction", - "object": "session1" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session1", - "document": { - "_id": 1 - } - }, - "result": { - "errorCodeName": "WriteConflict", - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session1", - "result": { - "errorCodeName": "NoSuchTransaction", - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - } - ] - }, - { - "description": "write conflict abort", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "startTransaction", - "object": "session1" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session1", - "document": { - "_id": 1 - } - }, - "result": { - "errorCodeName": "WriteConflict", - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "abortTransaction", - "object": "session1" - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/findOneAndDelete.json b/lib/mongoc/libmongoc/tests/json/transactions/findOneAndDelete.json deleted file mode 100644 index d82657a9f533c72813b9b1e9409fb48339e9d699..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/findOneAndDelete.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "tests": [ - { - "description": "findOneAndDelete", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndDelete", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - } - }, - "result": { - "_id": 3 - } - }, - { - "name": "findOneAndDelete", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 4 - } - }, - "result": null - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 3 - }, - "remove": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 4 - }, - "remove": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "collection writeConcern ignored for findOneAndDelete", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "findOneAndDelete", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - } - }, - "result": { - "_id": 3 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 3 - }, - "remove": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/findOneAndReplace.json b/lib/mongoc/libmongoc/tests/json/transactions/findOneAndReplace.json deleted file mode 100644 index 7a54ca3433e7da2ef1027feb792858114690f90b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/findOneAndReplace.json +++ /dev/null @@ -1,255 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "tests": [ - { - "description": "findOneAndReplace", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndReplace", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "replacement": { - "x": 1 - }, - "returnDocument": "Before" - }, - "result": { - "_id": 3 - } - }, - { - "name": "findOneAndReplace", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 4 - }, - "replacement": { - "x": 1 - }, - "upsert": true, - "returnDocument": "After" - }, - "result": { - "_id": 4, - "x": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 3 - }, - "update": { - "x": 1 - }, - "new": false, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 4 - }, - "update": { - "x": 1 - }, - "new": true, - "upsert": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3, - "x": 1 - }, - { - "_id": 4, - "x": 1 - } - ] - } - } - }, - { - "description": "collection writeConcern ignored for findOneAndReplace", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "findOneAndReplace", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "replacement": { - "x": 1 - }, - "returnDocument": "Before" - }, - "result": { - "_id": 3 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 3 - }, - "update": { - "x": 1 - }, - "new": false, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/findOneAndUpdate.json b/lib/mongoc/libmongoc/tests/json/transactions/findOneAndUpdate.json deleted file mode 100644 index 7af54ba808102308048b22b86959a0cb49443393..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/findOneAndUpdate.json +++ /dev/null @@ -1,413 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "tests": [ - { - "description": "findOneAndUpdate", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - }, - "result": { - "_id": 3 - } - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true, - "returnDocument": "After" - }, - "result": { - "_id": 4, - "x": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - }, - "result": { - "_id": 3, - "x": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - }, - "result": { - "_id": 3, - "x": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "new": false, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "new": true, - "upsert": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "new": false, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "afterClusterTime": 42 - }, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "new": false, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "afterClusterTime": 42 - }, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3, - "x": 2 - }, - { - "_id": 4, - "x": 1 - } - ] - } - } - }, - { - "description": "collection writeConcern ignored for findOneAndUpdate", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - }, - "result": { - "_id": 3 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "new": false, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/insert.json b/lib/mongoc/libmongoc/tests/json/transactions/insert.json deleted file mode 100644 index f26e7c2a7636548f2506e7da84fc07eca12731b7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/insert.json +++ /dev/null @@ -1,648 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "insert", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 2, - "1": 3 - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 4 - } - }, - "result": { - "insertedId": 4 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 5 - } - }, - "result": { - "insertedId": 5 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 4 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 5 - } - ], - "ordered": true, - "readConcern": { - "afterClusterTime": 42 - }, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - }, - { - "_id": 5 - } - ] - } - } - }, - { - "description": "insert with session1", - "operations": [ - { - "name": "startTransaction", - "object": "session1" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session1", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "session": "session1" - }, - "result": { - "insertedIds": { - "0": 2, - "1": 3 - } - } - }, - { - "name": "commitTransaction", - "object": "session1" - }, - { - "name": "startTransaction", - "object": "session1" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session1", - "document": { - "_id": 4 - } - }, - "result": { - "insertedId": 4 - } - }, - { - "name": "abortTransaction", - "object": "session1" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session1", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "ordered": true, - "lsid": "session1", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session1", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 4 - } - ], - "ordered": true, - "readConcern": { - "afterClusterTime": 42 - }, - "lsid": "session1", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session1", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ] - } - } - }, - { - "description": "collection writeConcern without transaction", - "clientOptions": { - "retryWrites": false - }, - "operations": [ - { - "name": "insertOne", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": null, - "startTransaction": null, - "autocommit": null, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "collection writeConcern ignored for insert", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "documents": [ - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 2, - "1": 3 - } - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/isolation.json b/lib/mongoc/libmongoc/tests/json/transactions/isolation.json deleted file mode 100644 index f16b28a5e6c09d5271c6349e099231c272a7987a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/isolation.json +++ /dev/null @@ -1,225 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "one transaction", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session1", - "filter": { - "_id": 1 - } - }, - "result": [] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": [] - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session1", - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1 - } - ] - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "two transactions", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session1" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session1", - "filter": { - "_id": 1 - } - }, - "result": [] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": [] - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session1", - "filter": { - "_id": 1 - } - }, - "result": [] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "result": [ - { - "_id": 1 - } - ] - }, - { - "name": "commitTransaction", - "object": "session1" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/mongos-pin-auto.json b/lib/mongoc/libmongoc/tests/json/transactions/mongos-pin-auto.json deleted file mode 100644 index f6ede52687c7f802a6d6eeaa37a74e254ac34876..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/mongos-pin-auto.json +++ /dev/null @@ -1,4814 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "remain pinned after non-transient Interrupted error on insertOne", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 4 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ], - "errorCodeName": "Interrupted" - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 3 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 4 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ] - } - } - }, - { - "description": "unpin after transient error within a transaction", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 4 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 3 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 4 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null, - "recoveryToken": 42 - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on insertOne insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 4 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on insertMany insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "session": "session0", - "documents": [ - { - "_id": 4 - }, - { - "_id": 5 - } - ] - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on updateOne update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "updateOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on replaceOne update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "replaceOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "replacement": { - "y": 1 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on updateMany update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "updateMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 1 - } - }, - "update": { - "$set": { - "z": 1 - } - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on deleteOne delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "deleteOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on deleteMany delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "deleteMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 1 - } - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on findOneAndDelete findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "findOneAndDelete", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on findOneAndUpdate findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on findOneAndReplace findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "findOneAndReplace", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "replacement": { - "y": 1 - }, - "returnDocument": "Before" - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on bulkWrite insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1 - } - } - } - ] - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on bulkWrite update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$set": { - "x": 1 - } - } - } - } - ] - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on bulkWrite delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - } - ] - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on find find", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on countDocuments aggregate", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "session": "session0", - "filter": {} - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on aggregate aggregate", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "session": "session0", - "pipeline": [] - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on distinct distinct", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient Interrupted error on runCommand insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 11601 - } - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "insert", - "arguments": { - "session": "session0", - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ] - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on insertOne insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 4 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on insertOne insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 4 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on insertMany insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "session": "session0", - "documents": [ - { - "_id": 4 - }, - { - "_id": 5 - } - ] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on insertMany insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "session": "session0", - "documents": [ - { - "_id": 4 - }, - { - "_id": 5 - } - ] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on updateOne update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "closeConnection": true - } - } - } - }, - { - "name": "updateOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on updateOne update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "updateOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on replaceOne update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "closeConnection": true - } - } - } - }, - { - "name": "replaceOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "replacement": { - "y": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on replaceOne update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "replaceOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "replacement": { - "y": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on updateMany update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "closeConnection": true - } - } - } - }, - { - "name": "updateMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 1 - } - }, - "update": { - "$set": { - "z": 1 - } - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on updateMany update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "updateMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 1 - } - }, - "update": { - "$set": { - "z": 1 - } - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on deleteOne delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "closeConnection": true - } - } - } - }, - { - "name": "deleteOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on deleteOne delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "deleteOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on deleteMany delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "closeConnection": true - } - } - } - }, - { - "name": "deleteMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 1 - } - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on deleteMany delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "deleteMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 1 - } - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on findOneAndDelete findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "closeConnection": true - } - } - } - }, - { - "name": "findOneAndDelete", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on findOneAndDelete findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "findOneAndDelete", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on findOneAndUpdate findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "closeConnection": true - } - } - } - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on findOneAndUpdate findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on findOneAndReplace findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "closeConnection": true - } - } - } - }, - { - "name": "findOneAndReplace", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "replacement": { - "y": 1 - }, - "returnDocument": "Before" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on findOneAndReplace findAndModify", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "findAndModify" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "findOneAndReplace", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "replacement": { - "y": 1 - }, - "returnDocument": "Before" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on bulkWrite insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1 - } - } - } - ] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on bulkWrite insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1 - } - } - } - ] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on bulkWrite update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "closeConnection": true - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$set": { - "x": 1 - } - } - } - } - ] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on bulkWrite update", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "update" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$set": { - "x": 1 - } - } - } - } - ] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on bulkWrite delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "closeConnection": true - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - } - ] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on bulkWrite delete", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "delete" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "deleteOne", - "arguments": { - "filter": { - "_id": 1 - } - } - } - ] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on find find", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true - } - } - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on find find", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on countDocuments aggregate", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - } - } - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "session": "session0", - "filter": {} - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on countDocuments aggregate", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "session": "session0", - "filter": {} - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on aggregate aggregate", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "closeConnection": true - } - } - } - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "session": "session0", - "pipeline": [] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on aggregate aggregate", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "aggregate" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "session": "session0", - "pipeline": [] - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on distinct distinct", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "closeConnection": true - } - } - } - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on distinct distinct", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "distinct" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient connection error on runCommand insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "insert", - "arguments": { - "session": "session0", - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ] - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient ShutdownInProgress error on runCommand insert", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "errorCode": 91 - } - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "insert", - "arguments": { - "session": "session0", - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ] - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "assertSessionUnpinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/mongos-recovery-token.json b/lib/mongoc/libmongoc/tests/json/transactions/mongos-recovery-token.json deleted file mode 100644 index 50c7349c1e656be34021af7bd83eb722b399a87f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/mongos-recovery-token.json +++ /dev/null @@ -1,506 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "commitTransaction explicit retries include recoveryToken", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction retry succeeds on new mongos", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - } - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - }, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction retry fails on new mongos", - "useMultipleMongoses": true, - "clientOptions": { - "heartbeatFrequencyMS": 30000 - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 7 - }, - "data": { - "failCommands": [ - "commitTransaction", - "isMaster" - ], - "closeConnection": true - } - } - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ], - "errorCodeName": "NoSuchTransaction" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction sends recoveryToken", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "closeConnection": true - } - } - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null, - "recoveryToken": 42 - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null, - "recoveryToken": 42 - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/opts.json b/lib/mongoc/libmongoc/tests/json/transactions/opts.json deleted file mode 100644 index e92a00916a20ba6712ed93b2c0fad70d9e07f6a0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/opts.json +++ /dev/null @@ -1,664 +0,0 @@ -{ - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "aggregate fails with secondary read preference from transaction options", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Secondary" - } - } - } - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - } - ] - }, - { - "description": "aggregate fails with explicit secondary read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0", - "readPreference": { - "mode": "Secondary" - } - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - } - ] - }, - { - "description": "find fails with secondary read preference from transaction options", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Secondary" - } - } - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0" - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - } - ] - }, - { - "description": "find fails with explicit secondary read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "readPreference": { - "mode": "Secondary" - } - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - } - ] - }, - { - "description": "aggregate succeeds with explicit primary read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0", - "readPreference": { - "mode": "Primary" - } - }, - "result": [] - } - ] - }, - { - "description": "find succeeds with explicit primary read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "readPreference": { - "mode": "Primary" - } - }, - "result": [] - } - ] - }, - { - "description": "distinct succeeds with explicit primary read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": [] - } - ] - }, - { - "description": "countDocuments succeeds with explicit primary read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "session": "session0", - "filter": {}, - "readPreference": { - "mode": "Primary" - } - }, - "result": 0 - } - ] - }, - { - "description": "aggregate fails with explicit read concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0", - "readConcern": { - "level": "majority" - } - }, - "result": { - "errorContains": "cannot set read concern after starting transaction" - } - } - ] - }, - { - "description": "find fails with explicit read concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "readConcern": { - "level": "majority" - } - }, - "result": { - "errorContains": "cannot set read concern after starting transaction" - } - } - ] - }, - { - "description": "find fails with collection read concern and explicit read concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "find", - "collectionOptions": { - "readConcern": { - "level": "foo" - } - }, - "object": "collection", - "arguments": { - "session": "session0", - "readConcern": { - "level": "majority" - } - }, - "result": { - "errorContains": "cannot set read concern after starting transaction" - } - } - ] - }, - { - "description": "runCommand fails with explicit read concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "runCommand", - "object": "database", - "command_name": "find", - "arguments": { - "session": "session0", - "command": { - "find": "test" - }, - "readConcern": { - "level": "majority" - } - }, - "result": { - "errorContains": "cannot set read concern after starting transaction" - } - } - ] - }, - { - "description": "insertOne fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "insertMany fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "session": "session0", - "documents": [ - { - "_id": 1 - } - ], - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "updateOne fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "updateOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "updateMany fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "updateMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gt": 1 - } - }, - "update": { - "$inc": { - "x": 1 - } - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "replaceOne fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "replaceOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "x": 1 - }, - "replacement": { - "y": 1 - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "deleteOne fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "deleteOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "deleteMany fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "deleteMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "bulkWrite fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "session": "session0", - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1 - } - } - }, - { - "name": "updateOne", - "arguments": { - "filter": { - "_id": 1 - }, - "update": { - "$set": { - "x": 1 - } - } - } - } - ], - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "findOneAndUpdate fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "findOneAndReplace fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndReplace", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "replacement": { - "x": 1 - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "findOneAndDelete fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndDelete", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 3 - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - }, - { - "description": "runCommand fails with explicit write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "runCommand", - "object": "database", - "command_name": "insert", - "arguments": { - "session": "session0", - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ] - }, - "writeConcern": { - "w": 1 - } - }, - "result": { - "errorContains": "cannot set write concern after starting transaction" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/pin-mongos.json b/lib/mongoc/libmongoc/tests/json/transactions/pin-mongos.json deleted file mode 100644 index 586616ebab0745986ed277741b6902e63555d54b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/pin-mongos.json +++ /dev/null @@ -1,1228 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "countDocuments", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "distinct", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": [ - 1, - 2 - ] - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": [ - 1, - 2 - ] - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": [ - 1, - 2 - ] - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": [ - 1, - 2 - ] - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": [ - 1, - 2 - ] - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": [ - 1, - 2 - ] - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": [ - 1, - 2 - ] - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "fieldName": "_id", - "session": "session0" - }, - "result": [ - 1, - 2 - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "find", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": [ - { - "_id": 2 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": [ - { - "_id": 2 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": [ - { - "_id": 2 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": [ - { - "_id": 2 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": [ - { - "_id": 2 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": [ - { - "_id": 2 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": [ - { - "_id": 2 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 2 - }, - "session": "session0" - }, - "result": [ - { - "_id": 2 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "insertOne", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 3 - }, - "session": "session0" - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 4 - }, - "session": "session0" - }, - "result": { - "insertedId": 4 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 5 - }, - "session": "session0" - }, - "result": { - "insertedId": 5 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 6 - }, - "session": "session0" - }, - "result": { - "insertedId": 6 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 7 - }, - "session": "session0" - }, - "result": { - "insertedId": 7 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 8 - }, - "session": "session0" - }, - "result": { - "insertedId": 8 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 9 - }, - "session": "session0" - }, - "result": { - "insertedId": 9 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 10 - }, - "session": "session0" - }, - "result": { - "insertedId": 10 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - }, - { - "_id": 5 - }, - { - "_id": 6 - }, - { - "_id": 7 - }, - { - "_id": 8 - }, - { - "_id": 9 - }, - { - "_id": 10 - } - ] - } - } - }, - { - "description": "mixed read write operations", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 3 - }, - "session": "session0" - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 3 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 3 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 3 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 3 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "countDocuments", - "object": "collection", - "arguments": { - "filter": { - "_id": 3 - }, - "session": "session0" - }, - "result": 1 - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 4 - }, - "session": "session0" - }, - "result": { - "insertedId": 4 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 5 - }, - "session": "session0" - }, - "result": { - "insertedId": 5 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 6 - }, - "session": "session0" - }, - "result": { - "insertedId": 6 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 7 - }, - "session": "session0" - }, - "result": { - "insertedId": 7 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - }, - { - "_id": 5 - }, - { - "_id": 6 - }, - { - "_id": 7 - } - ] - } - } - }, - { - "description": "multiple commits", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 3, - "1": 4 - } - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "remain pinned after non-transient error on commit", - "skipReason": "blocked on SPEC-1320", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 3, - "1": 4 - } - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 50 - } - } - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ], - "errorCode": 50 - } - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "assertSessionPinned", - "object": "testRunner", - "arguments": { - "session": "session0" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "unpin after transient error within a transaction", - "useMultipleMongoses": true, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 4 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 3 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 4 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null, - "recoveryToken": 42 - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unpin after transient error within a transaction and commit", - "useMultipleMongoses": true, - "clientOptions": { - "heartbeatFrequencyMS": 30000 - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "targetedFailPoint", - "object": "testRunner", - "arguments": { - "session": "session0", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 7 - }, - "data": { - "failCommands": [ - "insert", - "isMaster" - ], - "closeConnection": true - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 4 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ], - "errorLabelsOmit": [ - "UnknownTransactionCommitResult" - ], - "errorCodeName": "NoSuchTransaction" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 3 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 4 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null, - "recoveryToken": 42 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/read-concern.json b/lib/mongoc/libmongoc/tests/json/transactions/read-concern.json deleted file mode 100644 index a54cca57285afeb0f334ab7b2459e3244cd4edfd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/read-concern.json +++ /dev/null @@ -1,1628 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "tests": [ - { - "description": "only first countDocuments includes readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - } - } - } - }, - { - "name": "countDocuments", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 2 - } - } - }, - "result": 3 - }, - { - "name": "countDocuments", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 2 - } - } - }, - "result": 3 - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$match": { - "_id": { - "$gte": 2 - } - } - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ], - "cursor": {}, - "lsid": "session0", - "readConcern": { - "level": "snapshot" - }, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$match": { - "_id": { - "$gte": 2 - } - } - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ], - "cursor": {}, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "only first find includes readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - } - } - } - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": { - "level": "snapshot" - }, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "only first aggregate includes readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - } - } - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "cursor": { - "batchSize": 3 - }, - "lsid": "session0", - "readConcern": { - "level": "snapshot" - }, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "cursor": { - "batchSize": 3 - }, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "only first distinct includes readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - } - } - } - }, - { - "name": "distinct", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": [ - 1, - 2, - 3, - 4 - ] - }, - { - "name": "distinct", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": [ - 1, - 2, - 3, - 4 - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "test", - "key": "_id", - "lsid": "session0", - "readConcern": { - "level": "snapshot" - }, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "distinct", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "test", - "key": "_id", - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "distinct", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "only first runCommand includes readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - } - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "find", - "arguments": { - "session": "session0", - "command": { - "find": "test" - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "find", - "arguments": { - "session": "session0", - "command": { - "find": "test" - } - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "lsid": "session0", - "readConcern": { - "level": "snapshot" - }, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "test", - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "countDocuments ignores collection readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "countDocuments", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 2 - } - } - }, - "result": 3 - }, - { - "name": "countDocuments", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 2 - } - } - }, - "result": 3 - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$match": { - "_id": { - "$gte": 2 - } - } - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ], - "cursor": {}, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$match": { - "_id": { - "$gte": 2 - } - } - }, - { - "$group": { - "_id": 1, - "n": { - "$sum": 1 - } - } - } - ], - "cursor": {}, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "find ignores collection readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "aggregate ignores collection readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "cursor": { - "batchSize": 3 - }, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "cursor": { - "batchSize": 3 - }, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "distinct ignores collection readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "distinct", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": [ - 1, - 2, - 3, - 4 - ] - }, - { - "name": "distinct", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": [ - 1, - 2, - 3, - 4 - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "test", - "key": "_id", - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "distinct", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "distinct": "test", - "key": "_id", - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "distinct", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "runCommand ignores database readConcern", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "runCommand", - "object": "database", - "databaseOptions": { - "readConcern": { - "level": "majority" - } - }, - "command_name": "find", - "arguments": { - "session": "session0", - "command": { - "find": "test" - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "find", - "arguments": { - "session": "session0", - "command": { - "find": "test" - } - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "test", - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/read-pref.json b/lib/mongoc/libmongoc/tests/json/transactions/read-pref.json deleted file mode 100644 index bf1f1970eb639ea2734f2404fbba3223e90d4133..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/read-pref.json +++ /dev/null @@ -1,720 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "default readPreference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 1, - "1": 2, - "2": 3, - "3": 4 - } - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Secondary" - } - }, - "arguments": { - "session": "session0", - "pipeline": [ - { - "$match": { - "_id": 1 - } - }, - { - "$count": "count" - } - ] - }, - "result": [ - { - "count": 1 - } - ] - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Secondary" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Secondary" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "primary readPreference", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Primary" - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 1, - "1": 2, - "2": 3, - "3": 4 - } - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Secondary" - } - }, - "arguments": { - "session": "session0", - "pipeline": [ - { - "$match": { - "_id": 1 - } - }, - { - "$count": "count" - } - ] - }, - "result": [ - { - "count": 1 - } - ] - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Secondary" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Secondary" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "secondary readPreference", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Secondary" - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 1, - "1": 2, - "2": 3, - "3": 4 - } - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "session": "session0", - "pipeline": [ - { - "$match": { - "_id": 1 - } - }, - { - "$count": "count" - } - ] - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "primaryPreferred readPreference", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "PrimaryPreferred" - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 1, - "1": 2, - "2": 3, - "3": 4 - } - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "session": "session0", - "pipeline": [ - { - "$match": { - "_id": 1 - } - }, - { - "$count": "count" - } - ] - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "nearest readPreference", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Nearest" - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 1, - "1": 2, - "2": 3, - "3": 4 - } - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "session": "session0", - "pipeline": [ - { - "$match": { - "_id": 1 - } - }, - { - "$count": "count" - } - ] - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "aggregate", - "object": "collection", - "collectionOptions": { - "readPreference": { - "mode": "Primary" - } - }, - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "secondary write only", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Secondary" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/reads.json b/lib/mongoc/libmongoc/tests/json/transactions/reads.json deleted file mode 100644 index 9fc587f482d3567f8485ddc40ace153aa087de0a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/reads.json +++ /dev/null @@ -1,543 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ], - "tests": [ - { - "description": "collection readConcern without transaction", - "operations": [ - { - "name": "find", - "object": "collection", - "collectionOptions": { - "readConcern": { - "level": "majority" - } - }, - "arguments": { - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "readConcern": { - "level": "majority" - }, - "lsid": "session0", - "txnNumber": null, - "startTransaction": null, - "autocommit": null - }, - "command_name": "find", - "database_name": "transaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "find", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "batchSize": 3 - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "test", - "batchSize": 3, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "find": "test", - "batchSize": 3, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "find", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "aggregate", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "aggregate", - "object": "collection", - "arguments": { - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "batchSize": 3, - "session": "session0" - }, - "result": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "cursor": { - "batchSize": 3 - }, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "aggregate": "test", - "pipeline": [ - { - "$project": { - "_id": 1 - } - } - ], - "cursor": { - "batchSize": 3 - }, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "aggregate", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "getMore": { - "$numberLong": "42" - }, - "collection": "test", - "batchSize": 3, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false - }, - "command_name": "getMore", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "distinct", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "distinct", - "object": "collection", - "arguments": { - "session": "session0", - "fieldName": "_id" - }, - "result": [ - 1, - 2, - 3, - 4 - ] - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "distinct": "test", - "key": "_id", - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "distinct", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "readConcern": null, - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/retryable-abort.json b/lib/mongoc/libmongoc/tests/json/transactions/retryable-abort.json deleted file mode 100644 index f6b7b0e49a12e5aa9cd63144e3ca0b4758f8cbcc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/retryable-abort.json +++ /dev/null @@ -1,1972 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "abortTransaction only performs a single retry", - "clientOptions": { - "retryWrites": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction does not retry after Interrupted", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 11601, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction does not retry after WriteConcernError Interrupted", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "writeConcernError": { - "code": 11601, - "errmsg": "operation was interrupted" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after connection error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 10107, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 13436, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 13435, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 11602, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 11600, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 189, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 91, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 7, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 6, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 9001, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "errorCode": 89, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after WriteConcernError InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "writeConcernError": { - "code": 11600, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after WriteConcernError InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "writeConcernError": { - "code": 11602, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after WriteConcernError PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "writeConcernError": { - "code": 189, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "abortTransaction succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "abortTransaction" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/retryable-commit.json b/lib/mongoc/libmongoc/tests/json/transactions/retryable-commit.json deleted file mode 100644 index b17438b7001777d207b9c4c2906d786d899b7282..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/retryable-commit.json +++ /dev/null @@ -1,2285 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "commitTransaction fails after two errors", - "clientOptions": { - "retryWrites": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction applies majority write concern on retries", - "clientOptions": { - "retryWrites": false - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": 2, - "j": true, - "wtimeout": 5000 - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": 2, - "j": true, - "wtimeout": 5000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "j": true, - "wtimeout": 5000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "j": true, - "wtimeout": 5000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction fails after Interrupted", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 11601, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorCodeName": "Interrupted", - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "commitTransaction fails after WriteConcernError Interrupted", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 11601, - "errmsg": "operation was interrupted" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0", - "result": { - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after connection error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after NotMaster", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 10107, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after NotMasterOrSecondary", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 13436, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after NotMasterNoSlaveOk", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 13435, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 11602, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 11600, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 189, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 91, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after HostNotFound", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 7, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after HostUnreachable", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 6, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after SocketException", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 9001, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after NetworkTimeout", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 89, - "closeConnection": false - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after WriteConcernError InterruptedAtShutdown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 11600, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after WriteConcernError InterruptedDueToReplStateChange", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 11602, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after WriteConcernError PrimarySteppedDown", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 189, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction succeeds after WriteConcernError ShutdownInProgress", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 91, - "errmsg": "Replication is being shut down" - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/retryable-writes.json b/lib/mongoc/libmongoc/tests/json/transactions/retryable-writes.json deleted file mode 100644 index c932893b5bc926f19acee88bbf023d7f465367de..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/retryable-writes.json +++ /dev/null @@ -1,343 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "increment txnNumber", - "clientOptions": { - "retryWrites": true - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 4 - }, - { - "_id": 5 - } - ], - "session": "session0" - }, - "result": { - "insertedIds": { - "0": 4, - "1": 5 - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 3 - } - ], - "ordered": true, - "readConcern": { - "afterClusterTime": 42 - }, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 4 - }, - { - "_id": 5 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "4" - }, - "startTransaction": null, - "autocommit": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 4 - }, - { - "_id": 5 - } - ] - } - } - }, - { - "description": "writes are not retried", - "clientOptions": { - "retryWrites": true - }, - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorLabelsContain": [ - "TransientTransactionError" - ] - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/run-command.json b/lib/mongoc/libmongoc/tests/json/transactions/run-command.json deleted file mode 100644 index 2f2a3a88158e038f582fa3f074b38b352074c027..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/run-command.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "run command with default read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "runCommand", - "object": "database", - "command_name": "insert", - "arguments": { - "session": "session0", - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ] - } - }, - "result": { - "n": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ] - }, - { - "description": "run command with secondary read preference in client option and primary read preference in transaction options", - "clientOptions": { - "readPreference": "secondary" - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Primary" - } - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "insert", - "arguments": { - "session": "session0", - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ] - } - }, - "result": { - "n": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ] - }, - { - "description": "run command with explicit primary read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "runCommand", - "object": "database", - "command_name": "insert", - "arguments": { - "session": "session0", - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ] - }, - "readPreference": { - "mode": "Primary" - } - }, - "result": { - "n": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ] - }, - { - "description": "run command fails with explicit secondary read preference", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "runCommand", - "object": "database", - "command_name": "find", - "arguments": { - "session": "session0", - "command": { - "find": "test" - }, - "readPreference": { - "mode": "Secondary" - } - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - } - ] - }, - { - "description": "run command fails with secondary read preference from transaction options", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Secondary" - } - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "find", - "arguments": { - "session": "session0", - "command": { - "find": "test" - } - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/transaction-options.json b/lib/mongoc/libmongoc/tests/json/transactions/transaction-options.json deleted file mode 100644 index 7af7bb64562f7168216db60450f4e53ba686af5e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/transaction-options.json +++ /dev/null @@ -1,1570 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "no transaction options set", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "afterClusterTime": 42 - }, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "transaction options inherited from client", - "clientOptions": { - "w": 1, - "readConcernLevel": "local" - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "local" - }, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": 1 - }, - "maxTimeMS": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "local", - "afterClusterTime": 42 - }, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": 1 - }, - "maxTimeMS": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "transaction options inherited from defaultTransactionOptions", - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": 1 - }, - "maxCommitTimeMS": 60000 - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": 1 - }, - "maxTimeMS": 60000 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot", - "afterClusterTime": 42 - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": 1 - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "startTransaction options override defaults", - "clientOptions": { - "readConcernLevel": "local", - "w": 1 - }, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "majority" - }, - "writeConcern": { - "w": 1 - }, - "maxCommitTimeMS": 30000 - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": "majority" - }, - "maxCommitTimeMS": 60000 - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot" - }, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": "majority" - }, - "maxTimeMS": 60000 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot", - "afterClusterTime": 42 - }, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": "majority" - }, - "maxTimeMS": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "defaultTransactionOptions override client options", - "clientOptions": { - "readConcernLevel": "local", - "w": 1 - }, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": "majority" - }, - "maxCommitTimeMS": 60000 - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot" - }, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": "majority" - }, - "maxTimeMS": 60000 - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot", - "afterClusterTime": 42 - }, - "writeConcern": null, - "maxTimeMS": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": "majority" - }, - "maxTimeMS": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "readConcern local in defaultTransactionOptions", - "clientOptions": { - "w": 1 - }, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "local" - } - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "local" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": 1 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "local", - "afterClusterTime": 42 - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": { - "w": 1 - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "readConcern snapshot in startTransaction options", - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "majority" - } - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readConcern": { - "level": "snapshot" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot", - "afterClusterTime": 42 - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "client writeConcern ignored for bulk", - "clientOptions": { - "w": "majority" - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": 1 - } - } - } - }, - { - "name": "bulkWrite", - "object": "collection", - "arguments": { - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1 - } - } - } - ], - "session": "session0" - }, - "result": { - "deletedCount": 0, - "insertedCount": 1, - "insertedIds": { - "0": 1 - }, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": 1 - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "readPreference inherited from client", - "clientOptions": { - "readPreference": "secondary" - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "readPreference inherited from defaultTransactionOptions", - "clientOptions": { - "readPreference": "primary" - }, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readPreference": { - "mode": "Secondary" - } - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "startTransaction overrides readPreference", - "clientOptions": { - "readPreference": "primary" - }, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readPreference": { - "mode": "Primary" - } - } - } - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "readPreference": { - "mode": "Secondary" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 1 - } - }, - "result": { - "errorContains": "read preference in a transaction must be primary" - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/update.json b/lib/mongoc/libmongoc/tests/json/transactions/update.json deleted file mode 100644 index 13cf2c92681034f830bff0a819031358bffeb375..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/update.json +++ /dev/null @@ -1,450 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ], - "tests": [ - { - "description": "update", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "updateOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - }, - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 1, - "upsertedId": 4 - } - }, - { - "name": "replaceOne", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "x": 1 - }, - "replacement": { - "y": 1 - } - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - }, - { - "name": "updateMany", - "object": "collection", - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 3 - } - }, - "update": { - "$set": { - "z": 1 - } - } - }, - "result": { - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 4 - }, - "u": { - "$inc": { - "x": 1 - } - }, - "multi": false, - "upsert": true - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "x": 1 - }, - "u": { - "y": 1 - }, - "multi": false, - "upsert": false - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": { - "$gte": 3 - } - }, - "u": { - "$set": { - "z": 1 - } - }, - "multi": true, - "upsert": false - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3, - "z": 1 - }, - { - "_id": 4, - "y": 1, - "z": 1 - } - ] - } - } - }, - { - "description": "collections writeConcern ignored for update", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "updateOne", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 4 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - }, - "result": { - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 1, - "upsertedId": 4 - } - }, - { - "name": "replaceOne", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "x": 1 - }, - "replacement": { - "y": 1 - } - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - }, - { - "name": "updateMany", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": "majority" - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": { - "$gte": 3 - } - }, - "update": { - "$set": { - "z": 1 - } - } - }, - "result": { - "matchedCount": 2, - "modifiedCount": 2, - "upsertedCount": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 4 - }, - "u": { - "$inc": { - "x": 1 - } - }, - "multi": false, - "upsert": true - } - ], - "ordered": true, - "readConcern": null, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "x": 1 - }, - "u": { - "y": 1 - }, - "multi": false, - "upsert": false - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": { - "$gte": 3 - } - }, - "u": { - "$set": { - "z": 1 - } - }, - "multi": true, - "upsert": false - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ] - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/transactions/write-concern.json b/lib/mongoc/libmongoc/tests/json/transactions/write-concern.json deleted file mode 100644 index 88d062635f3b1a359b8e7bf37dfe08c2c64aa5c0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/transactions/write-concern.json +++ /dev/null @@ -1,1279 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "transaction-tests", - "collection_name": "test", - "data": [ - { - "_id": 0 - } - ], - "tests": [ - { - "description": "commit with majority", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0 - }, - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commit with default", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0 - }, - { - "_id": 1 - } - ] - } - } - }, - { - "description": "abort with majority", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": "majority" - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": { - "w": "majority" - } - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0 - } - ] - } - } - }, - { - "description": "abort with default", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0 - } - ] - } - } - }, - { - "description": "start with unacknowledged write concern", - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "arguments": { - "options": { - "writeConcern": { - "w": 0 - } - } - }, - "result": { - "errorContains": "transactions do not support unacknowledged write concern" - } - } - ] - }, - { - "description": "start with implicit unacknowledged write concern", - "clientOptions": { - "w": 0 - }, - "operations": [ - { - "name": "startTransaction", - "object": "session0", - "result": { - "errorContains": "transactions do not support unacknowledged write concern" - } - } - ] - }, - { - "description": "unacknowledged write concern coll insertOne", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0 - }, - { - "_id": 1 - } - ] - } - } - }, - { - "description": "unacknowledged write concern coll insertMany", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertMany", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "result": { - "insertedIds": { - "0": 1, - "1": 2 - } - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0 - }, - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "unacknowledged write concern coll bulkWrite", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "bulkWrite", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "requests": [ - { - "name": "insertOne", - "arguments": { - "document": { - "_id": 1 - } - } - } - ] - }, - "result": { - "deletedCount": 0, - "insertedCount": 1, - "insertedIds": { - "0": 1 - }, - "matchedCount": 0, - "modifiedCount": 0, - "upsertedCount": 0, - "upsertedIds": {} - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0 - }, - { - "_id": 1 - } - ] - } - } - }, - { - "description": "unacknowledged write concern coll deleteOne", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "deleteOne", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 0 - } - }, - "result": { - "deletedCount": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": 0 - }, - "limit": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "unacknowledged write concern coll deleteMany", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "deleteMany", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 0 - } - }, - "result": { - "deletedCount": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "delete": "test", - "deletes": [ - { - "q": { - "_id": 0 - }, - "limit": 0 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "delete", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "unacknowledged write concern coll updateOne", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "updateOne", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 0 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 0 - }, - "u": { - "$inc": { - "x": 1 - } - }, - "multi": false, - "upsert": true - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0, - "x": 1 - } - ] - } - } - }, - { - "description": "unacknowledged write concern coll updateMany", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "updateMany", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 0 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "upsert": true - }, - "result": { - "matchedCount": 1, - "modifiedCount": 1, - "upsertedCount": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "update": "test", - "updates": [ - { - "q": { - "_id": 0 - }, - "u": { - "$inc": { - "x": 1 - } - }, - "multi": true, - "upsert": true - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "update", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0, - "x": 1 - } - ] - } - } - }, - { - "description": "unacknowledged write concern coll findOneAndDelete", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndDelete", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 0 - } - }, - "result": { - "_id": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 0 - }, - "remove": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "unacknowledged write concern coll findOneAndReplace", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndReplace", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 0 - }, - "replacement": { - "x": 1 - }, - "returnDocument": "Before" - }, - "result": { - "_id": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 0 - }, - "update": { - "x": 1 - }, - "new": false, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0, - "x": 1 - } - ] - } - } - }, - { - "description": "unacknowledged write concern coll findOneAndUpdate", - "operations": [ - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "findOneAndUpdate", - "object": "collection", - "collectionOptions": { - "writeConcern": { - "w": 0 - } - }, - "arguments": { - "session": "session0", - "filter": { - "_id": 0 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "returnDocument": "Before" - }, - "result": { - "_id": 0 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "findAndModify": "test", - "query": { - "_id": 0 - }, - "update": { - "$inc": { - "x": 1 - } - }, - "new": false, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "findAndModify", - "database_name": "transaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": null, - "autocommit": false, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 0, - "x": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/README b/lib/mongoc/libmongoc/tests/json/uri-options/README deleted file mode 100644 index 2a03219c9d5d9536b3a35f18f37796a01116a7df..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/README +++ /dev/null @@ -1 +0,0 @@ -Driver URI options tests from: https://github.com/mongodb/specifications/tree/master/source/uri-options diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/auth-options.json b/lib/mongoc/libmongoc/tests/json/uri-options/auth-options.json deleted file mode 100644 index 65a168b33412c59a79da0ea54c45791351fa7591..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/auth-options.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "tests": [ - { - "description": "Valid auth options are parsed correctly", - "uri": "mongodb://foo:bar@example.com/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true&authSource=$external", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "authMechanism": "GSSAPI", - "authMechanismProperties": { - "SERVICE_NAME": "other", - "CANONICALIZE_HOST_NAME": true - }, - "authSource": "$external" - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/compression-options.json b/lib/mongoc/libmongoc/tests/json/uri-options/compression-options.json deleted file mode 100644 index 16bd27b2ccf0d0abc560cd8397ff63d32eaea1ce..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/compression-options.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "tests": [ - { - "description": "Valid compression options are parsed correctly", - "uri": "mongodb://example.com/?compressors=zlib&zlibCompressionLevel=9", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "compressors": [ - "zlib" - ], - "zlibCompressionLevel": 9 - } - }, - { - "description": "Multiple compressors are parsed correctly", - "uri": "mongodb://example.com/?compressors=snappy,zlib", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "compressors": [ - "snappy", - "zlib" - ] - } - }, - { - "description": "Non-numeric zlibCompressionLevel causes a warning", - "uri": "mongodb://example.com/?compressors=zlib&zlibCompressionLevel=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low zlibCompressionLevel causes a warning", - "uri": "mongodb://example.com/?compressors=zlib&zlibCompressionLevel=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too high zlibCompressionLevel causes a warning", - "uri": "mongodb://example.com/?compressors=zlib&zlibCompressionLevel=10", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/concern-options.json b/lib/mongoc/libmongoc/tests/json/uri-options/concern-options.json deleted file mode 100644 index 2b3783746c30c786039fbf93c39e9708b7d1ab3f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/concern-options.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "tests": [ - { - "description": "Valid read and write concern are parsed correctly", - "uri": "mongodb://example.com/?readConcernLevel=majority&w=5&wTimeoutMS=30000&journal=false", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "readConcernLevel": "majority", - "w": 5, - "wTimeoutMS": 30000, - "journal": false - } - }, - { - "description": "Arbitrary string readConcernLevel does not cause a warning", - "uri": "mongodb://example.com/?readConcernLevel=arbitraryButStillValid", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "readConcernLevel": "arbitraryButStillValid" - } - }, - { - "description": "Arbitrary string w doesn't cause a warning", - "uri": "mongodb://example.com/?w=arbitraryButStillValid", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "w": "arbitraryButStillValid" - } - }, - { - "description": "Too low w causes a warning", - "uri": "mongodb://example.com/?w=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Non-numeric wTimeoutMS causes a warning", - "uri": "mongodb://example.com/?wTimeoutMS=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low wTimeoutMS causes a warning", - "uri": "mongodb://example.com/?wTimeoutMS=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Invalid journal causes a warning", - "uri": "mongodb://example.com/?journal=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/connection-options.json b/lib/mongoc/libmongoc/tests/json/uri-options/connection-options.json deleted file mode 100644 index 1e2dccd6e29371974cb025fd9522c202d2de8919..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/connection-options.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "tests": [ - { - "description": "Valid connection and timeout options are parsed correctly", - "uri": "mongodb://example.com/?appname=URI-OPTIONS-SPEC-TEST&connectTimeoutMS=20000&heartbeatFrequencyMS=5000&localThresholdMS=3000&maxIdleTimeMS=50000&replicaSet=uri-options-spec&retryWrites=true&serverSelectionTimeoutMS=15000&socketTimeoutMS=7500", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "appname": "URI-OPTIONS-SPEC-TEST", - "connectTimeoutMS": 20000, - "heartbeatFrequencyMS": 5000, - "localThresholdMS": 3000, - "maxIdleTimeMS": 50000, - "replicaSet": "uri-options-spec", - "retryWrites": true, - "serverSelectionTimeoutMS": 15000, - "socketTimeoutMS": 7500 - } - }, - { - "description": "Non-numeric connectTimeoutMS causes a warning", - "uri": "mongodb://example.com/?connectTimeoutMS=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low connectTimeoutMS causes a warning", - "uri": "mongodb://example.com/?connectTimeoutMS=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Non-numeric heartbeatFrequencyMS causes a warning", - "uri": "mongodb://example.com/?heartbeatFrequencyMS=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low heartbeatFrequencyMS causes a warning", - "uri": "mongodb://example.com/?heartbeatFrequencyMS=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Non-numeric localThresholdMS causes a warning", - "uri": "mongodb://example.com/?localThresholdMS=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low localThresholdMS causes a warning", - "uri": "mongodb://example.com/?localThresholdMS=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Invalid retryWrites causes a warning", - "uri": "mongodb://example.com/?retryWrites=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Non-numeric serverSelectionTimeoutMS causes a warning", - "uri": "mongodb://example.com/?serverSelectionTimeoutMS=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low serverSelectionTimeoutMS causes a warning", - "uri": "mongodb://example.com/?serverSelectionTimeoutMS=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Non-numeric socketTimeoutMS causes a warning", - "uri": "mongodb://example.com/?socketTimeoutMS=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low socketTimeoutMS causes a warning", - "uri": "mongodb://example.com/?socketTimeoutMS=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/connection-pool-options.json b/lib/mongoc/libmongoc/tests/json/uri-options/connection-pool-options.json deleted file mode 100644 index be401f55d5d14a0780c73766cbd2dfb57ce12849..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/connection-pool-options.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "tests": [ - { - "description": "Valid connection pool options are parsed correctly", - "uri": "mongodb://example.com/?maxIdleTimeMS=50000", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "maxIdleTimeMS": 50000 - } - }, - { - "description": "Non-numeric maxIdleTimeMS causes a warning", - "uri": "mongodb://example.com/?maxIdleTimeMS=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low maxIdleTimeMS causes a warning", - "uri": "mongodb://example.com/?maxIdleTimeMS=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/read-preference-options.json b/lib/mongoc/libmongoc/tests/json/uri-options/read-preference-options.json deleted file mode 100644 index e62ce4fa75c0bd8c28ff92c08b30205cc23d5549..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/read-preference-options.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "tests": [ - { - "description": "Valid read preference options are parsed correctly", - "uri": "mongodb://example.com/?readPreference=primaryPreferred&readPreferenceTags=dc:ny,rack:1&maxStalenessSeconds=120&readPreferenceTags=dc:ny", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "readPreference": "primaryPreferred", - "readPreferenceTags": [ - { - "dc": "ny", - "rack": "1" - }, - { - "dc": "ny" - } - ], - "maxStalenessSeconds": 120 - } - }, - { - "description": "Invalid readPreferenceTags causes a warning", - "uri": "mongodb://example.com/?readPreferenceTags=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Non-numeric maxStalenessSeconds causes a warning", - "uri": "mongodb://example.com/?maxStalenessSeconds=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "Too low maxStalenessSeconds causes a warning", - "uri": "mongodb://example.com/?maxStalenessSeconds=-2", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/single-threaded-options.json b/lib/mongoc/libmongoc/tests/json/uri-options/single-threaded-options.json deleted file mode 100644 index fcd24fb880342831304b840ec32d3e0e39b9f503..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/single-threaded-options.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "tests": [ - { - "description": "Valid options specific to single-threaded drivers are parsed correctly", - "uri": "mongodb://example.com/?serverSelectionTryOnce=false", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "serverSelectionTryOnce": false - } - }, - { - "description": "Invalid serverSelectionTryOnce causes a warning", - "uri": "mongodb://example.com/?serverSelectionTryOnce=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/uri-options/tls-options.json b/lib/mongoc/libmongoc/tests/json/uri-options/tls-options.json deleted file mode 100644 index 6db80ed623519be7b50db8c300aa6dc4af3885f5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/uri-options/tls-options.json +++ /dev/null @@ -1,231 +0,0 @@ -{ - "tests": [ - { - "description": "Valid required tls options are parsed correctly", - "uri": "mongodb://example.com/?tls=true&tlsCAFile=ca.pem&tlsCertificateKeyFile=cert.pem&tlsCertificateKeyFilePassword=hunter2", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "tls": true, - "tlsCAFile": "ca.pem", - "tlsCertificateKeyFile": "cert.pem", - "tlsCertificateKeyFilePassword": "hunter2" - } - }, - { - "description": "Invalid tlsAllowInvalidCertificates causes a warning", - "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsAllowInvalidCertificates is parsed correctly", - "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=true", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "tlsAllowInvalidCertificates": true - } - }, - { - "description": "Invalid tlsAllowInvalidCertificates causes a warning", - "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsAllowInvalidHostnames is parsed correctly", - "uri": "mongodb://example.com/?tlsAllowInvalidHostnames=true", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "tlsAllowInvalidHostnames": true - } - }, - { - "description": "Invalid tlsAllowInvalidHostnames causes a warning", - "uri": "mongodb://example.com/?tlsAllowInvalidHostnames=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsInsecure is parsed correctly", - "uri": "mongodb://example.com/?tlsInsecure=true", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": { - "tlsInsecure": true - } - }, - { - "description": "Invalid tlsAllowInsecure causes a warning", - "uri": "mongodb://example.com/?tlsAllowInsecure=invalid", - "valid": true, - "warning": true, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsInsecure and tlsAllowInvalidCertificates both present (and true) raises an error", - "uri": "mongodb://example.com/?tlsInsecure=true&tlsAllowInvalidCertificates=true", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsInsecure and tlsAllowInvalidCertificates both present (and false) raises an error", - "uri": "mongodb://example.com/?tlsInsecure=false&tlsAllowInvalidCertificates=false", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsAllowInvalidCertificates and tlsInsecure both present (and true) raises an error", - "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=true&tlsInsecure=true", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsAllowInvalidCertificates and tlsInsecure both present (and false) raises an error", - "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=false&tlsInsecure=false", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsInsecure and tlsAllowInvalidHostnames both present (and true) raises an error", - "uri": "mongodb://example.com/?tlsInsecure=true&tlsAllowInvalidHostnames=true", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsInsecure and tlsAllowInvalidHostnames both present (and false) raises an error", - "uri": "mongodb://example.com/?tlsInsecure=false&tlsAllowInvalidHostnames=false", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsAllowInvalidHostnames and tlsInsecure both present (and true) raises an error", - "uri": "mongodb://example.com/?tlsAllowInvalidHostnames=true&tlsInsecure=true", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tlsAllowInvalidHostnames and tlsInsecure both present (and false) raises an error", - "uri": "mongodb://example.com/?tlsAllowInvalidHostnames=false&tlsInsecure=false", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tls=true and ssl=true doesn't warn", - "uri": "mongodb://example.com/?tls=true&ssl=true", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tls=false and ssl=false doesn't warn", - "uri": "mongodb://example.com/?tls=false&ssl=false", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "ssl=true and tls=true doesn't warn", - "uri": "mongodb://example.com/?ssl=true&tls=true", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "ssl=false and tls=false doesn't warn", - "uri": "mongodb://example.com/?ssl=false&tls=false", - "valid": true, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tls=false and ssl=true raises error", - "uri": "mongodb://example.com/?tls=false&ssl=true", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "tls=true and ssl=false raises error", - "uri": "mongodb://example.com/?tls=true&ssl=false", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "ssl=false and tls=true raises error", - "uri": "mongodb://example.com/?ssl=false&tls=true", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - }, - { - "description": "ssl=true and tls=false raises error", - "uri": "mongodb://example.com/?ssl=true&tls=false", - "valid": false, - "warning": false, - "hosts": null, - "auth": null, - "options": {} - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/callback-aborts.json b/lib/mongoc/libmongoc/tests/json/with_transaction/callback-aborts.json deleted file mode 100644 index 2a3038e8baab9d0f0f261da97903e11503fa14d9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/callback-aborts.json +++ /dev/null @@ -1,244 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "withTransaction succeeds if callback aborts", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "withTransaction succeeds if callback aborts with no ops", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "abortTransaction", - "object": "session0" - } - ] - } - } - } - ], - "expectations": [], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "withTransaction still succeeds if callback aborts and runs extra op", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "autocommit": null, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 2 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/callback-commits.json b/lib/mongoc/libmongoc/tests/json/with_transaction/callback-commits.json deleted file mode 100644 index 4abbbdd0e637b92a264e0c536eb1707b677a48bd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/callback-commits.json +++ /dev/null @@ -1,303 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "withTransaction succeeds if callback commits", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "withTransaction still succeeds if callback commits and runs extra op", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 3 - } - ], - "ordered": true, - "lsid": "session0", - "autocommit": null, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/callback-retry.json b/lib/mongoc/libmongoc/tests/json/with_transaction/callback-retry.json deleted file mode 100644 index ed36434452cfbba580516008d4f6b17e7c6b9344..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/callback-retry.json +++ /dev/null @@ -1,314 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "callback succeeds after multiple connection errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "callback is not retried after non-transient error (DuplicateKeyError)", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ] - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/commit-retry.json b/lib/mongoc/libmongoc/tests/json/with_transaction/commit-retry.json deleted file mode 100644 index d4b948ce1a5afd01690c4fd88b6d4f2341f6a729..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/commit-retry.json +++ /dev/null @@ -1,528 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "commitTransaction succeeds after multiple connection errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction retry only overwrites write concern w option", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "writeConcern": { - "w": 2, - "j": true, - "wtimeout": 5000 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 2, - "j": true, - "wtimeout": 5000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "j": true, - "wtimeout": 5000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "j": true, - "wtimeout": 5000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commit is retried after commitTransaction UnknownTransactionCommitResult (NotMaster)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 10107, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commit is not retried after MaxTimeMSExpired error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 50 - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "maxCommitTimeMS": 60000 - } - }, - "result": { - "errorCodeName": "MaxTimeMSExpired", - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "maxTimeMS": 60000, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/commit-transienttransactionerror-4.2.json b/lib/mongoc/libmongoc/tests/json/with_transaction/commit-transienttransactionerror-4.2.json deleted file mode 100644 index 7663bb54e18a5b76e95d4f6fd1d40c828b01f0e7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/commit-transienttransactionerror-4.2.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.6", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "transaction is retried after commitTransaction TransientTransactionError (PreparedTransactionInProgress)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 267, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/commit-transienttransactionerror.json b/lib/mongoc/libmongoc/tests/json/with_transaction/commit-transienttransactionerror.json deleted file mode 100644 index 18becbe09c6c36105590c71098f483b619cbddfc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/commit-transienttransactionerror.json +++ /dev/null @@ -1,725 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "transaction is retried after commitTransaction TransientTransactionError (LockTimeout)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 24, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "transaction is retried after commitTransaction TransientTransactionError (WriteConflict)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 112, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "transaction is retried after commitTransaction TransientTransactionError (SnapshotUnavailable)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 246, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "transaction is retried after commitTransaction TransientTransactionError (NoSuchTransaction)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 251, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/commit-writeconcernerror.json b/lib/mongoc/libmongoc/tests/json/with_transaction/commit-writeconcernerror.json deleted file mode 100644 index fbad6455465ffe49af8c9a95c7f1a189fed9815e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/commit-writeconcernerror.json +++ /dev/null @@ -1,602 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "commitTransaction is retried after WriteConcernFailed timeout error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 64, - "codeName": "WriteConcernFailed", - "errmsg": "waiting for replication timed out", - "errInfo": { - "wtimeout": true - } - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction is retried after WriteConcernFailed non-timeout error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 64, - "codeName": "WriteConcernFailed", - "errmsg": "multiple errors reported" - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction is not retried after UnknownReplWriteConcern error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 79, - "codeName": "UnknownReplWriteConcern", - "errmsg": "No write concern mode named 'foo' found in replica set configuration" - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - }, - "result": { - "errorCodeName": "UnknownReplWriteConcern", - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction is not retried after UnsatisfiableWriteConcern error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 100, - "codeName": "UnsatisfiableWriteConcern", - "errmsg": "Not enough data-bearing nodes" - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - }, - "result": { - "errorCodeName": "UnsatisfiableWriteConcern", - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction is not retried after MaxTimeMSExpired error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 50, - "codeName": "MaxTimeMSExpired", - "errmsg": "operation exceeded time limit" - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - }, - "result": { - "errorCodeName": "MaxTimeMSExpired", - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/commit.json b/lib/mongoc/libmongoc/tests/json/with_transaction/commit.json deleted file mode 100644 index 0a7451db952dc3712aaa39293629694453ec70ed..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/commit.json +++ /dev/null @@ -1,286 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "withTransaction commits after callback returns", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "withTransaction commits after callback returns (second transaction)", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/json/with_transaction/transaction-options.json b/lib/mongoc/libmongoc/tests/json/with_transaction/transaction-options.json deleted file mode 100644 index 6b197a44c59161ef25cd8b735354de043a14ee72..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/json/with_transaction/transaction-options.json +++ /dev/null @@ -1,577 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "withTransaction and no transaction options set", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction inherits transaction options from client", - "useMultipleMongoses": true, - "clientOptions": { - "readConcernLevel": "local", - "w": 1 - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "local" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction inherits transaction options from defaultTransactionOptions", - "useMultipleMongoses": true, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": 1 - } - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction explicit transaction options", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": 1 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction explicit transaction options override defaultTransactionOptions", - "useMultipleMongoses": true, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "majority" - }, - "writeConcern": { - "w": "majority" - } - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": 1 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction explicit transaction options override client options", - "useMultipleMongoses": true, - "clientOptions": { - "readConcernLevel": "majority", - "w": "majority" - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": 1 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "snapshot" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/lib/mongoc/libmongoc/tests/mock_server/future-functions.c b/lib/mongoc/libmongoc/tests/mock_server/future-functions.c deleted file mode 100644 index 45a24c9da10963050f8b369054c39476897375df..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/future-functions.c +++ /dev/null @@ -1,2922 +0,0 @@ -/************************************************** - * - * Generated by build/generate-future-functions.py. - * - * DO NOT EDIT THIS FILE. - * - *************************************************/ -/* clang-format off */ - -/* - * Define two sets of functions: background functions and future functions. - - * A background function like background_mongoc_cursor_next runs a driver - * operation on a thread. - - * A future function like future_mongoc_cursor_next launches the background - * operation and returns a future_t that will resolve when the operation - * finishes. - * - * These are used with mock_server_t so you can run the driver on a thread while - * controlling the server from the main thread. - */ - -#include "mongoc/mongoc-topology-private.h" - -#include "future-functions.h" - - -static void * -background_mongoc_async_run (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_void_type; - - mongoc_async_run ( - future_value_get_mongoc_async_ptr (future_get_param (future, 0))); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_bulk_operation_execute (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_uint32_t_type; - - future_value_set_uint32_t ( - &return_value, - mongoc_bulk_operation_execute ( - future_value_get_mongoc_bulk_operation_ptr (future_get_param (future, 0)), - future_value_get_bson_ptr (future_get_param (future, 1)), - future_value_get_bson_error_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_database_read_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_database_read_command_with_opts ( - future_value_get_mongoc_database_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_database_read_write_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_database_read_write_command_with_opts ( - future_value_get_mongoc_database_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_database_write_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_database_write_command_with_opts ( - future_value_get_mongoc_database_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_command_simple (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_client_command_simple ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_const_char_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_client_command_with_opts ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_const_char_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 3)), - future_value_get_const_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_ptr (future_get_param (future, 5)), - future_value_get_bson_error_ptr (future_get_param (future, 6)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_read_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_client_read_command_with_opts ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_const_char_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 3)), - future_value_get_const_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_ptr (future_get_param (future, 5)), - future_value_get_bson_error_ptr (future_get_param (future, 6)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_write_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_client_write_command_with_opts ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_const_char_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_read_write_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_client_read_write_command_with_opts ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_const_char_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 3)), - future_value_get_const_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_ptr (future_get_param (future, 5)), - future_value_get_bson_error_ptr (future_get_param (future, 6)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_kill_cursor (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_void_type; - - mongoc_client_kill_cursor ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_int64_t (future_get_param (future, 1))); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_watch (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_change_stream_ptr_type; - - future_value_set_mongoc_change_stream_ptr ( - &return_value, - mongoc_client_watch ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_aggregate (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_cursor_ptr_type; - - future_value_set_mongoc_cursor_ptr ( - &return_value, - mongoc_collection_aggregate ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_mongoc_query_flags_t (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_count (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_int64_t_type; - - future_value_set_int64_t ( - &return_value, - mongoc_collection_count ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_mongoc_query_flags_t (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_int64_t (future_get_param (future, 3)), - future_value_get_int64_t (future_get_param (future, 4)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 5)), - future_value_get_bson_error_ptr (future_get_param (future, 6)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_count_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_int64_t_type; - - future_value_set_int64_t ( - &return_value, - mongoc_collection_count_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_mongoc_query_flags_t (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_int64_t (future_get_param (future, 3)), - future_value_get_int64_t (future_get_param (future, 4)), - future_value_get_const_bson_ptr (future_get_param (future, 5)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 6)), - future_value_get_bson_error_ptr (future_get_param (future, 7)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_create_index_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_create_index_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_mongoc_index_opt_t (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_drop_index_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_drop_index_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_char_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_bson_error_ptr (future_get_param (future, 3)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_drop_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_drop_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_bson_error_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_find_and_modify_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_find_and_modify_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_mongoc_find_and_modify_opts_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_find_and_modify (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_find_and_modify ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_const_bson_ptr (future_get_param (future, 4)), - future_value_get_bool (future_get_param (future, 5)), - future_value_get_bool (future_get_param (future, 6)), - future_value_get_bool (future_get_param (future, 7)), - future_value_get_bson_ptr (future_get_param (future, 8)), - future_value_get_bson_error_ptr (future_get_param (future, 9)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_find_indexes_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_cursor_ptr_type; - - future_value_set_mongoc_cursor_ptr ( - &return_value, - mongoc_collection_find_indexes_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_stats (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_stats ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_bson_ptr (future_get_param (future, 2)), - future_value_get_bson_error_ptr (future_get_param (future, 3)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_insert_many (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_insert_many ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr_ptr (future_get_param (future, 1)), - future_value_get_size_t (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_insert_one (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_insert_one ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_read_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_read_command_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_read_write_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_read_write_command_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_write_command_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_write_command_with_opts ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_insert_bulk (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_insert_bulk ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_mongoc_insert_flags_t (future_get_param (future, 1)), - future_value_get_const_bson_ptr_ptr (future_get_param (future, 2)), - future_value_get_uint32_t (future_get_param (future, 3)), - future_value_get_const_mongoc_write_concern_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_cluster_run_command_parts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_cluster_run_command_parts ( - future_value_get_mongoc_cluster_ptr (future_get_param (future, 0)), - future_value_get_mongoc_server_stream_ptr (future_get_param (future, 1)), - future_value_get_mongoc_cmd_parts_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_cursor_destroy (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_void_type; - - mongoc_cursor_destroy ( - future_value_get_mongoc_cursor_ptr (future_get_param (future, 0))); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_cursor_next (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_cursor_next ( - future_value_get_mongoc_cursor_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr_ptr (future_get_param (future, 1)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_get_database_names_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_char_ptr_ptr_type; - - future_value_set_char_ptr_ptr ( - &return_value, - mongoc_client_get_database_names_with_opts ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_bson_error_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_select_server (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_server_description_ptr_type; - - future_value_set_mongoc_server_description_ptr ( - &return_value, - mongoc_client_select_server ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_bool (future_get_param (future, 1)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 2)), - future_value_get_bson_error_ptr (future_get_param (future, 3)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_destroy (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_void_type; - - mongoc_client_destroy ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0))); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_pool_destroy (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_void_type; - - mongoc_client_pool_destroy ( - future_value_get_mongoc_client_pool_ptr (future_get_param (future, 0))); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_database_command_simple (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_database_command_simple ( - future_value_get_mongoc_database_ptr (future_get_param (future, 0)), - future_value_get_bson_ptr (future_get_param (future, 1)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_database_drop_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_database_drop_with_opts ( - future_value_get_mongoc_database_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_bson_error_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_database_get_collection_names_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_char_ptr_ptr_type; - - future_value_set_char_ptr_ptr ( - &return_value, - mongoc_database_get_collection_names_with_opts ( - future_value_get_mongoc_database_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_bson_error_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_database_watch (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_change_stream_ptr_type; - - future_value_set_mongoc_change_stream_ptr ( - &return_value, - mongoc_database_watch ( - future_value_get_mongoc_database_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_gridfs_file_readv (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_ssize_t_type; - - future_value_set_ssize_t ( - &return_value, - mongoc_gridfs_file_readv ( - future_value_get_mongoc_gridfs_file_ptr (future_get_param (future, 0)), - future_value_get_mongoc_iovec_ptr (future_get_param (future, 1)), - future_value_get_size_t (future_get_param (future, 2)), - future_value_get_size_t (future_get_param (future, 3)), - future_value_get_uint32_t (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_gridfs_find_one (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_gridfs_file_ptr_type; - - future_value_set_mongoc_gridfs_file_ptr ( - &return_value, - mongoc_gridfs_find_one ( - future_value_get_mongoc_gridfs_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_bson_error_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_gridfs_file_remove (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_gridfs_file_remove ( - future_value_get_mongoc_gridfs_file_ptr (future_get_param (future, 0)), - future_value_get_bson_error_ptr (future_get_param (future, 1)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_gridfs_file_seek (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_int_type; - - future_value_set_int ( - &return_value, - mongoc_gridfs_file_seek ( - future_value_get_mongoc_gridfs_file_ptr (future_get_param (future, 0)), - future_value_get_int64_t (future_get_param (future, 1)), - future_value_get_int (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_gridfs_file_writev (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_ssize_t_type; - - future_value_set_ssize_t ( - &return_value, - mongoc_gridfs_file_writev ( - future_value_get_mongoc_gridfs_file_ptr (future_get_param (future, 0)), - future_value_get_const_mongoc_iovec_ptr (future_get_param (future, 1)), - future_value_get_size_t (future_get_param (future, 2)), - future_value_get_uint32_t (future_get_param (future, 3)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_gridfs_find_one_with_opts (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_gridfs_file_ptr_type; - - future_value_set_mongoc_gridfs_file_ptr ( - &return_value, - mongoc_gridfs_find_one_with_opts ( - future_value_get_mongoc_gridfs_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_bson_error_ptr (future_get_param (future, 3)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_topology_select (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_server_description_ptr_type; - - future_value_set_mongoc_server_description_ptr ( - &return_value, - mongoc_topology_select ( - future_value_get_mongoc_topology_ptr (future_get_param (future, 0)), - future_value_get_mongoc_ss_optype_t (future_get_param (future, 1)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 2)), - future_value_get_bson_error_ptr (future_get_param (future, 3)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_client_get_gridfs (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_gridfs_ptr_type; - - future_value_set_mongoc_gridfs_ptr ( - &return_value, - mongoc_client_get_gridfs ( - future_value_get_mongoc_client_ptr (future_get_param (future, 0)), - future_value_get_const_char_ptr (future_get_param (future, 1)), - future_value_get_const_char_ptr (future_get_param (future, 2)), - future_value_get_bson_error_ptr (future_get_param (future, 3)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_watch (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_mongoc_change_stream_ptr_type; - - future_value_set_mongoc_change_stream_ptr ( - &return_value, - mongoc_collection_watch ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_change_stream_next (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_change_stream_next ( - future_value_get_mongoc_change_stream_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr_ptr (future_get_param (future, 1)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_change_stream_destroy (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_void_type; - - mongoc_change_stream_destroy ( - future_value_get_mongoc_change_stream_ptr (future_get_param (future, 0))); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_delete_one (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_delete_one ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_delete_many (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_delete_many ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_remove (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_remove ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_mongoc_remove_flags_t (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_mongoc_write_concern_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_update_one (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_update_one ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_update_many (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_update_many ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_replace_one (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_bool_type; - - future_value_set_bool ( - &return_value, - mongoc_collection_replace_one ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_count_documents (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_int64_t_type; - - future_value_set_int64_t ( - &return_value, - mongoc_collection_count_documents ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_bson_ptr (future_get_param (future, 2)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 3)), - future_value_get_bson_ptr (future_get_param (future, 4)), - future_value_get_bson_error_ptr (future_get_param (future, 5)) - )); - - future_resolve (future, return_value); - - return NULL; -} - -static void * -background_mongoc_collection_estimated_document_count (void *data) -{ - future_t *future = (future_t *) data; - future_value_t return_value; - - return_value.type = future_value_int64_t_type; - - future_value_set_int64_t ( - &return_value, - mongoc_collection_estimated_document_count ( - future_value_get_mongoc_collection_ptr (future_get_param (future, 0)), - future_value_get_const_bson_ptr (future_get_param (future, 1)), - future_value_get_const_mongoc_read_prefs_ptr (future_get_param (future, 2)), - future_value_get_bson_ptr (future_get_param (future, 3)), - future_value_get_bson_error_ptr (future_get_param (future, 4)) - )); - - future_resolve (future, return_value); - - return NULL; -} - - - -future_t * -future_async_run ( - mongoc_async_ptr async) -{ - future_t *future = future_new (future_value_void_type, - 1); - - future_value_set_mongoc_async_ptr ( - future_get_param (future, 0), async); - - future_start (future, background_mongoc_async_run); - return future; -} - -future_t * -future_bulk_operation_execute ( - mongoc_bulk_operation_ptr bulk, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_uint32_t_type, - 3); - - future_value_set_mongoc_bulk_operation_ptr ( - future_get_param (future, 0), bulk); - - future_value_set_bson_ptr ( - future_get_param (future, 1), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 2), error); - - future_start (future, background_mongoc_bulk_operation_execute); - return future; -} - -future_t * -future_database_read_command_with_opts ( - mongoc_database_ptr database, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_database_ptr ( - future_get_param (future, 0), database); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 2), read_prefs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_database_read_command_with_opts); - return future; -} - -future_t * -future_database_read_write_command_with_opts ( - mongoc_database_ptr database, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_database_ptr ( - future_get_param (future, 0), database); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 2), read_prefs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_database_read_write_command_with_opts); - return future; -} - -future_t * -future_database_write_command_with_opts ( - mongoc_database_ptr database, - const_bson_ptr command, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_database_ptr ( - future_get_param (future, 0), database); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), command); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_database_write_command_with_opts); - return future; -} - -future_t * -future_client_command_simple ( - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_const_char_ptr ( - future_get_param (future, 1), db_name); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 3), read_prefs); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_client_command_simple); - return future; -} - -future_t * -future_client_command_with_opts ( - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 7); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_const_char_ptr ( - future_get_param (future, 1), db_name); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 3), read_prefs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 4), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 5), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 6), error); - - future_start (future, background_mongoc_client_command_with_opts); - return future; -} - -future_t * -future_client_read_command_with_opts ( - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 7); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_const_char_ptr ( - future_get_param (future, 1), db_name); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 3), read_prefs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 4), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 5), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 6), error); - - future_start (future, background_mongoc_client_read_command_with_opts); - return future; -} - -future_t * -future_client_write_command_with_opts ( - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_const_char_ptr ( - future_get_param (future, 1), db_name); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), command); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_client_write_command_with_opts); - return future; -} - -future_t * -future_client_read_write_command_with_opts ( - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 7); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_const_char_ptr ( - future_get_param (future, 1), db_name); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 3), read_prefs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 4), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 5), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 6), error); - - future_start (future, background_mongoc_client_read_write_command_with_opts); - return future; -} - -future_t * -future_client_kill_cursor ( - mongoc_client_ptr client, - int64_t cursor_id) -{ - future_t *future = future_new (future_value_void_type, - 2); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_int64_t ( - future_get_param (future, 1), cursor_id); - - future_start (future, background_mongoc_client_kill_cursor); - return future; -} - -future_t * -future_client_watch ( - mongoc_client_ptr client, - const_bson_ptr pipeline, - const_bson_ptr opts) -{ - future_t *future = future_new (future_value_mongoc_change_stream_ptr_type, - 3); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), pipeline); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_start (future, background_mongoc_client_watch); - return future; -} - -future_t * -future_collection_aggregate ( - mongoc_collection_ptr collection, - mongoc_query_flags_t flags, - const_bson_ptr pipeline, - const_bson_ptr options, - const_mongoc_read_prefs_ptr read_prefs) -{ - future_t *future = future_new (future_value_mongoc_cursor_ptr_type, - 5); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_mongoc_query_flags_t ( - future_get_param (future, 1), flags); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), pipeline); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), options); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 4), read_prefs); - - future_start (future, background_mongoc_collection_aggregate); - return future; -} - -future_t * -future_collection_count ( - mongoc_collection_ptr collection, - mongoc_query_flags_t flags, - const_bson_ptr query, - int64_t skip, - int64_t limit, - const_mongoc_read_prefs_ptr read_prefs, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_int64_t_type, - 7); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_mongoc_query_flags_t ( - future_get_param (future, 1), flags); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), query); - - future_value_set_int64_t ( - future_get_param (future, 3), skip); - - future_value_set_int64_t ( - future_get_param (future, 4), limit); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 5), read_prefs); - - future_value_set_bson_error_ptr ( - future_get_param (future, 6), error); - - future_start (future, background_mongoc_collection_count); - return future; -} - -future_t * -future_collection_count_with_opts ( - mongoc_collection_ptr collection, - mongoc_query_flags_t flags, - const_bson_ptr query, - int64_t skip, - int64_t limit, - const_bson_ptr opts, - const_mongoc_read_prefs_ptr read_prefs, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_int64_t_type, - 8); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_mongoc_query_flags_t ( - future_get_param (future, 1), flags); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), query); - - future_value_set_int64_t ( - future_get_param (future, 3), skip); - - future_value_set_int64_t ( - future_get_param (future, 4), limit); - - future_value_set_const_bson_ptr ( - future_get_param (future, 5), opts); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 6), read_prefs); - - future_value_set_bson_error_ptr ( - future_get_param (future, 7), error); - - future_start (future, background_mongoc_collection_count_with_opts); - return future; -} - -future_t * -future_collection_create_index_with_opts ( - mongoc_collection_ptr collection, - const_bson_ptr keys, - const_mongoc_index_opt_t opt, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), keys); - - future_value_set_const_mongoc_index_opt_t ( - future_get_param (future, 2), opt); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_create_index_with_opts); - return future; -} - -future_t * -future_collection_drop_index_with_opts ( - mongoc_collection_ptr collection, - const_char_ptr index_name, - const_bson_ptr opts, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 4); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_char_ptr ( - future_get_param (future, 1), index_name); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_value_set_bson_error_ptr ( - future_get_param (future, 3), error); - - future_start (future, background_mongoc_collection_drop_index_with_opts); - return future; -} - -future_t * -future_collection_drop_with_opts ( - mongoc_collection_ptr collection, - const_bson_ptr opts, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 3); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), opts); - - future_value_set_bson_error_ptr ( - future_get_param (future, 2), error); - - future_start (future, background_mongoc_collection_drop_with_opts); - return future; -} - -future_t * -future_collection_find_and_modify_with_opts ( - mongoc_collection_ptr collection, - const_bson_ptr query, - const_mongoc_find_and_modify_opts_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), query); - - future_value_set_const_mongoc_find_and_modify_opts_ptr ( - future_get_param (future, 2), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_collection_find_and_modify_with_opts); - return future; -} - -future_t * -future_collection_find_and_modify ( - mongoc_collection_ptr collection, - const_bson_ptr query, - const_bson_ptr sort, - const_bson_ptr update, - const_bson_ptr fields, - bool _remove, - bool upsert, - bool _new, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 10); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), query); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), sort); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), update); - - future_value_set_const_bson_ptr ( - future_get_param (future, 4), fields); - - future_value_set_bool ( - future_get_param (future, 5), _remove); - - future_value_set_bool ( - future_get_param (future, 6), upsert); - - future_value_set_bool ( - future_get_param (future, 7), _new); - - future_value_set_bson_ptr ( - future_get_param (future, 8), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 9), error); - - future_start (future, background_mongoc_collection_find_and_modify); - return future; -} - -future_t * -future_collection_find_indexes_with_opts ( - mongoc_collection_ptr collection, - const_bson_ptr opts) -{ - future_t *future = future_new (future_value_mongoc_cursor_ptr_type, - 2); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), opts); - - future_start (future, background_mongoc_collection_find_indexes_with_opts); - return future; -} - -future_t * -future_collection_stats ( - mongoc_collection_ptr collection, - const_bson_ptr options, - bson_ptr stats, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 4); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), options); - - future_value_set_bson_ptr ( - future_get_param (future, 2), stats); - - future_value_set_bson_error_ptr ( - future_get_param (future, 3), error); - - future_start (future, background_mongoc_collection_stats); - return future; -} - -future_t * -future_collection_insert_many ( - mongoc_collection_ptr collection, - const_bson_ptr_ptr documents, - size_t n_documents, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr_ptr ( - future_get_param (future, 1), documents); - - future_value_set_size_t ( - future_get_param (future, 2), n_documents); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_insert_many); - return future; -} - -future_t * -future_collection_insert_one ( - mongoc_collection_ptr collection, - const_bson_ptr document, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), document); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_collection_insert_one); - return future; -} - -future_t * -future_collection_read_command_with_opts ( - mongoc_collection_ptr collection, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 2), read_prefs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_read_command_with_opts); - return future; -} - -future_t * -future_collection_read_write_command_with_opts ( - mongoc_collection_ptr collection, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 2), read_prefs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_read_write_command_with_opts); - return future; -} - -future_t * -future_collection_write_command_with_opts ( - mongoc_collection_ptr collection, - const_bson_ptr command, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), command); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_collection_write_command_with_opts); - return future; -} - -future_t * -future_collection_insert_bulk ( - mongoc_collection_ptr collection, - mongoc_insert_flags_t flags, - const_bson_ptr_ptr documents, - uint32_t n_documents, - const_mongoc_write_concern_ptr write_concern, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), collection); - - future_value_set_mongoc_insert_flags_t ( - future_get_param (future, 1), flags); - - future_value_set_const_bson_ptr_ptr ( - future_get_param (future, 2), documents); - - future_value_set_uint32_t ( - future_get_param (future, 3), n_documents); - - future_value_set_const_mongoc_write_concern_ptr ( - future_get_param (future, 4), write_concern); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_insert_bulk); - return future; -} - -future_t * -future_cluster_run_command_parts ( - mongoc_cluster_ptr cluster, - mongoc_server_stream_ptr server_stream, - mongoc_cmd_parts_ptr parts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_cluster_ptr ( - future_get_param (future, 0), cluster); - - future_value_set_mongoc_server_stream_ptr ( - future_get_param (future, 1), server_stream); - - future_value_set_mongoc_cmd_parts_ptr ( - future_get_param (future, 2), parts); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_cluster_run_command_parts); - return future; -} - -future_t * -future_cursor_destroy ( - mongoc_cursor_ptr cursor) -{ - future_t *future = future_new (future_value_void_type, - 1); - - future_value_set_mongoc_cursor_ptr ( - future_get_param (future, 0), cursor); - - future_start (future, background_mongoc_cursor_destroy); - return future; -} - -future_t * -future_cursor_next ( - mongoc_cursor_ptr cursor, - const_bson_ptr_ptr doc) -{ - future_t *future = future_new (future_value_bool_type, - 2); - - future_value_set_mongoc_cursor_ptr ( - future_get_param (future, 0), cursor); - - future_value_set_const_bson_ptr_ptr ( - future_get_param (future, 1), doc); - - future_start (future, background_mongoc_cursor_next); - return future; -} - -future_t * -future_client_get_database_names_with_opts ( - mongoc_client_ptr client, - const_bson_ptr opts, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_char_ptr_ptr_type, - 3); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), opts); - - future_value_set_bson_error_ptr ( - future_get_param (future, 2), error); - - future_start (future, background_mongoc_client_get_database_names_with_opts); - return future; -} - -future_t * -future_client_select_server ( - mongoc_client_ptr client, - bool for_writes, - const_mongoc_read_prefs_ptr prefs, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_mongoc_server_description_ptr_type, - 4); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_bool ( - future_get_param (future, 1), for_writes); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 2), prefs); - - future_value_set_bson_error_ptr ( - future_get_param (future, 3), error); - - future_start (future, background_mongoc_client_select_server); - return future; -} - -future_t * -future_client_destroy ( - mongoc_client_ptr client) -{ - future_t *future = future_new (future_value_void_type, - 1); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_start (future, background_mongoc_client_destroy); - return future; -} - -future_t * -future_client_pool_destroy ( - mongoc_client_pool_ptr pool) -{ - future_t *future = future_new (future_value_void_type, - 1); - - future_value_set_mongoc_client_pool_ptr ( - future_get_param (future, 0), pool); - - future_start (future, background_mongoc_client_pool_destroy); - return future; -} - -future_t * -future_database_command_simple ( - mongoc_database_ptr database, - bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_database_ptr ( - future_get_param (future, 0), database); - - future_value_set_bson_ptr ( - future_get_param (future, 1), command); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 2), read_prefs); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_database_command_simple); - return future; -} - -future_t * -future_database_drop_with_opts ( - mongoc_database_ptr database, - const_bson_ptr opts, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 3); - - future_value_set_mongoc_database_ptr ( - future_get_param (future, 0), database); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), opts); - - future_value_set_bson_error_ptr ( - future_get_param (future, 2), error); - - future_start (future, background_mongoc_database_drop_with_opts); - return future; -} - -future_t * -future_database_get_collection_names_with_opts ( - mongoc_database_ptr database, - const_bson_ptr opts, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_char_ptr_ptr_type, - 3); - - future_value_set_mongoc_database_ptr ( - future_get_param (future, 0), database); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), opts); - - future_value_set_bson_error_ptr ( - future_get_param (future, 2), error); - - future_start (future, background_mongoc_database_get_collection_names_with_opts); - return future; -} - -future_t * -future_database_watch ( - mongoc_database_ptr database, - const_bson_ptr pipeline, - const_bson_ptr opts) -{ - future_t *future = future_new (future_value_mongoc_change_stream_ptr_type, - 3); - - future_value_set_mongoc_database_ptr ( - future_get_param (future, 0), database); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), pipeline); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_start (future, background_mongoc_database_watch); - return future; -} - -future_t * -future_gridfs_file_readv ( - mongoc_gridfs_file_ptr file, - mongoc_iovec_ptr iov, - size_t iovcnt, - size_t min_bytes, - uint32_t timeout_msec) -{ - future_t *future = future_new (future_value_ssize_t_type, - 5); - - future_value_set_mongoc_gridfs_file_ptr ( - future_get_param (future, 0), file); - - future_value_set_mongoc_iovec_ptr ( - future_get_param (future, 1), iov); - - future_value_set_size_t ( - future_get_param (future, 2), iovcnt); - - future_value_set_size_t ( - future_get_param (future, 3), min_bytes); - - future_value_set_uint32_t ( - future_get_param (future, 4), timeout_msec); - - future_start (future, background_mongoc_gridfs_file_readv); - return future; -} - -future_t * -future_gridfs_find_one ( - mongoc_gridfs_ptr gridfs, - const_bson_ptr query, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_mongoc_gridfs_file_ptr_type, - 3); - - future_value_set_mongoc_gridfs_ptr ( - future_get_param (future, 0), gridfs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), query); - - future_value_set_bson_error_ptr ( - future_get_param (future, 2), error); - - future_start (future, background_mongoc_gridfs_find_one); - return future; -} - -future_t * -future_gridfs_file_remove ( - mongoc_gridfs_file_ptr file, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 2); - - future_value_set_mongoc_gridfs_file_ptr ( - future_get_param (future, 0), file); - - future_value_set_bson_error_ptr ( - future_get_param (future, 1), error); - - future_start (future, background_mongoc_gridfs_file_remove); - return future; -} - -future_t * -future_gridfs_file_seek ( - mongoc_gridfs_file_ptr file, - int64_t delta, - int whence) -{ - future_t *future = future_new (future_value_int_type, - 3); - - future_value_set_mongoc_gridfs_file_ptr ( - future_get_param (future, 0), file); - - future_value_set_int64_t ( - future_get_param (future, 1), delta); - - future_value_set_int ( - future_get_param (future, 2), whence); - - future_start (future, background_mongoc_gridfs_file_seek); - return future; -} - -future_t * -future_gridfs_file_writev ( - mongoc_gridfs_file_ptr file, - const_mongoc_iovec_ptr iov, - size_t iovcnt, - uint32_t timeout_msec) -{ - future_t *future = future_new (future_value_ssize_t_type, - 4); - - future_value_set_mongoc_gridfs_file_ptr ( - future_get_param (future, 0), file); - - future_value_set_const_mongoc_iovec_ptr ( - future_get_param (future, 1), iov); - - future_value_set_size_t ( - future_get_param (future, 2), iovcnt); - - future_value_set_uint32_t ( - future_get_param (future, 3), timeout_msec); - - future_start (future, background_mongoc_gridfs_file_writev); - return future; -} - -future_t * -future_gridfs_find_one_with_opts ( - mongoc_gridfs_ptr gridfs, - const_bson_ptr filter, - const_bson_ptr opts, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_mongoc_gridfs_file_ptr_type, - 4); - - future_value_set_mongoc_gridfs_ptr ( - future_get_param (future, 0), gridfs); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), filter); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_value_set_bson_error_ptr ( - future_get_param (future, 3), error); - - future_start (future, background_mongoc_gridfs_find_one_with_opts); - return future; -} - -future_t * -future_topology_select ( - mongoc_topology_ptr topology, - mongoc_ss_optype_t optype, - const_mongoc_read_prefs_ptr read_prefs, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_mongoc_server_description_ptr_type, - 4); - - future_value_set_mongoc_topology_ptr ( - future_get_param (future, 0), topology); - - future_value_set_mongoc_ss_optype_t ( - future_get_param (future, 1), optype); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 2), read_prefs); - - future_value_set_bson_error_ptr ( - future_get_param (future, 3), error); - - future_start (future, background_mongoc_topology_select); - return future; -} - -future_t * -future_client_get_gridfs ( - mongoc_client_ptr client, - const_char_ptr db, - const_char_ptr prefix, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_mongoc_gridfs_ptr_type, - 4); - - future_value_set_mongoc_client_ptr ( - future_get_param (future, 0), client); - - future_value_set_const_char_ptr ( - future_get_param (future, 1), db); - - future_value_set_const_char_ptr ( - future_get_param (future, 2), prefix); - - future_value_set_bson_error_ptr ( - future_get_param (future, 3), error); - - future_start (future, background_mongoc_client_get_gridfs); - return future; -} - -future_t * -future_collection_watch ( - mongoc_collection_ptr coll, - const_bson_ptr pipeline, - const_bson_ptr opts) -{ - future_t *future = future_new (future_value_mongoc_change_stream_ptr_type, - 3); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), pipeline); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_start (future, background_mongoc_collection_watch); - return future; -} - -future_t * -future_change_stream_next ( - mongoc_change_stream_ptr stream, - const_bson_ptr_ptr bson) -{ - future_t *future = future_new (future_value_bool_type, - 2); - - future_value_set_mongoc_change_stream_ptr ( - future_get_param (future, 0), stream); - - future_value_set_const_bson_ptr_ptr ( - future_get_param (future, 1), bson); - - future_start (future, background_mongoc_change_stream_next); - return future; -} - -future_t * -future_change_stream_destroy ( - mongoc_change_stream_ptr stream) -{ - future_t *future = future_new (future_value_void_type, - 1); - - future_value_set_mongoc_change_stream_ptr ( - future_get_param (future, 0), stream); - - future_start (future, background_mongoc_change_stream_destroy); - return future; -} - -future_t * -future_collection_delete_one ( - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), selector); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_collection_delete_one); - return future; -} - -future_t * -future_collection_delete_many ( - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), selector); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_collection_delete_many); - return future; -} - -future_t * -future_collection_remove ( - mongoc_collection_ptr coll, - mongoc_remove_flags_t flags, - const_bson_ptr selector, - const_mongoc_write_concern_ptr write_concern, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 5); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_mongoc_remove_flags_t ( - future_get_param (future, 1), flags); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), selector); - - future_value_set_const_mongoc_write_concern_ptr ( - future_get_param (future, 3), write_concern); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_collection_remove); - return future; -} - -future_t * -future_collection_update_one ( - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr update, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), selector); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), update); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_update_one); - return future; -} - -future_t * -future_collection_update_many ( - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr update, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), selector); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), update); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_update_many); - return future; -} - -future_t * -future_collection_replace_one ( - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr replacement, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_bool_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), selector); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), replacement); - - future_value_set_const_bson_ptr ( - future_get_param (future, 3), opts); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_replace_one); - return future; -} - -future_t * -future_collection_count_documents ( - mongoc_collection_ptr coll, - const_bson_ptr filter, - const_bson_ptr opts, - const_mongoc_read_prefs_ptr read_prefs, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_int64_t_type, - 6); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), filter); - - future_value_set_const_bson_ptr ( - future_get_param (future, 2), opts); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 3), read_prefs); - - future_value_set_bson_ptr ( - future_get_param (future, 4), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 5), error); - - future_start (future, background_mongoc_collection_count_documents); - return future; -} - -future_t * -future_collection_estimated_document_count ( - mongoc_collection_ptr coll, - const_bson_ptr opts, - const_mongoc_read_prefs_ptr read_prefs, - bson_ptr reply, - bson_error_ptr error) -{ - future_t *future = future_new (future_value_int64_t_type, - 5); - - future_value_set_mongoc_collection_ptr ( - future_get_param (future, 0), coll); - - future_value_set_const_bson_ptr ( - future_get_param (future, 1), opts); - - future_value_set_const_mongoc_read_prefs_ptr ( - future_get_param (future, 2), read_prefs); - - future_value_set_bson_ptr ( - future_get_param (future, 3), reply); - - future_value_set_bson_error_ptr ( - future_get_param (future, 4), error); - - future_start (future, background_mongoc_collection_estimated_document_count); - return future; -} - - diff --git a/lib/mongoc/libmongoc/tests/mock_server/future-functions.h b/lib/mongoc/libmongoc/tests/mock_server/future-functions.h deleted file mode 100644 index 5c9e923781206d277908cba6673592d0fa7581d8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/future-functions.h +++ /dev/null @@ -1,624 +0,0 @@ -#ifndef FUTURE_FUNCTIONS_H -#define FUTURE_FUNCTIONS_H - -#include "future-value.h" -#include "future.h" -#include "mongoc/mongoc-bulk-operation.h" - -/************************************************** - * - * Generated by build/generate-future-functions.py. - * - * DO NOT EDIT THIS FILE. - * - *************************************************/ -/* clang-format off */ - - -future_t * -future_async_run ( - - mongoc_async_ptr async -); - - -future_t * -future_bulk_operation_execute ( - - mongoc_bulk_operation_ptr bulk, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_database_read_command_with_opts ( - - mongoc_database_ptr database, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_database_read_write_command_with_opts ( - - mongoc_database_ptr database, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_database_write_command_with_opts ( - - mongoc_database_ptr database, - const_bson_ptr command, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_client_command_simple ( - - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_client_command_with_opts ( - - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_client_read_command_with_opts ( - - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_client_write_command_with_opts ( - - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_client_read_write_command_with_opts ( - - mongoc_client_ptr client, - const_char_ptr db_name, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_client_kill_cursor ( - - mongoc_client_ptr client, - int64_t cursor_id -); - - -future_t * -future_client_watch ( - - mongoc_client_ptr client, - const_bson_ptr pipeline, - const_bson_ptr opts -); - - -future_t * -future_collection_aggregate ( - - mongoc_collection_ptr collection, - mongoc_query_flags_t flags, - const_bson_ptr pipeline, - const_bson_ptr options, - const_mongoc_read_prefs_ptr read_prefs -); - - -future_t * -future_collection_count ( - - mongoc_collection_ptr collection, - mongoc_query_flags_t flags, - const_bson_ptr query, - int64_t skip, - int64_t limit, - const_mongoc_read_prefs_ptr read_prefs, - bson_error_ptr error -); - - -future_t * -future_collection_count_with_opts ( - - mongoc_collection_ptr collection, - mongoc_query_flags_t flags, - const_bson_ptr query, - int64_t skip, - int64_t limit, - const_bson_ptr opts, - const_mongoc_read_prefs_ptr read_prefs, - bson_error_ptr error -); - - -future_t * -future_collection_create_index_with_opts ( - - mongoc_collection_ptr collection, - const_bson_ptr keys, - const_mongoc_index_opt_t opt, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_drop_index_with_opts ( - - mongoc_collection_ptr collection, - const_char_ptr index_name, - const_bson_ptr opts, - bson_error_ptr error -); - - -future_t * -future_collection_drop_with_opts ( - - mongoc_collection_ptr collection, - const_bson_ptr opts, - bson_error_ptr error -); - - -future_t * -future_collection_find_and_modify_with_opts ( - - mongoc_collection_ptr collection, - const_bson_ptr query, - const_mongoc_find_and_modify_opts_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_find_and_modify ( - - mongoc_collection_ptr collection, - const_bson_ptr query, - const_bson_ptr sort, - const_bson_ptr update, - const_bson_ptr fields, - bool _remove, - bool upsert, - bool _new, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_find_indexes_with_opts ( - - mongoc_collection_ptr collection, - const_bson_ptr opts -); - - -future_t * -future_collection_stats ( - - mongoc_collection_ptr collection, - const_bson_ptr options, - bson_ptr stats, - bson_error_ptr error -); - - -future_t * -future_collection_insert_many ( - - mongoc_collection_ptr collection, - const_bson_ptr_ptr documents, - size_t n_documents, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_insert_one ( - - mongoc_collection_ptr collection, - const_bson_ptr document, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_read_command_with_opts ( - - mongoc_collection_ptr collection, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_read_write_command_with_opts ( - - mongoc_collection_ptr collection, - const_bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_write_command_with_opts ( - - mongoc_collection_ptr collection, - const_bson_ptr command, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_insert_bulk ( - - mongoc_collection_ptr collection, - mongoc_insert_flags_t flags, - const_bson_ptr_ptr documents, - uint32_t n_documents, - const_mongoc_write_concern_ptr write_concern, - bson_error_ptr error -); - - -future_t * -future_cluster_run_command_parts ( - - mongoc_cluster_ptr cluster, - mongoc_server_stream_ptr server_stream, - mongoc_cmd_parts_ptr parts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_cursor_destroy ( - - mongoc_cursor_ptr cursor -); - - -future_t * -future_cursor_next ( - - mongoc_cursor_ptr cursor, - const_bson_ptr_ptr doc -); - - -future_t * -future_client_get_database_names_with_opts ( - - mongoc_client_ptr client, - const_bson_ptr opts, - bson_error_ptr error -); - - -future_t * -future_client_select_server ( - - mongoc_client_ptr client, - bool for_writes, - const_mongoc_read_prefs_ptr prefs, - bson_error_ptr error -); - - -future_t * -future_client_destroy ( - - mongoc_client_ptr client -); - - -future_t * -future_client_pool_destroy ( - - mongoc_client_pool_ptr pool -); - - -future_t * -future_database_command_simple ( - - mongoc_database_ptr database, - bson_ptr command, - const_mongoc_read_prefs_ptr read_prefs, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_database_drop_with_opts ( - - mongoc_database_ptr database, - const_bson_ptr opts, - bson_error_ptr error -); - - -future_t * -future_database_get_collection_names_with_opts ( - - mongoc_database_ptr database, - const_bson_ptr opts, - bson_error_ptr error -); - - -future_t * -future_database_watch ( - - mongoc_database_ptr database, - const_bson_ptr pipeline, - const_bson_ptr opts -); - - -future_t * -future_gridfs_file_readv ( - - mongoc_gridfs_file_ptr file, - mongoc_iovec_ptr iov, - size_t iovcnt, - size_t min_bytes, - uint32_t timeout_msec -); - - -future_t * -future_gridfs_find_one ( - - mongoc_gridfs_ptr gridfs, - const_bson_ptr query, - bson_error_ptr error -); - - -future_t * -future_gridfs_file_remove ( - - mongoc_gridfs_file_ptr file, - bson_error_ptr error -); - - -future_t * -future_gridfs_file_seek ( - - mongoc_gridfs_file_ptr file, - int64_t delta, - int whence -); - - -future_t * -future_gridfs_file_writev ( - - mongoc_gridfs_file_ptr file, - const_mongoc_iovec_ptr iov, - size_t iovcnt, - uint32_t timeout_msec -); - - -future_t * -future_gridfs_find_one_with_opts ( - - mongoc_gridfs_ptr gridfs, - const_bson_ptr filter, - const_bson_ptr opts, - bson_error_ptr error -); - - -future_t * -future_topology_select ( - - mongoc_topology_ptr topology, - mongoc_ss_optype_t optype, - const_mongoc_read_prefs_ptr read_prefs, - bson_error_ptr error -); - - -future_t * -future_client_get_gridfs ( - - mongoc_client_ptr client, - const_char_ptr db, - const_char_ptr prefix, - bson_error_ptr error -); - - -future_t * -future_collection_watch ( - - mongoc_collection_ptr coll, - const_bson_ptr pipeline, - const_bson_ptr opts -); - - -future_t * -future_change_stream_next ( - - mongoc_change_stream_ptr stream, - const_bson_ptr_ptr bson -); - - -future_t * -future_change_stream_destroy ( - - mongoc_change_stream_ptr stream -); - - -future_t * -future_collection_delete_one ( - - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_delete_many ( - - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_remove ( - - mongoc_collection_ptr coll, - mongoc_remove_flags_t flags, - const_bson_ptr selector, - const_mongoc_write_concern_ptr write_concern, - bson_error_ptr error -); - - -future_t * -future_collection_update_one ( - - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr update, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_update_many ( - - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr update, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_replace_one ( - - mongoc_collection_ptr coll, - const_bson_ptr selector, - const_bson_ptr replacement, - const_bson_ptr opts, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_count_documents ( - - mongoc_collection_ptr coll, - const_bson_ptr filter, - const_bson_ptr opts, - const_mongoc_read_prefs_ptr read_prefs, - bson_ptr reply, - bson_error_ptr error -); - - -future_t * -future_collection_estimated_document_count ( - - mongoc_collection_ptr coll, - const_bson_ptr opts, - const_mongoc_read_prefs_ptr read_prefs, - bson_ptr reply, - bson_error_ptr error -); - - - -#endif /* FUTURE_FUNCTIONS_H */ diff --git a/lib/mongoc/libmongoc/tests/mock_server/future-value.c b/lib/mongoc/libmongoc/tests/mock_server/future-value.c deleted file mode 100644 index e9a34797ad21b1e0b6a1b0c5bc93bdf33e275674..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/future-value.c +++ /dev/null @@ -1,576 +0,0 @@ -#include "future-value.h" - -/************************************************** - * - * Generated by build/generate-future-functions.py. - * - * DO NOT EDIT THIS FILE. - * - *************************************************/ -/* clang-format off */ - -future_value_t * -future_value_new () -{ - return (future_value_t *) bson_malloc0 (sizeof (future_value_t)); -} - -void -future_value_set_void (future_value_t *future_value) -{ - future_value->type = future_value_void_type; -} - -void -future_value_get_void (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_void_type); -} - - -void -future_value_set_bool (future_value_t *future_value, bool value) -{ - future_value->type = future_value_bool_type; - future_value->value.bool_value = value; -} - -bool -future_value_get_bool (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_bool_type); - return future_value->value.bool_value; -} - -void -future_value_set_char_ptr (future_value_t *future_value, char_ptr value) -{ - future_value->type = future_value_char_ptr_type; - future_value->value.char_ptr_value = value; -} - -char_ptr -future_value_get_char_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_char_ptr_type); - return future_value->value.char_ptr_value; -} - -void -future_value_set_char_ptr_ptr (future_value_t *future_value, char_ptr_ptr value) -{ - future_value->type = future_value_char_ptr_ptr_type; - future_value->value.char_ptr_ptr_value = value; -} - -char_ptr_ptr -future_value_get_char_ptr_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_char_ptr_ptr_type); - return future_value->value.char_ptr_ptr_value; -} - -void -future_value_set_int (future_value_t *future_value, int value) -{ - future_value->type = future_value_int_type; - future_value->value.int_value = value; -} - -int -future_value_get_int (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_int_type); - return future_value->value.int_value; -} - -void -future_value_set_int64_t (future_value_t *future_value, int64_t value) -{ - future_value->type = future_value_int64_t_type; - future_value->value.int64_t_value = value; -} - -int64_t -future_value_get_int64_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_int64_t_type); - return future_value->value.int64_t_value; -} - -void -future_value_set_size_t (future_value_t *future_value, size_t value) -{ - future_value->type = future_value_size_t_type; - future_value->value.size_t_value = value; -} - -size_t -future_value_get_size_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_size_t_type); - return future_value->value.size_t_value; -} - -void -future_value_set_ssize_t (future_value_t *future_value, ssize_t value) -{ - future_value->type = future_value_ssize_t_type; - future_value->value.ssize_t_value = value; -} - -ssize_t -future_value_get_ssize_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_ssize_t_type); - return future_value->value.ssize_t_value; -} - -void -future_value_set_uint32_t (future_value_t *future_value, uint32_t value) -{ - future_value->type = future_value_uint32_t_type; - future_value->value.uint32_t_value = value; -} - -uint32_t -future_value_get_uint32_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_uint32_t_type); - return future_value->value.uint32_t_value; -} - -void -future_value_set_const_char_ptr (future_value_t *future_value, const_char_ptr value) -{ - future_value->type = future_value_const_char_ptr_type; - future_value->value.const_char_ptr_value = value; -} - -const_char_ptr -future_value_get_const_char_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_const_char_ptr_type); - return future_value->value.const_char_ptr_value; -} - -void -future_value_set_bson_error_ptr (future_value_t *future_value, bson_error_ptr value) -{ - future_value->type = future_value_bson_error_ptr_type; - future_value->value.bson_error_ptr_value = value; -} - -bson_error_ptr -future_value_get_bson_error_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_bson_error_ptr_type); - return future_value->value.bson_error_ptr_value; -} - -void -future_value_set_bson_ptr (future_value_t *future_value, bson_ptr value) -{ - future_value->type = future_value_bson_ptr_type; - future_value->value.bson_ptr_value = value; -} - -bson_ptr -future_value_get_bson_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_bson_ptr_type); - return future_value->value.bson_ptr_value; -} - -void -future_value_set_const_bson_ptr (future_value_t *future_value, const_bson_ptr value) -{ - future_value->type = future_value_const_bson_ptr_type; - future_value->value.const_bson_ptr_value = value; -} - -const_bson_ptr -future_value_get_const_bson_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_const_bson_ptr_type); - return future_value->value.const_bson_ptr_value; -} - -void -future_value_set_const_bson_ptr_ptr (future_value_t *future_value, const_bson_ptr_ptr value) -{ - future_value->type = future_value_const_bson_ptr_ptr_type; - future_value->value.const_bson_ptr_ptr_value = value; -} - -const_bson_ptr_ptr -future_value_get_const_bson_ptr_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_const_bson_ptr_ptr_type); - return future_value->value.const_bson_ptr_ptr_value; -} - -void -future_value_set_mongoc_async_ptr (future_value_t *future_value, mongoc_async_ptr value) -{ - future_value->type = future_value_mongoc_async_ptr_type; - future_value->value.mongoc_async_ptr_value = value; -} - -mongoc_async_ptr -future_value_get_mongoc_async_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_async_ptr_type); - return future_value->value.mongoc_async_ptr_value; -} - -void -future_value_set_mongoc_bulk_operation_ptr (future_value_t *future_value, mongoc_bulk_operation_ptr value) -{ - future_value->type = future_value_mongoc_bulk_operation_ptr_type; - future_value->value.mongoc_bulk_operation_ptr_value = value; -} - -mongoc_bulk_operation_ptr -future_value_get_mongoc_bulk_operation_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_bulk_operation_ptr_type); - return future_value->value.mongoc_bulk_operation_ptr_value; -} - -void -future_value_set_mongoc_client_ptr (future_value_t *future_value, mongoc_client_ptr value) -{ - future_value->type = future_value_mongoc_client_ptr_type; - future_value->value.mongoc_client_ptr_value = value; -} - -mongoc_client_ptr -future_value_get_mongoc_client_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_client_ptr_type); - return future_value->value.mongoc_client_ptr_value; -} - -void -future_value_set_mongoc_client_pool_ptr (future_value_t *future_value, mongoc_client_pool_ptr value) -{ - future_value->type = future_value_mongoc_client_pool_ptr_type; - future_value->value.mongoc_client_pool_ptr_value = value; -} - -mongoc_client_pool_ptr -future_value_get_mongoc_client_pool_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_client_pool_ptr_type); - return future_value->value.mongoc_client_pool_ptr_value; -} - -void -future_value_set_mongoc_collection_ptr (future_value_t *future_value, mongoc_collection_ptr value) -{ - future_value->type = future_value_mongoc_collection_ptr_type; - future_value->value.mongoc_collection_ptr_value = value; -} - -mongoc_collection_ptr -future_value_get_mongoc_collection_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_collection_ptr_type); - return future_value->value.mongoc_collection_ptr_value; -} - -void -future_value_set_mongoc_cluster_ptr (future_value_t *future_value, mongoc_cluster_ptr value) -{ - future_value->type = future_value_mongoc_cluster_ptr_type; - future_value->value.mongoc_cluster_ptr_value = value; -} - -mongoc_cluster_ptr -future_value_get_mongoc_cluster_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_cluster_ptr_type); - return future_value->value.mongoc_cluster_ptr_value; -} - -void -future_value_set_mongoc_cmd_parts_ptr (future_value_t *future_value, mongoc_cmd_parts_ptr value) -{ - future_value->type = future_value_mongoc_cmd_parts_ptr_type; - future_value->value.mongoc_cmd_parts_ptr_value = value; -} - -mongoc_cmd_parts_ptr -future_value_get_mongoc_cmd_parts_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_cmd_parts_ptr_type); - return future_value->value.mongoc_cmd_parts_ptr_value; -} - -void -future_value_set_mongoc_cursor_ptr (future_value_t *future_value, mongoc_cursor_ptr value) -{ - future_value->type = future_value_mongoc_cursor_ptr_type; - future_value->value.mongoc_cursor_ptr_value = value; -} - -mongoc_cursor_ptr -future_value_get_mongoc_cursor_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_cursor_ptr_type); - return future_value->value.mongoc_cursor_ptr_value; -} - -void -future_value_set_mongoc_database_ptr (future_value_t *future_value, mongoc_database_ptr value) -{ - future_value->type = future_value_mongoc_database_ptr_type; - future_value->value.mongoc_database_ptr_value = value; -} - -mongoc_database_ptr -future_value_get_mongoc_database_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_database_ptr_type); - return future_value->value.mongoc_database_ptr_value; -} - -void -future_value_set_mongoc_gridfs_file_ptr (future_value_t *future_value, mongoc_gridfs_file_ptr value) -{ - future_value->type = future_value_mongoc_gridfs_file_ptr_type; - future_value->value.mongoc_gridfs_file_ptr_value = value; -} - -mongoc_gridfs_file_ptr -future_value_get_mongoc_gridfs_file_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_gridfs_file_ptr_type); - return future_value->value.mongoc_gridfs_file_ptr_value; -} - -void -future_value_set_mongoc_gridfs_ptr (future_value_t *future_value, mongoc_gridfs_ptr value) -{ - future_value->type = future_value_mongoc_gridfs_ptr_type; - future_value->value.mongoc_gridfs_ptr_value = value; -} - -mongoc_gridfs_ptr -future_value_get_mongoc_gridfs_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_gridfs_ptr_type); - return future_value->value.mongoc_gridfs_ptr_value; -} - -void -future_value_set_mongoc_insert_flags_t (future_value_t *future_value, mongoc_insert_flags_t value) -{ - future_value->type = future_value_mongoc_insert_flags_t_type; - future_value->value.mongoc_insert_flags_t_value = value; -} - -mongoc_insert_flags_t -future_value_get_mongoc_insert_flags_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_insert_flags_t_type); - return future_value->value.mongoc_insert_flags_t_value; -} - -void -future_value_set_mongoc_iovec_ptr (future_value_t *future_value, mongoc_iovec_ptr value) -{ - future_value->type = future_value_mongoc_iovec_ptr_type; - future_value->value.mongoc_iovec_ptr_value = value; -} - -mongoc_iovec_ptr -future_value_get_mongoc_iovec_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_iovec_ptr_type); - return future_value->value.mongoc_iovec_ptr_value; -} - -void -future_value_set_mongoc_server_stream_ptr (future_value_t *future_value, mongoc_server_stream_ptr value) -{ - future_value->type = future_value_mongoc_server_stream_ptr_type; - future_value->value.mongoc_server_stream_ptr_value = value; -} - -mongoc_server_stream_ptr -future_value_get_mongoc_server_stream_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_server_stream_ptr_type); - return future_value->value.mongoc_server_stream_ptr_value; -} - -void -future_value_set_mongoc_query_flags_t (future_value_t *future_value, mongoc_query_flags_t value) -{ - future_value->type = future_value_mongoc_query_flags_t_type; - future_value->value.mongoc_query_flags_t_value = value; -} - -mongoc_query_flags_t -future_value_get_mongoc_query_flags_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_query_flags_t_type); - return future_value->value.mongoc_query_flags_t_value; -} - -void -future_value_set_const_mongoc_index_opt_t (future_value_t *future_value, const_mongoc_index_opt_t value) -{ - future_value->type = future_value_const_mongoc_index_opt_t_type; - future_value->value.const_mongoc_index_opt_t_value = value; -} - -const_mongoc_index_opt_t -future_value_get_const_mongoc_index_opt_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_const_mongoc_index_opt_t_type); - return future_value->value.const_mongoc_index_opt_t_value; -} - -void -future_value_set_mongoc_server_description_ptr (future_value_t *future_value, mongoc_server_description_ptr value) -{ - future_value->type = future_value_mongoc_server_description_ptr_type; - future_value->value.mongoc_server_description_ptr_value = value; -} - -mongoc_server_description_ptr -future_value_get_mongoc_server_description_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_server_description_ptr_type); - return future_value->value.mongoc_server_description_ptr_value; -} - -void -future_value_set_mongoc_ss_optype_t (future_value_t *future_value, mongoc_ss_optype_t value) -{ - future_value->type = future_value_mongoc_ss_optype_t_type; - future_value->value.mongoc_ss_optype_t_value = value; -} - -mongoc_ss_optype_t -future_value_get_mongoc_ss_optype_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_ss_optype_t_type); - return future_value->value.mongoc_ss_optype_t_value; -} - -void -future_value_set_mongoc_topology_ptr (future_value_t *future_value, mongoc_topology_ptr value) -{ - future_value->type = future_value_mongoc_topology_ptr_type; - future_value->value.mongoc_topology_ptr_value = value; -} - -mongoc_topology_ptr -future_value_get_mongoc_topology_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_topology_ptr_type); - return future_value->value.mongoc_topology_ptr_value; -} - -void -future_value_set_mongoc_write_concern_ptr (future_value_t *future_value, mongoc_write_concern_ptr value) -{ - future_value->type = future_value_mongoc_write_concern_ptr_type; - future_value->value.mongoc_write_concern_ptr_value = value; -} - -mongoc_write_concern_ptr -future_value_get_mongoc_write_concern_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_write_concern_ptr_type); - return future_value->value.mongoc_write_concern_ptr_value; -} - -void -future_value_set_mongoc_change_stream_ptr (future_value_t *future_value, mongoc_change_stream_ptr value) -{ - future_value->type = future_value_mongoc_change_stream_ptr_type; - future_value->value.mongoc_change_stream_ptr_value = value; -} - -mongoc_change_stream_ptr -future_value_get_mongoc_change_stream_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_change_stream_ptr_type); - return future_value->value.mongoc_change_stream_ptr_value; -} - -void -future_value_set_mongoc_remove_flags_t (future_value_t *future_value, mongoc_remove_flags_t value) -{ - future_value->type = future_value_mongoc_remove_flags_t_type; - future_value->value.mongoc_remove_flags_t_value = value; -} - -mongoc_remove_flags_t -future_value_get_mongoc_remove_flags_t (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_mongoc_remove_flags_t_type); - return future_value->value.mongoc_remove_flags_t_value; -} - -void -future_value_set_const_mongoc_find_and_modify_opts_ptr (future_value_t *future_value, const_mongoc_find_and_modify_opts_ptr value) -{ - future_value->type = future_value_const_mongoc_find_and_modify_opts_ptr_type; - future_value->value.const_mongoc_find_and_modify_opts_ptr_value = value; -} - -const_mongoc_find_and_modify_opts_ptr -future_value_get_const_mongoc_find_and_modify_opts_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_const_mongoc_find_and_modify_opts_ptr_type); - return future_value->value.const_mongoc_find_and_modify_opts_ptr_value; -} - -void -future_value_set_const_mongoc_iovec_ptr (future_value_t *future_value, const_mongoc_iovec_ptr value) -{ - future_value->type = future_value_const_mongoc_iovec_ptr_type; - future_value->value.const_mongoc_iovec_ptr_value = value; -} - -const_mongoc_iovec_ptr -future_value_get_const_mongoc_iovec_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_const_mongoc_iovec_ptr_type); - return future_value->value.const_mongoc_iovec_ptr_value; -} - -void -future_value_set_const_mongoc_read_prefs_ptr (future_value_t *future_value, const_mongoc_read_prefs_ptr value) -{ - future_value->type = future_value_const_mongoc_read_prefs_ptr_type; - future_value->value.const_mongoc_read_prefs_ptr_value = value; -} - -const_mongoc_read_prefs_ptr -future_value_get_const_mongoc_read_prefs_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_const_mongoc_read_prefs_ptr_type); - return future_value->value.const_mongoc_read_prefs_ptr_value; -} - -void -future_value_set_const_mongoc_write_concern_ptr (future_value_t *future_value, const_mongoc_write_concern_ptr value) -{ - future_value->type = future_value_const_mongoc_write_concern_ptr_type; - future_value->value.const_mongoc_write_concern_ptr_value = value; -} - -const_mongoc_write_concern_ptr -future_value_get_const_mongoc_write_concern_ptr (future_value_t *future_value) -{ - BSON_ASSERT (future_value->type == future_value_const_mongoc_write_concern_ptr_type); - return future_value->value.const_mongoc_write_concern_ptr_value; -} - diff --git a/lib/mongoc/libmongoc/tests/mock_server/future-value.h b/lib/mongoc/libmongoc/tests/mock_server/future-value.h deleted file mode 100644 index 6b4fd93efae5ca860fe9c8543694a0c24d17ad41..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/future-value.h +++ /dev/null @@ -1,511 +0,0 @@ -#ifndef FUTURE_VALUE_H -#define FUTURE_VALUE_H - -#include <mongoc/mongoc.h> - - -#include "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-topology-private.h" - - -/************************************************** - * - * Generated by build/generate-future-functions.py. - * - * DO NOT EDIT THIS FILE. - * - *************************************************/ -/* clang-format off */ - - -typedef char * char_ptr; -typedef char ** char_ptr_ptr; -typedef const char * const_char_ptr; -typedef bson_error_t * bson_error_ptr; -typedef bson_t * bson_ptr; -typedef const bson_t * const_bson_ptr; -typedef const bson_t ** const_bson_ptr_ptr; -typedef mongoc_async_t * mongoc_async_ptr; -typedef mongoc_bulk_operation_t * mongoc_bulk_operation_ptr; -typedef mongoc_client_t * mongoc_client_ptr; -typedef mongoc_client_pool_t * mongoc_client_pool_ptr; -typedef mongoc_collection_t * mongoc_collection_ptr; -typedef mongoc_cluster_t * mongoc_cluster_ptr; -typedef mongoc_cmd_parts_t * mongoc_cmd_parts_ptr; -typedef mongoc_cursor_t * mongoc_cursor_ptr; -typedef mongoc_database_t * mongoc_database_ptr; -typedef mongoc_gridfs_file_t * mongoc_gridfs_file_ptr; -typedef mongoc_gridfs_t * mongoc_gridfs_ptr; -typedef mongoc_iovec_t * mongoc_iovec_ptr; -typedef mongoc_server_stream_t * mongoc_server_stream_ptr; -typedef const mongoc_index_opt_t * const_mongoc_index_opt_t; -typedef mongoc_server_description_t * mongoc_server_description_ptr; -typedef mongoc_topology_t * mongoc_topology_ptr; -typedef mongoc_write_concern_t * mongoc_write_concern_ptr; -typedef mongoc_change_stream_t * mongoc_change_stream_ptr; -typedef const mongoc_find_and_modify_opts_t * const_mongoc_find_and_modify_opts_ptr; -typedef const mongoc_iovec_t * const_mongoc_iovec_ptr; -typedef const mongoc_read_prefs_t * const_mongoc_read_prefs_ptr; -typedef const mongoc_write_concern_t * const_mongoc_write_concern_ptr; - -typedef enum { - future_value_no_type = 0, - future_value_bool_type, - future_value_char_ptr_type, - future_value_char_ptr_ptr_type, - future_value_int_type, - future_value_int64_t_type, - future_value_size_t_type, - future_value_ssize_t_type, - future_value_uint32_t_type, - future_value_const_char_ptr_type, - future_value_bson_error_ptr_type, - future_value_bson_ptr_type, - future_value_const_bson_ptr_type, - future_value_const_bson_ptr_ptr_type, - future_value_mongoc_async_ptr_type, - future_value_mongoc_bulk_operation_ptr_type, - future_value_mongoc_client_ptr_type, - future_value_mongoc_client_pool_ptr_type, - future_value_mongoc_collection_ptr_type, - future_value_mongoc_cluster_ptr_type, - future_value_mongoc_cmd_parts_ptr_type, - future_value_mongoc_cursor_ptr_type, - future_value_mongoc_database_ptr_type, - future_value_mongoc_gridfs_file_ptr_type, - future_value_mongoc_gridfs_ptr_type, - future_value_mongoc_insert_flags_t_type, - future_value_mongoc_iovec_ptr_type, - future_value_mongoc_server_stream_ptr_type, - future_value_mongoc_query_flags_t_type, - future_value_const_mongoc_index_opt_t_type, - future_value_mongoc_server_description_ptr_type, - future_value_mongoc_ss_optype_t_type, - future_value_mongoc_topology_ptr_type, - future_value_mongoc_write_concern_ptr_type, - future_value_mongoc_change_stream_ptr_type, - future_value_mongoc_remove_flags_t_type, - future_value_const_mongoc_find_and_modify_opts_ptr_type, - future_value_const_mongoc_iovec_ptr_type, - future_value_const_mongoc_read_prefs_ptr_type, - future_value_const_mongoc_write_concern_ptr_type, - future_value_void_type, - -} future_value_type_t; - -typedef struct _future_value_t -{ - future_value_type_t type; - union { - bool bool_value; - char_ptr char_ptr_value; - char_ptr_ptr char_ptr_ptr_value; - int int_value; - int64_t int64_t_value; - size_t size_t_value; - ssize_t ssize_t_value; - uint32_t uint32_t_value; - const_char_ptr const_char_ptr_value; - bson_error_ptr bson_error_ptr_value; - bson_ptr bson_ptr_value; - const_bson_ptr const_bson_ptr_value; - const_bson_ptr_ptr const_bson_ptr_ptr_value; - mongoc_async_ptr mongoc_async_ptr_value; - mongoc_bulk_operation_ptr mongoc_bulk_operation_ptr_value; - mongoc_client_ptr mongoc_client_ptr_value; - mongoc_client_pool_ptr mongoc_client_pool_ptr_value; - mongoc_collection_ptr mongoc_collection_ptr_value; - mongoc_cluster_ptr mongoc_cluster_ptr_value; - mongoc_cmd_parts_ptr mongoc_cmd_parts_ptr_value; - mongoc_cursor_ptr mongoc_cursor_ptr_value; - mongoc_database_ptr mongoc_database_ptr_value; - mongoc_gridfs_file_ptr mongoc_gridfs_file_ptr_value; - mongoc_gridfs_ptr mongoc_gridfs_ptr_value; - mongoc_insert_flags_t mongoc_insert_flags_t_value; - mongoc_iovec_ptr mongoc_iovec_ptr_value; - mongoc_server_stream_ptr mongoc_server_stream_ptr_value; - mongoc_query_flags_t mongoc_query_flags_t_value; - const_mongoc_index_opt_t const_mongoc_index_opt_t_value; - mongoc_server_description_ptr mongoc_server_description_ptr_value; - mongoc_ss_optype_t mongoc_ss_optype_t_value; - mongoc_topology_ptr mongoc_topology_ptr_value; - mongoc_write_concern_ptr mongoc_write_concern_ptr_value; - mongoc_change_stream_ptr mongoc_change_stream_ptr_value; - mongoc_remove_flags_t mongoc_remove_flags_t_value; - const_mongoc_find_and_modify_opts_ptr const_mongoc_find_and_modify_opts_ptr_value; - const_mongoc_iovec_ptr const_mongoc_iovec_ptr_value; - const_mongoc_read_prefs_ptr const_mongoc_read_prefs_ptr_value; - const_mongoc_write_concern_ptr const_mongoc_write_concern_ptr_value; - - } value; -} future_value_t; - -future_value_t *future_value_new (); - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-function" -#endif - -void future_value_set_void (future_value_t *future_value); - -void future_value_get_void (future_value_t *future_value); - - -void -future_value_set_bool( - future_value_t *future_value, - bool value); - -bool -future_value_get_bool ( - future_value_t *future_value); - -void -future_value_set_char_ptr( - future_value_t *future_value, - char_ptr value); - -char_ptr -future_value_get_char_ptr ( - future_value_t *future_value); - -void -future_value_set_char_ptr_ptr( - future_value_t *future_value, - char_ptr_ptr value); - -char_ptr_ptr -future_value_get_char_ptr_ptr ( - future_value_t *future_value); - -void -future_value_set_int( - future_value_t *future_value, - int value); - -int -future_value_get_int ( - future_value_t *future_value); - -void -future_value_set_int64_t( - future_value_t *future_value, - int64_t value); - -int64_t -future_value_get_int64_t ( - future_value_t *future_value); - -void -future_value_set_size_t( - future_value_t *future_value, - size_t value); - -size_t -future_value_get_size_t ( - future_value_t *future_value); - -void -future_value_set_ssize_t( - future_value_t *future_value, - ssize_t value); - -ssize_t -future_value_get_ssize_t ( - future_value_t *future_value); - -void -future_value_set_uint32_t( - future_value_t *future_value, - uint32_t value); - -uint32_t -future_value_get_uint32_t ( - future_value_t *future_value); - -void -future_value_set_const_char_ptr( - future_value_t *future_value, - const_char_ptr value); - -const_char_ptr -future_value_get_const_char_ptr ( - future_value_t *future_value); - -void -future_value_set_bson_error_ptr( - future_value_t *future_value, - bson_error_ptr value); - -bson_error_ptr -future_value_get_bson_error_ptr ( - future_value_t *future_value); - -void -future_value_set_bson_ptr( - future_value_t *future_value, - bson_ptr value); - -bson_ptr -future_value_get_bson_ptr ( - future_value_t *future_value); - -void -future_value_set_const_bson_ptr( - future_value_t *future_value, - const_bson_ptr value); - -const_bson_ptr -future_value_get_const_bson_ptr ( - future_value_t *future_value); - -void -future_value_set_const_bson_ptr_ptr( - future_value_t *future_value, - const_bson_ptr_ptr value); - -const_bson_ptr_ptr -future_value_get_const_bson_ptr_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_async_ptr( - future_value_t *future_value, - mongoc_async_ptr value); - -mongoc_async_ptr -future_value_get_mongoc_async_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_bulk_operation_ptr( - future_value_t *future_value, - mongoc_bulk_operation_ptr value); - -mongoc_bulk_operation_ptr -future_value_get_mongoc_bulk_operation_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_client_ptr( - future_value_t *future_value, - mongoc_client_ptr value); - -mongoc_client_ptr -future_value_get_mongoc_client_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_client_pool_ptr( - future_value_t *future_value, - mongoc_client_pool_ptr value); - -mongoc_client_pool_ptr -future_value_get_mongoc_client_pool_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_collection_ptr( - future_value_t *future_value, - mongoc_collection_ptr value); - -mongoc_collection_ptr -future_value_get_mongoc_collection_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_cluster_ptr( - future_value_t *future_value, - mongoc_cluster_ptr value); - -mongoc_cluster_ptr -future_value_get_mongoc_cluster_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_cmd_parts_ptr( - future_value_t *future_value, - mongoc_cmd_parts_ptr value); - -mongoc_cmd_parts_ptr -future_value_get_mongoc_cmd_parts_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_cursor_ptr( - future_value_t *future_value, - mongoc_cursor_ptr value); - -mongoc_cursor_ptr -future_value_get_mongoc_cursor_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_database_ptr( - future_value_t *future_value, - mongoc_database_ptr value); - -mongoc_database_ptr -future_value_get_mongoc_database_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_gridfs_file_ptr( - future_value_t *future_value, - mongoc_gridfs_file_ptr value); - -mongoc_gridfs_file_ptr -future_value_get_mongoc_gridfs_file_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_gridfs_ptr( - future_value_t *future_value, - mongoc_gridfs_ptr value); - -mongoc_gridfs_ptr -future_value_get_mongoc_gridfs_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_insert_flags_t( - future_value_t *future_value, - mongoc_insert_flags_t value); - -mongoc_insert_flags_t -future_value_get_mongoc_insert_flags_t ( - future_value_t *future_value); - -void -future_value_set_mongoc_iovec_ptr( - future_value_t *future_value, - mongoc_iovec_ptr value); - -mongoc_iovec_ptr -future_value_get_mongoc_iovec_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_server_stream_ptr( - future_value_t *future_value, - mongoc_server_stream_ptr value); - -mongoc_server_stream_ptr -future_value_get_mongoc_server_stream_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_query_flags_t( - future_value_t *future_value, - mongoc_query_flags_t value); - -mongoc_query_flags_t -future_value_get_mongoc_query_flags_t ( - future_value_t *future_value); - -void -future_value_set_const_mongoc_index_opt_t( - future_value_t *future_value, - const_mongoc_index_opt_t value); - -const_mongoc_index_opt_t -future_value_get_const_mongoc_index_opt_t ( - future_value_t *future_value); - -void -future_value_set_mongoc_server_description_ptr( - future_value_t *future_value, - mongoc_server_description_ptr value); - -mongoc_server_description_ptr -future_value_get_mongoc_server_description_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_ss_optype_t( - future_value_t *future_value, - mongoc_ss_optype_t value); - -mongoc_ss_optype_t -future_value_get_mongoc_ss_optype_t ( - future_value_t *future_value); - -void -future_value_set_mongoc_topology_ptr( - future_value_t *future_value, - mongoc_topology_ptr value); - -mongoc_topology_ptr -future_value_get_mongoc_topology_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_write_concern_ptr( - future_value_t *future_value, - mongoc_write_concern_ptr value); - -mongoc_write_concern_ptr -future_value_get_mongoc_write_concern_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_change_stream_ptr( - future_value_t *future_value, - mongoc_change_stream_ptr value); - -mongoc_change_stream_ptr -future_value_get_mongoc_change_stream_ptr ( - future_value_t *future_value); - -void -future_value_set_mongoc_remove_flags_t( - future_value_t *future_value, - mongoc_remove_flags_t value); - -mongoc_remove_flags_t -future_value_get_mongoc_remove_flags_t ( - future_value_t *future_value); - -void -future_value_set_const_mongoc_find_and_modify_opts_ptr( - future_value_t *future_value, - const_mongoc_find_and_modify_opts_ptr value); - -const_mongoc_find_and_modify_opts_ptr -future_value_get_const_mongoc_find_and_modify_opts_ptr ( - future_value_t *future_value); - -void -future_value_set_const_mongoc_iovec_ptr( - future_value_t *future_value, - const_mongoc_iovec_ptr value); - -const_mongoc_iovec_ptr -future_value_get_const_mongoc_iovec_ptr ( - future_value_t *future_value); - -void -future_value_set_const_mongoc_read_prefs_ptr( - future_value_t *future_value, - const_mongoc_read_prefs_ptr value); - -const_mongoc_read_prefs_ptr -future_value_get_const_mongoc_read_prefs_ptr ( - future_value_t *future_value); - -void -future_value_set_const_mongoc_write_concern_ptr( - future_value_t *future_value, - const_mongoc_write_concern_ptr value); - -const_mongoc_write_concern_ptr -future_value_get_const_mongoc_write_concern_ptr ( - future_value_t *future_value); - - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#endif /* FUTURE_VALUE_H */ diff --git a/lib/mongoc/libmongoc/tests/mock_server/future.c b/lib/mongoc/libmongoc/tests/mock_server/future.c deleted file mode 100644 index 1513679a7e191d6b8892d08978016d1ee7074e9d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/future.c +++ /dev/null @@ -1,586 +0,0 @@ -#include <stdio.h> - -#include "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-thread-private.h" -#include "future.h" -#include "../test-libmongoc.h" - -/************************************************** - * - * Generated by build/generate-future-functions.py. - * - * DO NOT EDIT THIS FILE. - * - *************************************************/ -/* clang-format off */ - -void -future_get_void (future_t *future) -{ - if (!future_wait (future)) { - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); - } -} - - -bool -future_get_bool (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_bool (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -char_ptr -future_get_char_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_char_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -char_ptr_ptr -future_get_char_ptr_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_char_ptr_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -int -future_get_int (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_int (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -int64_t -future_get_int64_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_int64_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -size_t -future_get_size_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_size_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -ssize_t -future_get_ssize_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_ssize_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -uint32_t -future_get_uint32_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_uint32_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -const_char_ptr -future_get_const_char_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_const_char_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -bson_error_ptr -future_get_bson_error_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_bson_error_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -bson_ptr -future_get_bson_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_bson_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -const_bson_ptr -future_get_const_bson_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_const_bson_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -const_bson_ptr_ptr -future_get_const_bson_ptr_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_const_bson_ptr_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_async_ptr -future_get_mongoc_async_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_async_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_bulk_operation_ptr -future_get_mongoc_bulk_operation_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_bulk_operation_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_client_ptr -future_get_mongoc_client_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_client_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_client_pool_ptr -future_get_mongoc_client_pool_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_client_pool_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_collection_ptr -future_get_mongoc_collection_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_collection_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_cluster_ptr -future_get_mongoc_cluster_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_cluster_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_cmd_parts_ptr -future_get_mongoc_cmd_parts_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_cmd_parts_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_cursor_ptr -future_get_mongoc_cursor_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_cursor_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_database_ptr -future_get_mongoc_database_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_database_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_gridfs_file_ptr -future_get_mongoc_gridfs_file_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_gridfs_file_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_gridfs_ptr -future_get_mongoc_gridfs_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_gridfs_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_insert_flags_t -future_get_mongoc_insert_flags_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_insert_flags_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_iovec_ptr -future_get_mongoc_iovec_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_iovec_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_server_stream_ptr -future_get_mongoc_server_stream_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_server_stream_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_query_flags_t -future_get_mongoc_query_flags_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_query_flags_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -const_mongoc_index_opt_t -future_get_const_mongoc_index_opt_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_const_mongoc_index_opt_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_server_description_ptr -future_get_mongoc_server_description_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_server_description_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_ss_optype_t -future_get_mongoc_ss_optype_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_ss_optype_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_topology_ptr -future_get_mongoc_topology_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_topology_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_write_concern_ptr -future_get_mongoc_write_concern_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_write_concern_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_change_stream_ptr -future_get_mongoc_change_stream_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_change_stream_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -mongoc_remove_flags_t -future_get_mongoc_remove_flags_t (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_mongoc_remove_flags_t (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -const_mongoc_find_and_modify_opts_ptr -future_get_const_mongoc_find_and_modify_opts_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_const_mongoc_find_and_modify_opts_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -const_mongoc_iovec_ptr -future_get_const_mongoc_iovec_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_const_mongoc_iovec_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -const_mongoc_read_prefs_ptr -future_get_const_mongoc_read_prefs_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_const_mongoc_read_prefs_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - -const_mongoc_write_concern_ptr -future_get_const_mongoc_write_concern_ptr (future_t *future) -{ - if (future_wait (future)) { - return future_value_get_const_mongoc_write_concern_ptr (&future->return_value); - } - - fprintf (stderr, "%s timed out\n", BSON_FUNC); - fflush (stderr); - abort (); -} - - -future_t * -future_new (future_value_type_t return_type, int argc) -{ - future_t *future; - - future = (future_t *)bson_malloc0 (sizeof *future); - future->return_value.type = return_type; - future->argc = argc; - future->argv = (future_value_t *)bson_malloc0 ((size_t) argc * sizeof(future_value_t)); - mongoc_cond_init (&future->cond); - bson_mutex_init (&future->mutex); - - return future; -} - -future_value_t * -future_get_param (future_t *future, int i) -{ - return &future->argv[i]; -} - -void -future_start (future_t *future, - void *(*start_routine)(void *)) -{ - int r = bson_thread_create (&future->thread, - start_routine, - (void *) future); - - BSON_ASSERT (!r); -} - - -void -future_resolve (future_t *future, future_value_t return_value) -{ - bson_mutex_lock (&future->mutex); - BSON_ASSERT (!future->resolved); - BSON_ASSERT (future->return_value.type == return_value.type); - future->return_value = return_value; - future->resolved = true; - mongoc_cond_signal (&future->cond); - bson_mutex_unlock (&future->mutex); -} - - -bool -future_wait_max (future_t *future, int64_t timeout_ms) -{ - int64_t remaining_usec = timeout_ms * 1000; - int64_t deadline = bson_get_monotonic_time () + timeout_ms * 1000; - bool resolved; - - bson_mutex_lock (&future->mutex); - while (!future->resolved && remaining_usec > 0) { - mongoc_cond_timedwait (&future->cond, &future->mutex, - remaining_usec / 1000); - remaining_usec = deadline - bson_get_monotonic_time (); - } - resolved = future->resolved; - bson_mutex_unlock (&future->mutex); - - if (resolved) { - future->awaited = true; - - /* free memory */ - bson_thread_join (future->thread); - } - - return resolved; -} - - -bool -future_wait (future_t *future) -{ - return future_wait_max (future, get_future_timeout_ms ()); -} - - -void -future_destroy (future_t *future) -{ - BSON_ASSERT (future->awaited); - bson_free (future->argv); - mongoc_cond_destroy (&future->cond); - bson_mutex_destroy (&future->mutex); - bson_free (future); -} - diff --git a/lib/mongoc/libmongoc/tests/mock_server/future.h b/lib/mongoc/libmongoc/tests/mock_server/future.h deleted file mode 100644 index 2d76abe4625f9a89fa54f3f17176523aa4fb25fc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/future.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef FUTURE_H -#define FUTURE_H - -#include <bson/bson.h> - -#include "future-value.h" -#include "mongoc/mongoc-thread-private.h" - -/************************************************** - * - * Generated by build/generate-future-functions.py. - * - * DO NOT EDIT THIS FILE. - * - *************************************************/ -/* clang-format off */ - -typedef struct -{ - bool resolved; - bool awaited; - future_value_t return_value; - int argc; - future_value_t *argv; - mongoc_cond_t cond; - bson_mutex_t mutex; - bson_thread_t thread; -} future_t; - -future_t *future_new (future_value_type_t return_type, int argc); - -future_value_t *future_get_param (future_t *future, int i); - -void future_start (future_t *future, - void *(*start_routine)(void *)); - -void future_resolve (future_t *future, future_value_t return_value); - -bool future_wait (future_t *future); -bool future_wait_max (future_t *future, int64_t timeout_ms); - -void future_get_void (future_t *future); - - -bool -future_get_bool (future_t *future); - -char_ptr -future_get_char_ptr (future_t *future); - -char_ptr_ptr -future_get_char_ptr_ptr (future_t *future); - -int -future_get_int (future_t *future); - -int64_t -future_get_int64_t (future_t *future); - -size_t -future_get_size_t (future_t *future); - -ssize_t -future_get_ssize_t (future_t *future); - -uint32_t -future_get_uint32_t (future_t *future); - -const_char_ptr -future_get_const_char_ptr (future_t *future); - -bson_error_ptr -future_get_bson_error_ptr (future_t *future); - -bson_ptr -future_get_bson_ptr (future_t *future); - -const_bson_ptr -future_get_const_bson_ptr (future_t *future); - -const_bson_ptr_ptr -future_get_const_bson_ptr_ptr (future_t *future); - -mongoc_async_ptr -future_get_mongoc_async_ptr (future_t *future); - -mongoc_bulk_operation_ptr -future_get_mongoc_bulk_operation_ptr (future_t *future); - -mongoc_client_ptr -future_get_mongoc_client_ptr (future_t *future); - -mongoc_client_pool_ptr -future_get_mongoc_client_pool_ptr (future_t *future); - -mongoc_collection_ptr -future_get_mongoc_collection_ptr (future_t *future); - -mongoc_cluster_ptr -future_get_mongoc_cluster_ptr (future_t *future); - -mongoc_cmd_parts_ptr -future_get_mongoc_cmd_parts_ptr (future_t *future); - -mongoc_cursor_ptr -future_get_mongoc_cursor_ptr (future_t *future); - -mongoc_database_ptr -future_get_mongoc_database_ptr (future_t *future); - -mongoc_gridfs_file_ptr -future_get_mongoc_gridfs_file_ptr (future_t *future); - -mongoc_gridfs_ptr -future_get_mongoc_gridfs_ptr (future_t *future); - -mongoc_insert_flags_t -future_get_mongoc_insert_flags_t (future_t *future); - -mongoc_iovec_ptr -future_get_mongoc_iovec_ptr (future_t *future); - -mongoc_server_stream_ptr -future_get_mongoc_server_stream_ptr (future_t *future); - -mongoc_query_flags_t -future_get_mongoc_query_flags_t (future_t *future); - -const_mongoc_index_opt_t -future_get_const_mongoc_index_opt_t (future_t *future); - -mongoc_server_description_ptr -future_get_mongoc_server_description_ptr (future_t *future); - -mongoc_ss_optype_t -future_get_mongoc_ss_optype_t (future_t *future); - -mongoc_topology_ptr -future_get_mongoc_topology_ptr (future_t *future); - -mongoc_write_concern_ptr -future_get_mongoc_write_concern_ptr (future_t *future); - -mongoc_change_stream_ptr -future_get_mongoc_change_stream_ptr (future_t *future); - -mongoc_remove_flags_t -future_get_mongoc_remove_flags_t (future_t *future); - -const_mongoc_find_and_modify_opts_ptr -future_get_const_mongoc_find_and_modify_opts_ptr (future_t *future); - -const_mongoc_iovec_ptr -future_get_const_mongoc_iovec_ptr (future_t *future); - -const_mongoc_read_prefs_ptr -future_get_const_mongoc_read_prefs_ptr (future_t *future); - -const_mongoc_write_concern_ptr -future_get_const_mongoc_write_concern_ptr (future_t *future); - - -void future_destroy (future_t *future); - -#endif /* FUTURE_H */ - diff --git a/lib/mongoc/libmongoc/tests/mock_server/mock-rs.c b/lib/mongoc/libmongoc/tests/mock_server/mock-rs.c deleted file mode 100644 index 8837d371a0340fdee1e1566ec42ec90048dc9099..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/mock-rs.c +++ /dev/null @@ -1,1028 +0,0 @@ -/* - * Copyright 2015 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 <bson/bson.h> -#include <mongoc/mongoc-util-private.h> - -#include "mongoc/mongoc-client-private.h" - -#include "mock-rs.h" -#include "sync-queue.h" -#include "../test-libmongoc.h" - - -struct _mock_rs_t { - bool has_primary; - int n_secondaries; - int n_arbiters; - int32_t max_wire_version; - int64_t request_timeout_msec; - - mock_server_t *primary; - mongoc_array_t secondaries; - mongoc_array_t arbiters; - mongoc_array_t servers; - - char *hosts_str; - mongoc_uri_t *uri; - sync_queue_t *q; - - bson_t primary_tags; - bson_t **secondary_tags; -}; - - -mock_server_t * -get_server (mongoc_array_t *servers, int i) -{ - return _mongoc_array_index (servers, mock_server_t *, i); -} - - -void -append_array (mongoc_array_t *dst, mongoc_array_t *src) -{ - _mongoc_array_append_vals (dst, src->data, (uint32_t) src->len); -} - - -/* a string like: "localhost:1","localhost:2","localhost:3" */ -char * -hosts (mongoc_array_t *servers) -{ - int i; - const char *host_and_port; - bson_string_t *hosts_str = bson_string_new (""); - - for (i = 0; i < servers->len; i++) { - host_and_port = mock_server_get_host_and_port (get_server (servers, i)); - bson_string_append_printf (hosts_str, "\"%s\"", host_and_port); - - if (i < servers->len - 1) { - bson_string_append_printf (hosts_str, ", "); - } - } - - return bson_string_free (hosts_str, false); /* detach buffer */ -} - - -mongoc_uri_t * -make_uri (mongoc_array_t *servers) -{ - int i; - const char *host_and_port; - bson_string_t *uri_str = bson_string_new ("mongodb://"); - mongoc_uri_t *uri; - - for (i = 0; i < servers->len; i++) { - host_and_port = mock_server_get_host_and_port (get_server (servers, i)); - bson_string_append_printf (uri_str, "%s", host_and_port); - - if (i < servers->len - 1) { - bson_string_append_printf (uri_str, ","); - } - } - - bson_string_append_printf (uri_str, "/?replicaSet=rs"); - - uri = mongoc_uri_new (uri_str->str); - - bson_string_free (uri_str, true); - - return uri; -} - - -static char * -ismaster_json (mock_rs_t *rs, - mongoc_server_description_type_t type, - const bson_t *tags) -{ - char *server_type; - char *mongos_36_fields = ""; - char *tags_json; - char *hosts_str; - char *json; - - if (type == MONGOC_SERVER_RS_PRIMARY) { - server_type = "'ismaster': true, 'secondary': false, "; - } else if (type == MONGOC_SERVER_RS_SECONDARY) { - server_type = "'ismaster': false, 'secondary': true, "; - } else { - BSON_ASSERT (type == MONGOC_SERVER_RS_ARBITER); - server_type = "'ismaster': false, 'arbiterOnly': true, "; - } - - if (rs->max_wire_version >= WIRE_VERSION_OP_MSG) { - mongos_36_fields = - "'$clusterTime': {" - " 'clusterTime': {'$timestamp': {'t': 1, 'i': 1}}," - " 'signature': {" - " 'hash': {'$binary': {'subType': '0', 'base64': ''}}," - " 'keyId': {'$numberLong': '6446735049323708417'}" - " }," - " 'operationTime': {'$timestamp': {'t': 1, 'i': 1}}" - "}, " - "'logicalSessionTimeoutMinutes': 30, "; - } - - if (bson_empty0 (tags)) { - tags_json = bson_strdup ("{}"); - } else { - tags_json = bson_as_json (tags, NULL); - } - - hosts_str = hosts (&rs->servers); - - json = bson_strdup_printf ("{'ok': 1, %s %s 'tags': %s," - " 'maxWireVersion': %d, " - "'setName': 'rs', 'hosts': [%s]}", - server_type, - mongos_36_fields, - tags_json, - rs->max_wire_version, - hosts_str); - - bson_free (tags_json); - bson_free (hosts_str); - - return json; -} - - -static char * -primary_json (mock_rs_t *rs) -{ - return ismaster_json (rs, MONGOC_SERVER_RS_PRIMARY, &rs->primary_tags); -} - - -static char * -secondary_json (mock_rs_t *rs, int server_number) -{ - return ismaster_json ( - rs, MONGOC_SERVER_RS_SECONDARY, rs->secondary_tags[server_number]); -} - - -static char * -arbiter_json (mock_rs_t *rs) -{ - return ismaster_json (rs, MONGOC_SERVER_RS_ARBITER, NULL); -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_with_autoismaster -- - * - * A new mock replica set. Each member autoresponds to ismaster. - * Call mock_rs_run to start it, then mock_rs_get_uri to connect. - * - * Returns: - * A replica set you must mock_rs_destroy. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mock_rs_t * -mock_rs_with_autoismaster (int32_t max_wire_version, - bool has_primary, - int n_secondaries, - int n_arbiters) -{ - int i; - mock_rs_t *rs = (mock_rs_t *) bson_malloc0 (sizeof (mock_rs_t)); - - rs->max_wire_version = max_wire_version; - rs->has_primary = has_primary; - rs->n_secondaries = n_secondaries; - rs->n_arbiters = n_arbiters; - rs->request_timeout_msec = get_future_timeout_ms (); - rs->q = q_new (); - bson_init (&rs->primary_tags); - rs->secondary_tags = bson_malloc (n_secondaries * sizeof (bson_t *)); - - for (i = 0; i < n_secondaries; i++) { - rs->secondary_tags[i] = bson_new (); - } - - return rs; -} - - -void -mock_rs_tag_primary (mock_rs_t *rs, const bson_t *tags) -{ - bson_destroy (&rs->primary_tags); - bson_copy_to (tags, &rs->primary_tags); -} - - -void -mock_rs_tag_secondary (mock_rs_t *rs, int server_number, const bson_t *tags) -{ - bson_destroy (rs->secondary_tags[server_number]); - rs->secondary_tags[server_number] = bson_copy (tags); -} - - -static void -mock_rs_auto_endsessions (mock_rs_t *rs) -{ - int i; - - for (i = 0; i < rs->servers.len; i++) { - mock_server_auto_endsessions (get_server (&rs->servers, i)); - } -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_get_request_timeout_msec -- - * - * How long mock_rs_receives_* functions wait for a client - * request before giving up and returning NULL. - * - *-------------------------------------------------------------------------- - */ - -int64_t -mock_rs_get_request_timeout_msec (mock_rs_t *rs) -{ - return rs->request_timeout_msec; -} - -/*-------------------------------------------------------------------------- - * - * mock_rs_set_request_timeout_msec -- - * - * How long mock_rs_receives_* functions wait for a client - * request before giving up and returning NULL. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_set_request_timeout_msec (mock_rs_t *rs, int64_t request_timeout_msec) -{ - rs->request_timeout_msec = request_timeout_msec; -} - - -static bool -rs_q_append (request_t *request, void *data) -{ - mock_rs_t *rs = (mock_rs_t *) data; - - q_put (rs->q, (void *) request); - - return true; /* handled */ -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_run -- - * - * Start each member listening on an unused port. After this, call - * mock_rs_get_uri to connect. - * - * Returns: - * None. - * - * Side effects: - * The replica set's URI is set. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_run (mock_rs_t *rs) -{ - int i; - mock_server_t *server; - char *hosts_str; - char *ismaster_reply; - - if (rs->has_primary) { - /* start primary */ - rs->primary = mock_server_new (); - mock_server_run (rs->primary); - } - - /* start secondaries */ - _mongoc_array_init (&rs->secondaries, sizeof (mock_server_t *)); - - for (i = 0; i < rs->n_secondaries; i++) { - server = mock_server_new (); - mock_server_run (server); - _mongoc_array_append_val (&rs->secondaries, server); - } - - /* start arbiters */ - _mongoc_array_init (&rs->arbiters, sizeof (mock_server_t *)); - - for (i = 0; i < rs->n_arbiters; i++) { - server = mock_server_new (); - mock_server_run (server); - _mongoc_array_append_val (&rs->arbiters, server); - } - - /* add all servers to replica set */ - _mongoc_array_init (&rs->servers, sizeof (mock_server_t *)); - if (rs->has_primary) { - _mongoc_array_append_val (&rs->servers, rs->primary); - } - - append_array (&rs->servers, &rs->secondaries); - append_array (&rs->servers, &rs->arbiters); - - /* enqueue unhandled requests in rs->q, they're retrieved with - * mock_rs_receives_query() &co. rs_q_append is added first so it - * runs last, after auto_ismaster. - */ - for (i = 0; i < rs->servers.len; i++) { - mock_server_autoresponds ( - get_server (&rs->servers, i), rs_q_append, (void *) rs, NULL); - } - - - /* now we know all servers' ports and we have them in one array */ - rs->hosts_str = hosts_str = hosts (&rs->servers); - rs->uri = make_uri (&rs->servers); - - BSON_ASSERT (rs->max_wire_version > 0); - if (rs->has_primary) { - /* primary's ismaster response */ - ismaster_reply = primary_json (rs); - mock_server_auto_ismaster (rs->primary, ismaster_reply); - bson_free (ismaster_reply); - } - - /* secondaries' ismaster response */ - for (i = 0; i < rs->n_secondaries; i++) { - ismaster_reply = secondary_json (rs, i); - mock_server_auto_ismaster (get_server (&rs->secondaries, i), - ismaster_reply); - bson_free (ismaster_reply); - } - - /* arbiters' ismaster response */ - ismaster_reply = arbiter_json (rs); - - for (i = 0; i < rs->n_arbiters; i++) { - mock_server_auto_ismaster (get_server (&rs->arbiters, i), ismaster_reply); - } - - bson_free (ismaster_reply); - - if (rs->max_wire_version >= WIRE_VERSION_OP_MSG) { - mock_rs_auto_endsessions (rs); - } -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_get_uri -- - * - * Call after mock_rs_run to get the connection string. - * - * Returns: - * A const URI. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_uri_t * -mock_rs_get_uri (mock_rs_t *rs) -{ - return rs->uri; -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_receives_request -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_rs_receives_request (mock_rs_t *rs) -{ - return (request_t *) q_get (rs->q, rs->request_timeout_msec); -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_receives_query -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not a query matching ns, flags, - * skip, n_return, query_json, and fields_json. - * - *-------------------------------------------------------------------------- - */ - -/* TODO: refactor with mock_server_receives_query, etc.? */ -request_t * -mock_rs_receives_query (mock_rs_t *rs, - const char *ns, - mongoc_query_flags_t flags, - uint32_t skip, - int32_t n_return, - const char *query_json, - const char *fields_json) -{ - request_t *request; - - request = mock_rs_receives_request (rs); - - if (request && - !request_matches_query ( - request, ns, flags, skip, n_return, query_json, fields_json, false)) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_reply_to_find -- - * - * Receive an OP_QUERY or a find command and reply to it. - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Side effects: - * Logs and aborts if the current request is not a query or find command - * matching "flags". - * - *-------------------------------------------------------------------------- - */ -/* - -void -mock_rs_reply_to_find (mock_rs_t *rs, - mongoc_query_flags_t flags, - int64_t cursor_id, - int32_t number_returned, - const char *reply_json, - bool is_command) -{ - request_t *request; - - request = mock_rs_receives_request (rs); - BSON_ASSERT (request); - - mock_server_reply_to_find (request, flags, cursor_id, number_returned, - reply_json, is_command); -} -*/ - -/*-------------------------------------------------------------------------- - * - * mock_rs_receives_command -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not a command matching - * database_name, command_name, and command_json. - * - *-------------------------------------------------------------------------- - */ - -MONGOC_PRINTF_FORMAT (4, 5) -request_t * -mock_rs_receives_command (mock_rs_t *rs, - const char *database_name, - mongoc_query_flags_t flags, - const char *command_json, - ...) -{ - va_list args; - char *formatted_command_json = NULL; - char *ns; - request_t *request; - - va_start (args, command_json); - if (command_json) { - formatted_command_json = bson_strdupv_printf (command_json, args); - } - va_end (args); - - ns = bson_strdup_printf ("%s.$cmd", database_name); - - request = (request_t *) q_get (rs->q, rs->request_timeout_msec); - - if (request && - !request_matches_query ( - request, ns, flags, 0, 1, formatted_command_json, NULL, true)) { - bson_free (formatted_command_json); - request_destroy (request); - return NULL; - } - - bson_free (ns); - bson_free (formatted_command_json); - - return request; -} - -/*-------------------------------------------------------------------------- - * - * mock_rs_receives_insert -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not an insert matching ns, flags, - * and doc_json. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_rs_receives_insert (mock_rs_t *rs, - const char *ns, - mongoc_insert_flags_t flags, - const char *doc_json) -{ - request_t *request; - - request = (request_t *) q_get (rs->q, rs->request_timeout_msec); - - if (request && !request_matches_insert (request, ns, flags, doc_json)) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_receives_getmore -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not a getmore matching n_return - * and cursor_id. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_rs_receives_getmore (mock_rs_t *rs, - const char *ns, - int32_t n_return, - int64_t cursor_id) -{ - request_t *request; - - request = (request_t *) q_get (rs->q, rs->request_timeout_msec); - - if (request && !request_matches_getmore (request, ns, n_return, cursor_id)) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_receives_msg -- - * - * Pop a client OP_MSG request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. Pass varargs - * list of bson_t pointers, which are matched to the series of - * documents in the request, regardless of section boundaries. - * - * Returns: - * A request you must request_destroy. - * - * Side effects: - * Logs and aborts if the current request is not an OP_MSG matching - * flags and documents. - * - *-------------------------------------------------------------------------- - */ - -request_t * -_mock_rs_receives_msg (mock_rs_t *rs, uint32_t flags, ...) -{ - request_t *request; - va_list args; - bool r; - - request = (request_t *) q_get (rs->q, rs->request_timeout_msec); - - va_start (args, flags); - r = request_matches_msgv (request, flags, &args); - va_end (args); - - if (!r) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_hangs_up -- - * - * Hang up on a client request. - * - * Returns: - * None. - * - * Side effects: - * Causes a network error on the client side. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_hangs_up (request_t *request) -{ - mock_server_hangs_up (request); -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_receives_kill_cursors -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Real-life OP_KILLCURSORS can take multiple ids, but that is - * not yet supported here. - * - * Returns: - * A request you must request_destroy, or NULL if the request - * does not match. - * - * Side effects: - * Logs if the current request is not an OP_KILLCURSORS with the - * expected cursor_id. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_rs_receives_kill_cursors (mock_rs_t *rs, int64_t cursor_id) -{ - request_t *request; - - request = (request_t *) q_get (rs->q, rs->request_timeout_msec); - - if (request && !request_matches_kill_cursors (request, cursor_id)) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_replies -- - * - * Respond to a client request. - * - * Returns: - * None. - * - * Side effects: - * Sends an OP_REPLY to the client. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_replies (request_t *request, - uint32_t flags, - int64_t cursor_id, - int32_t starting_from, - int32_t number_returned, - const char *docs_json) -{ - mock_server_replies ( - request, flags, cursor_id, starting_from, number_returned, docs_json); -} - - -static mongoc_server_description_type_t -_mock_rs_server_type (mock_rs_t *rs, uint16_t port) -{ - int i; - - if (rs->primary && port == mock_server_get_port (rs->primary)) { - return MONGOC_SERVER_RS_PRIMARY; - } - - for (i = 0; i < rs->secondaries.len; i++) { - if (port == mock_server_get_port (get_server (&rs->secondaries, i))) { - return MONGOC_SERVER_RS_SECONDARY; - } - } - - for (i = 0; i < rs->arbiters.len; i++) { - if (port == mock_server_get_port (get_server (&rs->arbiters, i))) { - return MONGOC_SERVER_RS_ARBITER; - } - } - - return MONGOC_SERVER_UNKNOWN; -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_replies_simple -- - * - * Respond to a client request. - * - * Returns: - * None. - * - * Side effects: - * Sends an OP_REPLY to the client. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_replies_simple (request_t *request, const char *docs_json) -{ - mock_rs_replies (request, 0, 0, 0, 1, docs_json); -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_replies_to_find -- - * - * Receive an OP_QUERY or "find" command and reply appropriately. - * - * Returns: - * None. - * - * Side effects: - * Very roughly validates the query or "find" command or aborts. - * The intent is not to test the driver's query or find command - * implementation here, see _test_kill_cursors for example use. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_replies_to_find (request_t *request, - mongoc_query_flags_t flags, - int64_t cursor_id, - int32_t number_returned, - const char *ns, - const char *reply_json, - bool is_command) -{ - mock_server_replies_to_find ( - request, flags, cursor_id, number_returned, ns, reply_json, is_command); -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_request_is_to_primary -- - * - * Check that the request is non-NULL and sent to a - * primary in this replica set. - * - * Returns: - * True if so. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -mock_rs_request_is_to_primary (mock_rs_t *rs, request_t *request) -{ - BSON_ASSERT (request); - - return MONGOC_SERVER_RS_PRIMARY == - _mock_rs_server_type (rs, request_get_server_port (request)); -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_request_is_to_secondary -- - * - * Check that the request is non-NULL and sent to a - * secondary in this replica set. - * - * Returns: - * True if so. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -mock_rs_request_is_to_secondary (mock_rs_t *rs, request_t *request) -{ - BSON_ASSERT (request); - - return MONGOC_SERVER_RS_SECONDARY == - _mock_rs_server_type (rs, request_get_server_port (request)); -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_stepdown -- - * - * Change the primary to a secondary. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_stepdown (mock_rs_t *rs) -{ - char *json; - - BSON_ASSERT (rs->primary); - rs->n_secondaries++; - rs->secondary_tags = - bson_realloc (rs->secondary_tags, rs->n_secondaries * sizeof (bson_t *)); - - rs->secondary_tags[rs->n_secondaries - 1] = bson_copy (&rs->primary_tags); - bson_reinit (&rs->primary_tags); - - json = secondary_json (rs, rs->n_secondaries - 1); - mock_server_auto_ismaster (rs->primary, json); - bson_free (json); - - _mongoc_array_append_val (&rs->secondaries, rs->primary); - rs->primary = NULL; -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_elect -- - * - * Change a secondary to the primary. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_elect (mock_rs_t *rs, int id) -{ - char *json; - size_t i; - mock_server_t **ptrs; - - BSON_ASSERT (!rs->primary); - BSON_ASSERT (id >= 0); - BSON_ASSERT (id < rs->secondaries.len); - - rs->primary = get_server (&rs->secondaries, id); - - /* as the secondary becomes primary, its tags come along */ - bson_destroy (&rs->primary_tags); - BSON_ASSERT (bson_steal (&rs->primary_tags, rs->secondary_tags[id])); - - /* primary_json() uses the current primary_tags */ - json = primary_json (rs); - mock_server_auto_ismaster (rs->primary, json); - bson_free (json); - - ptrs = (mock_server_t **) rs->secondaries.data; - - for (i = (size_t) id + 1; i < rs->secondaries.len; i++) { - ptrs[i - 1] = ptrs[i]; - rs->secondary_tags[i - 1] = rs->secondary_tags[i]; - } - - rs->secondaries.len--; - rs->n_secondaries--; -} - - -/*-------------------------------------------------------------------------- - * - * mock_rs_destroy -- - * - * Free a mock_rs_t. - * - * Returns: - * None. - * - * Side effects: - * Destroys each member mock_server_t, closes sockets, joins threads. - * - *-------------------------------------------------------------------------- - */ - -void -mock_rs_destroy (mock_rs_t *rs) -{ - int i; - - for (i = 0; i < rs->servers.len; i++) { - mock_server_destroy (get_server (&rs->servers, i)); - } - - _mongoc_array_destroy (&rs->secondaries); - _mongoc_array_destroy (&rs->arbiters); - _mongoc_array_destroy (&rs->servers); - - bson_free (rs->hosts_str); - mongoc_uri_destroy (rs->uri); - q_destroy (rs->q); - - bson_destroy (&rs->primary_tags); - for (i = 0; i < rs->n_secondaries; i++) { - bson_destroy (rs->secondary_tags[i]); - } - - bson_free (rs->secondary_tags); - bson_free (rs); -} diff --git a/lib/mongoc/libmongoc/tests/mock_server/mock-rs.h b/lib/mongoc/libmongoc/tests/mock_server/mock-rs.h deleted file mode 100644 index 400050524f5b8b1cd60e768b6c12896133be6399..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/mock-rs.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2015 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 MOCK_RS_H -#define MOCK_RS_H - -#include "mongoc/mongoc.h" - -#include "mock-server.h" - -typedef struct _mock_rs_t mock_rs_t; - -mock_rs_t * -mock_rs_with_autoismaster (int32_t max_wire_version, - bool has_primary, - int n_secondaries, - int n_arbiters); - - -void -mock_rs_tag_primary (mock_rs_t *rs, const bson_t *tags); - -void -mock_rs_tag_secondary (mock_rs_t *rs, int server_number, const bson_t *tags); - -int64_t -mock_rs_get_request_timeout_msec (mock_rs_t *rs); - -void -mock_rs_set_request_timeout_msec (mock_rs_t *rs, int64_t request_timeout_msec); - -void -mock_rs_run (mock_rs_t *rs); - -const mongoc_uri_t * -mock_rs_get_uri (mock_rs_t *rs); - -request_t * -mock_rs_receives_request (mock_rs_t *rs); - -request_t * -mock_rs_receives_query (mock_rs_t *rs, - const char *ns, - mongoc_query_flags_t flags, - uint32_t skip, - int32_t n_return, - const char *query_json, - const char *fields_json); - -request_t * -mock_rs_receives_command (mock_rs_t *rs, - const char *database_name, - mongoc_query_flags_t flags, - const char *command_json, - ...); - -request_t * -mock_rs_receives_insert (mock_rs_t *rs, - const char *ns, - mongoc_insert_flags_t flags, - const char *doc_json); - -request_t * -mock_rs_receives_getmore (mock_rs_t *rs, - const char *ns, - int32_t n_return, - int64_t cursor_id); - -request_t * -mock_rs_receives_kill_cursors (mock_rs_t *rs, int64_t cursor_id); - -request_t * -_mock_rs_receives_msg (mock_rs_t *rs, uint32_t flags, ...); - -#define mock_rs_receives_msg(_rs, _flags, ...) \ - _mock_rs_receives_msg (_rs, _flags, __VA_ARGS__, NULL) - -void -mock_rs_replies (request_t *request, - uint32_t flags, - int64_t cursor_id, - int32_t starting_from, - int32_t number_returned, - const char *docs_json); - -void -mock_rs_replies_simple (request_t *request, const char *docs_json); - -void -mock_rs_replies_to_find (request_t *request, - mongoc_query_flags_t flags, - int64_t cursor_id, - int32_t number_returned, - const char *ns, - const char *reply_json, - bool is_command); - -void -mock_rs_hangs_up (request_t *request); - - -bool -mock_rs_request_is_to_primary (mock_rs_t *rs, request_t *request); - -bool -mock_rs_request_is_to_secondary (mock_rs_t *rs, request_t *request); - -void -mock_rs_stepdown (mock_rs_t *rs); - -void -mock_rs_elect (mock_rs_t *rs, int id); - -void -mock_rs_destroy (mock_rs_t *rs); - -#endif /* MOCK_RS_H */ diff --git a/lib/mongoc/libmongoc/tests/mock_server/mock-server.c b/lib/mongoc/libmongoc/tests/mock_server/mock-server.c deleted file mode 100644 index 2c8ca804b6ae9923095b05e62a83723306e93794..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/mock-server.c +++ /dev/null @@ -1,1997 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc.h" - -#include "mongoc/mongoc-buffer-private.h" -#include "mongoc/mongoc-socket-private.h" -#include "mongoc/mongoc-thread-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "sync-queue.h" -#include "mock-server.h" -#include "../test-conveniences.h" -#include "../test-libmongoc.h" -#include "../TestSuite.h" - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - -/* /Async/ismaster_ssl and /TOPOLOGY/scanner_ssl need a reasonable timeout */ -#define TIMEOUT 5000 - - -struct _mock_server_t { - bool running; - bool stopped; - bool rand_delay; - int64_t request_timeout_msec; - uint16_t port; - mongoc_socket_t *sock; - char *uri_str; - mongoc_uri_t *uri; - bson_thread_t main_thread; - mongoc_cond_t cond; - bson_mutex_t mutex; - int32_t last_response_id; - mongoc_array_t worker_threads; - sync_queue_t *q; - mongoc_array_t autoresponders; - int last_autoresponder_id; - int64_t start_time; - -#ifdef MONGOC_ENABLE_SSL - bool ssl; - mongoc_ssl_opt_t ssl_opts; -#endif - - mock_server_bind_opts_t bind_opts; -}; - - -struct _autoresponder_handle_t { - autoresponder_t responder; - void *data; - destructor_t destructor; - int id; -}; - - -typedef struct { - mongoc_reply_flags_t flags; - bson_t *docs; - int n_docs; - int64_t cursor_id; - uint16_t client_port; - mongoc_opcode_t request_opcode; - mongoc_query_flags_t query_flags; - int32_t response_to; -} reply_t; - - -static void * -main_thread (void *data); - -static void * -worker_thread (void *data); - -static void -_mock_server_reply_with_stream (mock_server_t *server, - reply_t *reply, - mongoc_stream_t *client); - -void -autoresponder_handle_destroy (autoresponder_handle_t *handle); - -static uint16_t -get_port (mongoc_socket_t *sock); - -/*-------------------------------------------------------------------------- - * - * mock_server_new -- - * - * Get a new mock_server_t. Call mock_server_run to start it, - * then mock_server_get_uri to connect. - * - * This server does not autorespond to "ismaster". - * - * Returns: - * A server you must mock_server_destroy. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mock_server_t * -mock_server_new () -{ - mock_server_t *server = - (mock_server_t *) bson_malloc0 (sizeof (mock_server_t)); - - server->request_timeout_msec = get_future_timeout_ms (); - _mongoc_array_init (&server->autoresponders, - sizeof (autoresponder_handle_t)); - _mongoc_array_init (&server->worker_threads, sizeof (bson_thread_t)); - mongoc_cond_init (&server->cond); - bson_mutex_init (&server->mutex); - server->q = q_new (); - server->start_time = bson_get_monotonic_time (); - - return server; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_with_autoismaster -- - * - * A new mock_server_t that autoresponds to ismaster. Call - * mock_server_run to start it, then mock_server_get_uri to - * connect. - * - * Returns: - * A server you must mock_server_destroy. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mock_server_t * -mock_server_with_autoismaster (int32_t max_wire_version) -{ - mock_server_t *server = mock_server_new (); - - char *ismaster = bson_strdup_printf ("{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 0," - " 'maxWireVersion': %d}", - max_wire_version); - - BSON_ASSERT (max_wire_version > 0); - mock_server_auto_ismaster (server, ismaster); - - bson_free (ismaster); - - return server; -} - - -/*-------------------------------------------------------------------------- - * - * mock_mongos_new -- - * - * A new mock_server_t that autoresponds to ismaster as if it were a - * mongos. Call mock_server_run to start it, then mock_server_get_uri - * to connect. - * - * Returns: - * A server you must mock_server_destroy. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mock_server_t * -mock_mongos_new (int32_t max_wire_version) -{ - mock_server_t *server = mock_server_new (); - char *mongos_36_fields = ""; - char *ismaster; - - if (max_wire_version >= WIRE_VERSION_OP_MSG) { - mongos_36_fields = - "," - "'$clusterTime': {" - " 'clusterTime': {'$timestamp': {'t': 1, 'i': 1}}," - " 'signature': {" - " 'hash': {'$binary': {'subType': '0', 'base64': ''}}," - " 'keyId': {'$numberLong': '6446735049323708417'}" - " }," - " 'operationTime': {'$timestamp': {'t': 1, 'i': 1}}" - "}," - "'logicalSessionTimeoutMinutes': 30"; - } - - ismaster = bson_strdup_printf ("{'ok': 1.0," - " 'ismaster': true," - " 'msg': 'isdbgrid'," - " 'minWireVersion': 2," - " 'maxWireVersion': %d" - " %s}", - max_wire_version, - mongos_36_fields); - - BSON_ASSERT (max_wire_version > 0); - mock_server_auto_ismaster (server, ismaster); - - bson_free (ismaster); - - return server; -} - - -static bool -hangup (request_t *request, void *ctx) -{ - mock_server_hangs_up (request); - request_destroy (request); - return true; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_down -- - * - * A new mock_server_t hangs up. Call mock_server_run to start it, - * then mock_server_get_uri to connect. - * - * Returns: - * A server you must mock_server_destroy. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -mock_server_t * -mock_server_down (void) -{ - mock_server_t *server = mock_server_new (); - - mock_server_autoresponds (server, hangup, NULL, NULL); - - return server; -} - - -#ifdef MONGOC_ENABLE_SSL - -/*-------------------------------------------------------------------------- - * - * mock_server_set_ssl_opts -- - * - * Set server-side SSL options before calling mock_server_run. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -void -mock_server_set_ssl_opts (mock_server_t *server, mongoc_ssl_opt_t *opts) -{ - bson_mutex_lock (&server->mutex); - server->ssl = true; - memcpy (&server->ssl_opts, opts, sizeof *opts); - bson_mutex_unlock (&server->mutex); -} - -#endif - -/*-------------------------------------------------------------------------- - * - * mock_server_run -- - * - * Start listening on an unused port. After this, call - * mock_server_get_uri to connect. - * - * Returns: - * The bound port. - * - * Side effects: - * The server's port and URI are set. - * - *-------------------------------------------------------------------------- - */ -uint16_t -mock_server_run (mock_server_t *server) -{ - mongoc_socket_t *ssock; - struct sockaddr_in default_bind_addr; - struct sockaddr_in *bind_addr; - int optval; - uint16_t bound_port; - size_t bind_addr_len = 0; - - MONGOC_INFO ("Starting mock server on port %d.", server->port); - ssock = mongoc_socket_new ( - server->bind_opts.family ? server->bind_opts.family : AF_INET, - SOCK_STREAM, - 0); - if (!ssock) { - perror ("Failed to create socket."); - return 0; - } - - optval = 1; - mongoc_socket_setsockopt ( - ssock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval); - - optval = server->bind_opts.ipv6_only; - mongoc_socket_setsockopt ( - ssock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof (optval)); - - memset (&default_bind_addr, 0, sizeof default_bind_addr); - - default_bind_addr.sin_family = AF_INET; - default_bind_addr.sin_addr.s_addr = htonl (INADDR_ANY); - - /* bind to unused port */ - default_bind_addr.sin_port = htons (0); - - if (server->bind_opts.bind_addr) { - bind_addr = server->bind_opts.bind_addr; - bind_addr_len = server->bind_opts.bind_addr_len; - } else { - bind_addr = &default_bind_addr; - bind_addr_len = sizeof (default_bind_addr); - } - - if (-1 == mongoc_socket_bind ( - ssock, (struct sockaddr *) bind_addr, bind_addr_len)) { - perror ("Failed to bind socket"); - return 0; - } - - if (-1 == mongoc_socket_listen (ssock, 10)) { - perror ("Failed to put socket into listen mode"); - return 0; - } - - bound_port = get_port (ssock); - if (!bound_port) { - perror ("Failed to get bound port number"); - return 0; - } - - bson_mutex_lock (&server->mutex); - - server->sock = ssock; - server->port = bound_port; - /* TODO: configurable timeouts, perhaps from env */ - server->uri_str = bson_strdup_printf ( - "mongodb://127.0.0.1:%hu/?serverselectiontimeoutms=10000&" - "sockettimeoutms=10000", - bound_port); - server->uri = mongoc_uri_new (server->uri_str); - - bson_thread_create (&server->main_thread, main_thread, (void *) server); - while (!server->running) { - mongoc_cond_wait (&server->cond, &server->mutex); - } - - bson_mutex_unlock (&server->mutex); - - test_suite_mock_server_log ("listening on port %hu", bound_port); - - return (uint16_t) bound_port; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_autoresponds -- - * - * Respond to matching requests. "data" is passed to the responder - * callback, and passed to "destructor" when the autoresponder is - * destroyed. - * - * Responders are run most-recently-added-first until one returns - * true to indicate it has handled the request. If none handles it, - * the request is enqueued until a call to mock_server_receives_*. - * - * Autoresponders must call request_destroy after handling a - * request. - * - * Returns: - * An id for mock_server_remove_autoresponder. - * - * Side effects: - * If a matching request is enqueued, pop it and respond. - * - *-------------------------------------------------------------------------- - */ - -int -mock_server_autoresponds (mock_server_t *server, - autoresponder_t responder, - void *data, - destructor_t destructor) -{ - autoresponder_handle_t handle = {responder, data, destructor}; - int id; - - bson_mutex_lock (&server->mutex); - id = handle.id = server->last_autoresponder_id++; - /* TODO: peek and see if a matching request is enqueued */ - _mongoc_array_append_val (&server->autoresponders, handle); - bson_mutex_unlock (&server->mutex); - - return id; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_remove_autoresponder -- - * - * Remove a responder callback. Pass in the id returned by - * mock_server_autoresponds. - * - * Returns: - * None. - * - * Side effects: - * The responder's destructor is called on its "data" pointer. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_remove_autoresponder (mock_server_t *server, int id) -{ - size_t i; - autoresponder_handle_t *handles; - - bson_mutex_lock (&server->mutex); - handles = (autoresponder_handle_t *) server->autoresponders.data; - for (i = 0; i < server->autoresponders.len; i++) { - if (handles[i].id == id) { - /* left-shift everyone after */ - server->autoresponders.len--; - for (; i < server->autoresponders.len; i++) { - handles[i] = handles[i + 1]; - } - - autoresponder_handle_destroy (handles); - - break; - } - } - - bson_mutex_unlock (&server->mutex); -} - - -static bool -auto_ismaster (request_t *request, void *data) -{ - const char *response_json = (const char *) data; - char *quotes_replaced; - bson_t response; - bson_error_t error; - - if (!request->is_command || strcasecmp (request->command_name, "ismaster")) { - return false; - } - - quotes_replaced = single_quotes_to_double (response_json); - - if (!bson_init_from_json (&response, quotes_replaced, -1, &error)) { - fprintf (stderr, "%s\n", error.message); - fflush (stderr); - abort (); - } - - if (mock_server_get_rand_delay (request->server)) { - _mongoc_usleep ((int64_t) (rand () % 10) * 1000); - } - - mock_server_replies (request, MONGOC_REPLY_NONE, 0, 0, 1, response_json); - - bson_destroy (&response); - bson_free (quotes_replaced); - request_destroy (request); - return true; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_auto_ismaster -- - * - * Autorespond to "ismaster" with the provided document. - * - * Returns: - * An id for mock_server_remove_autoresponder. - * - * Side effects: - * If a matching request is enqueued, pop it and respond. - * - *-------------------------------------------------------------------------- - */ - -MONGOC_PRINTF_FORMAT (2, 3) -int -mock_server_auto_ismaster (mock_server_t *server, - const char *response_json, - ...) -{ - char *formatted_response_json; - va_list args; - bson_t *tmp; - bson_iter_t iter; - - va_start (args, response_json); - formatted_response_json = bson_strdupv_printf (response_json, args); - va_end (args); - tmp = tmp_bson (formatted_response_json); - - if (!bson_iter_init_find (&iter, tmp, "minWireVersion")) { - BSON_APPEND_INT32 (tmp, "minWireVersion", WIRE_VERSION_MIN); - } - if (!bson_iter_init_find (&iter, tmp, "maxWireVersion")) { - BSON_APPEND_INT32 (tmp, "maxWireVersion", WIRE_VERSION_OP_MSG - 1); - } - bson_free (formatted_response_json); - formatted_response_json = bson_as_json (tmp, 0); - - return mock_server_autoresponds ( - server, auto_ismaster, (void *) formatted_response_json, bson_free); -} - - -static bool -auto_endsessions (request_t *request, void *data) -{ - if (!request->is_command || - strcasecmp (request->command_name, "endSessions") != 0) { - return false; - } - - mock_server_replies_ok_and_destroys (request); - return true; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_auto_endsessions -- - * - * Autorespond to "endSessions". - * - * Returns: - * An id for mock_server_remove_autoresponder. - * - * Side effects: - * If a matching request is enqueued, pop it and respond. - * - *-------------------------------------------------------------------------- - */ - -int -mock_server_auto_endsessions (mock_server_t *server) -{ - return mock_server_autoresponds (server, auto_endsessions, NULL, NULL); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_get_uri -- - * - * Call after mock_server_run to get the connection string. - * - * Returns: - * A const URI. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const mongoc_uri_t * -mock_server_get_uri (mock_server_t *server) -{ - mongoc_uri_t *uri; - - bson_mutex_lock (&server->mutex); - uri = server->uri; - bson_mutex_unlock (&server->mutex); - - return uri; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_get_host_and_port -- - * - * Call after mock_server_run to get the server's "host:port". - * - * Returns: - * A const string. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -const char * -mock_server_get_host_and_port (mock_server_t *server) -{ - const mongoc_uri_t *uri; - - uri = mock_server_get_uri (server); - BSON_ASSERT (uri); /* must call after mock_server_run */ - return (mongoc_uri_get_hosts (uri))->host_and_port; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_get_port -- - * - * Call after mock_server_run to get the server's listening port. - * - * Returns: - * A port number. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -uint16_t -mock_server_get_port (mock_server_t *server) -{ - return server->port; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_get_request_timeout_msec -- - * - * How long mock_server_receives_* functions wait for a client - * request before giving up and returning NULL. - * - *-------------------------------------------------------------------------- - */ - -int64_t -mock_server_get_request_timeout_msec (mock_server_t *server) -{ - int64_t request_timeout_msec; - - bson_mutex_lock (&server->mutex); - request_timeout_msec = server->request_timeout_msec; - bson_mutex_unlock (&server->mutex); - - return request_timeout_msec; -} - -/*-------------------------------------------------------------------------- - * - * mock_server_set_request_timeout_msec -- - * - * How long mock_server_receives_* functions wait for a client - * request before giving up and returning NULL. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_set_request_timeout_msec (mock_server_t *server, - int64_t request_timeout_msec) -{ - bson_mutex_lock (&server->mutex); - server->request_timeout_msec = request_timeout_msec; - bson_mutex_unlock (&server->mutex); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_get_rand_delay -- - * - * Does the server delay a random duration before responding? - * - *-------------------------------------------------------------------------- - */ - -bool -mock_server_get_rand_delay (mock_server_t *server) -{ - bool rand_delay; - - bson_mutex_lock (&server->mutex); - rand_delay = server->rand_delay; - bson_mutex_unlock (&server->mutex); - - return rand_delay; -} - -/*-------------------------------------------------------------------------- - * - * mock_server_set_rand_delay -- - * - * Whether to delay a random duration before responding. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_set_rand_delay (mock_server_t *server, bool rand_delay) -{ - bson_mutex_lock (&server->mutex); - server->rand_delay = rand_delay; - bson_mutex_unlock (&server->mutex); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_get_uptime_sec -- - * - * How long since mock_server_run() was called. - * - *-------------------------------------------------------------------------- - */ - -double -mock_server_get_uptime_sec (mock_server_t *server) -{ - double uptime; - - bson_mutex_lock (&server->mutex); - uptime = (bson_get_monotonic_time () - server->start_time) / 1e6; - bson_mutex_unlock (&server->mutex); - - return uptime; -} - - -sync_queue_t * -mock_server_get_queue (mock_server_t *server) -{ - sync_queue_t *q; - - bson_mutex_lock (&server->mutex); - q = server->q; - bson_mutex_unlock (&server->mutex); - - return q; -} - - -static void -request_assert_no_duplicate_keys (request_t *request) -{ - int i; - - for (i = 0; i < request->docs.len; i++) { - assert_no_duplicate_keys (request_get_doc (request, i)); - } -} - - -request_t * -mock_server_receives_request (mock_server_t *server) -{ - sync_queue_t *q; - int64_t request_timeout_msec; - request_t *r; - - q = mock_server_get_queue (server); - request_timeout_msec = mock_server_get_request_timeout_msec (server); - r = (request_t *) q_get (q, request_timeout_msec); - if (r) { - request_assert_no_duplicate_keys (r); - } - - return r; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_command -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not an OP_QUERY command matching - * database_name, command_name, and command_json. - * - *-------------------------------------------------------------------------- - */ - -MONGOC_PRINTF_FORMAT (4, 5) -request_t * -mock_server_receives_command (mock_server_t *server, - const char *database_name, - mongoc_query_flags_t flags, - const char *command_json, - ...) -{ - va_list args; - char *formatted_command_json = NULL; - char *ns; - request_t *request; - - va_start (args, command_json); - if (command_json) { - formatted_command_json = bson_strdupv_printf (command_json, args); - } - va_end (args); - - ns = bson_strdup_printf ("%s.$cmd", database_name); - - request = mock_server_receives_request (server); - - if (request && - !request_matches_query ( - request, ns, flags, 0, 1, formatted_command_json, NULL, true)) { - request_destroy (request); - request = NULL; - } - - bson_free (formatted_command_json); - bson_free (ns); - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_msg -- - * - * Pop a client OP_MSG request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. Pass varargs - * list of bson_t pointers, which are matched to the series of - * documents in the request, regardless of section boundaries. - * - * Returns: - * A request you must request_destroy. - * - * Side effects: - * Logs and aborts if the current request is not an OP_MSG matching - * flags and documents. - * - *-------------------------------------------------------------------------- - */ - -request_t * -_mock_server_receives_msg (mock_server_t *server, uint32_t flags, ...) -{ - request_t *request; - va_list args; - bool r; - - request = mock_server_receives_request (server); - - va_start (args, flags); - r = request_matches_msgv (request, flags, &args); - va_end (args); - - if (!r) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_ismaster -- - * - * Pop a client ismaster call if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the current - * request is not an ismaster command. - * - * Side effects: - * Logs if the current request is not an ismaster command. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_server_receives_ismaster (mock_server_t *server) -{ - return mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, "{'isMaster': 1}"); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_query -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not a query matching ns, flags, - * skip, n_return, query_json, and fields_json. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_server_receives_query (mock_server_t *server, - const char *ns, - mongoc_query_flags_t flags, - uint32_t skip, - int32_t n_return, - const char *query_json, - const char *fields_json) -{ - request_t *request; - - request = mock_server_receives_request (server); - - if (request && - !request_matches_query ( - request, ns, flags, skip, n_return, query_json, fields_json, false)) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_insert -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not an insert matching ns, flags, - * and doc_json. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_server_receives_insert (mock_server_t *server, - const char *ns, - mongoc_insert_flags_t flags, - const char *doc_json) -{ - request_t *request; - - request = mock_server_receives_request (server); - - if (request && !request_matches_insert (request, ns, flags, doc_json)) { - request_destroy (request); - return NULL; - } - - return request; -} - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_bulk_insert -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not an insert matching ns and flags, - * with "n" documents. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_server_receives_bulk_insert (mock_server_t *server, - const char *ns, - mongoc_insert_flags_t flags, - int n) -{ - request_t *request; - - request = mock_server_receives_request (server); - - if (request && !request_matches_bulk_insert (request, ns, flags, n)) { - request_destroy (request); - return NULL; - } - - return request; -} - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_update -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not an update matching ns, flags, - * selector_json, and update_json. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_server_receives_update (mock_server_t *server, - const char *ns, - mongoc_update_flags_t flags, - const char *selector_json, - const char *update_json) -{ - request_t *request; - - request = mock_server_receives_request (server); - - if (request && - !request_matches_update ( - request, ns, flags, selector_json, update_json)) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_delete -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not a delete matching ns, flags, - * and selector_json. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_server_receives_delete (mock_server_t *server, - const char *ns, - mongoc_remove_flags_t flags, - const char *selector_json) -{ - request_t *request; - - request = mock_server_receives_request (server); - - if (request && !request_matches_delete (request, ns, flags, selector_json)) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_getmore -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Returns: - * A request you must request_destroy, or NULL if the request does - * not match. - * - * Side effects: - * Logs if the current request is not a getmore matching n_return - * and cursor_id. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_server_receives_getmore (mock_server_t *server, - const char *ns, - int32_t n_return, - int64_t cursor_id) -{ - request_t *request; - - request = mock_server_receives_request (server); - - if (request && !request_matches_getmore (request, ns, n_return, cursor_id)) { - request_destroy (request); - return NULL; - } - - return request; -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_receives_kill_cursors -- - * - * Pop a client request if one is enqueued, or wait up to - * request_timeout_ms for the client to send a request. - * - * Real-life OP_KILLCURSORS can take multiple ids, but that is - * not yet supported here. - * - * Returns: - * A request you must request_destroy, or NULL if the request - * does not match. - * - * Side effects: - * Logs if the current request is not an OP_KILLCURSORS with the - * expected cursor_id. - * - *-------------------------------------------------------------------------- - */ - -request_t * -mock_server_receives_kill_cursors (mock_server_t *server, int64_t cursor_id) -{ - request_t *request; - - request = mock_server_receives_request (server); - - if (request && !request_matches_kill_cursors (request, cursor_id)) { - request_destroy (request); - return NULL; - } - - return request; -} - -/*-------------------------------------------------------------------------- - * - * mock_server_hangs_up -- - * - * Hang up on a client request. - * - * Returns: - * None. - * - * Side effects: - * Causes a network error on the client side. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_hangs_up (request_t *request) -{ - test_suite_mock_server_log ("%5.2f %hu <- %hu \thang up!", - mock_server_get_uptime_sec (request->server), - request->client_port, - request_get_server_port (request)); - - mongoc_stream_close (request->client); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_resets -- - * - * Forcefully reset a connection from the client. - * - * Returns: - * None. - * - * Side effects: - * Causes ECONNRESET on the client side. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_resets (request_t *request) -{ - struct linger no_linger; - no_linger.l_onoff = 1; - no_linger.l_linger = 0; - - test_suite_mock_server_log ("%5.2f %hu <- %hu \treset!", - mock_server_get_uptime_sec (request->server), - request->client_port, - request_get_server_port (request)); - - /* send RST packet to client */ - mongoc_stream_setsockopt ( - request->client, SOL_SOCKET, SO_LINGER, &no_linger, sizeof no_linger); - - mongoc_stream_close (request->client); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_replies -- - * - * Respond to a client request. - * - * Returns: - * None. - * - * Side effects: - * Sends an OP_REPLY to the client. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_replies (request_t *request, - mongoc_reply_flags_t flags, - int64_t cursor_id, - int32_t starting_from, - int32_t number_returned, - const char *docs_json) -{ - char *quotes_replaced; - bson_t doc; - bson_error_t error; - bool r; - - BSON_ASSERT (request); - - if (docs_json) { - quotes_replaced = single_quotes_to_double (docs_json); - r = bson_init_from_json (&doc, quotes_replaced, -1, &error); - bson_free (quotes_replaced); - } else { - r = bson_init_from_json (&doc, "{}", -1, &error); - } - - if (!r) { - MONGOC_WARNING ("%s", error.message); - return; - } - - mock_server_reply_multi (request, flags, &doc, 1, cursor_id); - bson_destroy (&doc); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_replies_simple -- - * - * Respond to a client request. - * - * Returns: - * None. - * - * Side effects: - * Sends an OP_REPLY to the client. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_replies_simple (request_t *request, const char *docs_json) -{ - mock_server_replies (request, MONGOC_REPLY_NONE, 0, 0, 1, docs_json); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_replies_ok_and_destroys -- - * - * Respond to a client request. - * - * Returns: - * None. - * - * Side effects: - * Sends an OP_REPLY with "{ok: 1}" to the client. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_replies_ok_and_destroys (request_t *request) -{ - mock_server_replies (request, MONGOC_REPLY_NONE, 0, 0, 1, "{'ok': 1}"); - request_destroy (request); -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_replies_to_find -- - * - * Receive an OP_QUERY or "find" command and reply appropriately. - * - * Returns: - * None. - * - * Side effects: - * Very roughly validates the query or "find" command or aborts. - * The intent is not to test the driver's query or find command - * implementation here, see _test_kill_cursors for example use. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_replies_to_find (request_t *request, - mongoc_query_flags_t flags, - int64_t cursor_id, - int32_t number_returned, - const char *ns, - const char *reply_json, - bool is_command) -{ - char *find_reply; - char db[MONGOC_NAMESPACE_MAX]; - - _mongoc_get_db_name (ns, db); - - /* minimal validation, we're not testing query / find cmd here */ - if (request->is_command && !is_command) { - test_error ("expected query, got command"); - abort (); - } - - if (!request->is_command && is_command) { - test_error ("expected command, got query"); - abort (); - } - - if (!request_matches_flags (request, flags)) { - abort (); - } - - if (is_command) { - find_reply = - bson_strdup_printf ("{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '%" PRId64 "'}," - " 'ns': '%s'," - " 'firstBatch': [%s]}}", - cursor_id, - ns, - reply_json); - - mock_server_replies_simple (request, find_reply); - bson_free (find_reply); - } else { - mock_server_replies ( - request, MONGOC_REPLY_NONE, cursor_id, 0, number_returned, reply_json); - } -} - - -/*-------------------------------------------------------------------------- - * - * mock_server_destroy -- - * - * Free a mock_server_t. - * - * Returns: - * None. - * - * Side effects: - * Closes sockets, joins threads, and calls destructors passed - * to mock_server_autoresponds. - * - *-------------------------------------------------------------------------- - */ - -void -mock_server_destroy (mock_server_t *server) -{ - size_t i; - autoresponder_handle_t *handle; - int64_t deadline = bson_get_monotonic_time () + 10 * 1000 * 1000; - request_t *request; - - bson_mutex_lock (&server->mutex); - if (server->running) { - server->stopped = true; - } - bson_mutex_unlock (&server->mutex); - - while (bson_get_monotonic_time () <= deadline) { - /* wait 10 seconds */ - bson_mutex_lock (&server->mutex); - if (!server->running) { - bson_mutex_unlock (&server->mutex); - break; - } - - bson_mutex_unlock (&server->mutex); - _mongoc_usleep (1000); - } - - bson_mutex_lock (&server->mutex); - if (server->running) { - fprintf (stderr, "server still running after timeout\n"); - fflush (stderr); - abort (); - } - - bson_mutex_unlock (&server->mutex); - bson_thread_join (server->main_thread); - - _mongoc_array_destroy (&server->worker_threads); - - for (i = 0; i < server->autoresponders.len; i++) { - handle = &_mongoc_array_index ( - &server->autoresponders, autoresponder_handle_t, i); - - autoresponder_handle_destroy (handle); - } - - _mongoc_array_destroy (&server->autoresponders); - - mongoc_cond_destroy (&server->cond); - bson_mutex_destroy (&server->mutex); - mongoc_socket_destroy (server->sock); - bson_free (server->uri_str); - mongoc_uri_destroy (server->uri); - - while ((request = (request_t *) q_get_nowait (server->q))) { - request_destroy (request); - } - - q_destroy (server->q); - bson_free (server); -} - - -static uint16_t -get_port (mongoc_socket_t *sock) -{ - struct sockaddr_storage bound_addr = {0}; - mongoc_socklen_t addr_len = (mongoc_socklen_t) sizeof bound_addr; - - if (mongoc_socket_getsockname ( - sock, (struct sockaddr *) &bound_addr, &addr_len) < 0) { - perror ("Failed to get listening port number"); - return 0; - } - - if (bound_addr.ss_family == AF_INET6) { - return ntohs (((struct sockaddr_in6 *) &bound_addr)->sin6_port); - } else { - return ntohs (((struct sockaddr_in *) &bound_addr)->sin_port); - } -} - - -static bool -_mock_server_stopping (mock_server_t *server) -{ - bool stopped; - - bson_mutex_lock (&server->mutex); - stopped = server->stopped; - bson_mutex_unlock (&server->mutex); - - return stopped; -} - - -typedef struct worker_closure_t { - mock_server_t *server; - mongoc_stream_t *client_stream; - uint16_t port; -} worker_closure_t; - - -static void * -main_thread (void *data) -{ - mock_server_t *server = (mock_server_t *) data; - mongoc_socket_t *client_sock; - uint16_t port; - mongoc_stream_t *client_stream; - worker_closure_t *closure; - bson_thread_t thread; - mongoc_array_t worker_threads; - size_t i; - - bson_mutex_lock (&server->mutex); - server->running = true; - mongoc_cond_signal (&server->cond); - bson_mutex_unlock (&server->mutex); - - for (;;) { - client_sock = mongoc_socket_accept_ex ( - server->sock, bson_get_monotonic_time () + 100 * 1000, &port); - - if (_mock_server_stopping (server)) { - mongoc_socket_destroy (client_sock); - break; - } - - if (client_sock) { - test_suite_mock_server_log ( - "%5.2f %hu -> server port %hu (connected)", - mock_server_get_uptime_sec (server), - port, - server->port); - - client_stream = mongoc_stream_socket_new (client_sock); - -#ifdef MONGOC_ENABLE_SSL - bson_mutex_lock (&server->mutex); - if (server->ssl) { - mongoc_stream_t *tls_stream; - server->ssl_opts.weak_cert_validation = 1; - tls_stream = mongoc_stream_tls_new_with_hostname ( - client_stream, NULL, &server->ssl_opts, 0); - if (!tls_stream) { - mongoc_stream_destroy (client_stream); - bson_mutex_unlock (&server->mutex); - perror ("Failed to attach tls stream"); - break; - } - client_stream = tls_stream; - } - bson_mutex_unlock (&server->mutex); -#endif - closure = (worker_closure_t *) bson_malloc (sizeof *closure); - closure->server = server; - closure->client_stream = client_stream; - closure->port = port; - - bson_mutex_lock (&server->mutex); - bson_thread_create (&thread, worker_thread, closure); - _mongoc_array_append_val (&server->worker_threads, thread); - bson_mutex_unlock (&server->mutex); - } - } - - /* copy list of worker threads and join them all */ - _mongoc_array_init (&worker_threads, sizeof (bson_thread_t)); - bson_mutex_lock (&server->mutex); - _mongoc_array_copy (&worker_threads, &server->worker_threads); - bson_mutex_unlock (&server->mutex); - - for (i = 0; i < worker_threads.len; i++) { - bson_thread_join ( - _mongoc_array_index (&worker_threads, bson_thread_t, i)); - } - - _mongoc_array_destroy (&worker_threads); - - bson_mutex_lock (&server->mutex); - server->running = false; - bson_mutex_unlock (&server->mutex); - - return NULL; -} - - -static void -_reply_destroy (reply_t *reply) -{ - int i; - - for (i = 0; i < reply->n_docs; i++) { - bson_destroy (&reply->docs[i]); - } - - bson_free (reply->docs); - bson_free (reply); -} - - -static void * -worker_thread (void *data) -{ - worker_closure_t *closure = (worker_closure_t *) data; - mock_server_t *server = closure->server; - mongoc_stream_t *client_stream = closure->client_stream; - mongoc_buffer_t buffer; - mongoc_rpc_t *rpc = NULL; - bool handled; - bson_error_t error; - int32_t msg_len; - sync_queue_t *requests; - sync_queue_t *replies; - request_t *request; - mongoc_array_t autoresponders; - ssize_t i; - autoresponder_handle_t handle; - reply_t *reply; - -#ifdef MONGOC_ENABLE_SSL - bool ssl; -#endif - - ENTRY; - - /* queue of client replies sent over this worker's connection */ - replies = q_new (); - -#ifdef MONGOC_ENABLE_SSL - bson_mutex_lock (&server->mutex); - ssl = server->ssl; - bson_mutex_unlock (&server->mutex); - - if (ssl) { - if (!mongoc_stream_tls_handshake_block ( - client_stream, "localhost", TIMEOUT, &error)) { - mongoc_stream_close (client_stream); - mongoc_stream_destroy (client_stream); - bson_free (closure); - q_destroy (replies); - RETURN (NULL); - } - } -#endif - - _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); - _mongoc_array_init (&autoresponders, sizeof (autoresponder_handle_t)); - -again: - /* loop, checking for requests to receive or replies to send */ - bson_free (rpc); - rpc = NULL; - - if (_mongoc_buffer_fill (&buffer, client_stream, 4, 10, &error) > 0) { - BSON_ASSERT (buffer.len >= 4); - - memcpy (&msg_len, buffer.data, 4); - msg_len = BSON_UINT32_FROM_LE (msg_len); - - if (msg_len < 16) { - MONGOC_WARNING ("No data"); - GOTO (failure); - } - - if (_mongoc_buffer_fill ( - &buffer, client_stream, (size_t) msg_len, -1, &error) == -1) { - MONGOC_WARNING ("%s():%d: %s", BSON_FUNC, __LINE__, error.message); - GOTO (failure); - } - - BSON_ASSERT (buffer.len >= (unsigned) msg_len); - - /* copies message from buffer */ - request = request_new ( - &buffer, msg_len, server, client_stream, closure->port, replies); - - memmove (buffer.data, buffer.data + msg_len, buffer.len - msg_len); - buffer.len -= msg_len; - - bson_mutex_lock (&server->mutex); - _mongoc_array_copy (&autoresponders, &server->autoresponders); - bson_mutex_unlock (&server->mutex); - - test_suite_mock_server_log ("%5.2f %hu -> %hu %s", - mock_server_get_uptime_sec (server), - closure->port, - server->port, - request->as_str); - - /* run responders most-recently-added-first */ - handled = false; - - for (i = server->autoresponders.len - 1; i >= 0; i--) { - handle = _mongoc_array_index ( - &server->autoresponders, autoresponder_handle_t, i); - - if (handle.responder (request, handle.data)) { - /* responder destroyed request and enqueued a reply in "replies" */ - handled = true; - request = NULL; - break; - } - } - - if (!handled) { - /* pass to the main thread via the queue */ - requests = mock_server_get_queue (server); - q_put (requests, (void *) request); - } - } - - if (_mock_server_stopping (server)) { - GOTO (failure); - } - - reply = q_get (replies, 10); - if (reply) { - _mock_server_reply_with_stream (server, reply, client_stream); - _reply_destroy (reply); - } - - if (_mock_server_stopping (server)) { - GOTO (failure); - } - - GOTO (again); - -failure: - _mongoc_array_destroy (&autoresponders); - _mongoc_buffer_destroy (&buffer); - - mongoc_stream_close (client_stream); - mongoc_stream_destroy (client_stream); - bson_free (rpc); - bson_free (closure); - _mongoc_buffer_destroy (&buffer); - - while ((reply = q_get_nowait (replies))) { - _reply_destroy (reply); - } - - q_destroy (replies); - - RETURN (NULL); -} - - -/* enqueue server reply for this connection's worker thread to send to client */ -void -mock_server_reply_multi (request_t *request, - mongoc_reply_flags_t flags, - const bson_t *docs, - int n_docs, - int64_t cursor_id) -{ - reply_t *reply; - int i; - - BSON_ASSERT (request); - - reply = bson_malloc0 (sizeof (reply_t)); - - reply->flags = flags; - reply->n_docs = n_docs; - reply->docs = bson_malloc0 (n_docs * sizeof (bson_t)); - - for (i = 0; i < n_docs; i++) { - bson_copy_to (&docs[i], &reply->docs[i]); - } - - reply->cursor_id = cursor_id; - reply->client_port = request_get_client_port (request); - reply->request_opcode = (mongoc_opcode_t) request->request_rpc.header.opcode; - reply->query_flags = (mongoc_query_flags_t) request->request_rpc.query.flags; - reply->response_to = request->request_rpc.header.request_id; - - q_put (request->replies, reply); -} - - -static void -_mock_server_reply_with_stream (mock_server_t *server, - reply_t *reply, - mongoc_stream_t *client) -{ - char *doc_json; - bson_string_t *docs_json; - mongoc_iovec_t *iov; - mongoc_array_t ar; - mongoc_rpc_t r = {{0}}; - size_t expected = 0; - ssize_t n_written; - int iovcnt; - int i; - uint8_t *buf; - uint8_t *ptr; - size_t len; - bool is_op_msg; - - mongoc_reply_flags_t flags = reply->flags; - const bson_t *docs = reply->docs; - int n_docs = reply->n_docs; - int64_t cursor_id = reply->cursor_id; - - docs_json = bson_string_new (""); - for (i = 0; i < n_docs; i++) { - doc_json = bson_as_json (&docs[i], NULL); - bson_string_append (docs_json, doc_json); - bson_free (doc_json); - if (i < n_docs - 1) { - bson_string_append (docs_json, ", "); - } - } - - is_op_msg = reply->request_opcode == MONGOC_OPCODE_MSG; - - test_suite_mock_server_log ("%5.2f %hu <- %hu %s %s", - mock_server_get_uptime_sec (server), - reply->client_port, - mock_server_get_port (server), - is_op_msg ? "OP_MSG" : "OP_REPLY", - docs_json->str); - - len = 0; - - for (i = 0; i < n_docs; i++) { - len += docs[i].len; - } - - ptr = buf = bson_malloc (len); - - for (i = 0; i < n_docs; i++) { - memcpy (ptr, bson_get_data (&docs[i]), docs[i].len); - ptr += docs[i].len; - } - - _mongoc_array_init (&ar, sizeof (mongoc_iovec_t)); - - bson_mutex_lock (&server->mutex); - - if (!(reply->request_opcode == MONGOC_OPCODE_QUERY && - reply->query_flags & MONGOC_QUERY_EXHAUST)) { - server->last_response_id++; - } - - r.header.request_id = server->last_response_id; - bson_mutex_unlock (&server->mutex); - r.header.msg_len = 0; - r.header.response_to = reply->response_to; - - if (is_op_msg) { - r.header.opcode = MONGOC_OPCODE_MSG; - r.msg.n_sections = 1; - /* we don't yet implement payload type 1, a document stream */ - r.msg.sections[0].payload_type = 0; - r.msg.sections[0].payload.bson_document = buf; - } else { - r.header.opcode = MONGOC_OPCODE_REPLY; - r.reply.flags = flags; - r.reply.cursor_id = cursor_id; - r.reply.start_from = 0; - r.reply.n_returned = 1; - r.reply.documents = buf; - r.reply.documents_len = (uint32_t) len; - } - - _mongoc_rpc_gather (&r, &ar); - _mongoc_rpc_swab_to_le (&r); - - iov = (mongoc_iovec_t *) ar.data; - iovcnt = (int) ar.len; - - for (i = 0; i < iovcnt; i++) { - expected += iov[i].iov_len; - } - - n_written = mongoc_stream_writev (client, iov, (size_t) iovcnt, -1); - - BSON_ASSERT (n_written == expected); - - bson_string_free (docs_json, true); - _mongoc_array_destroy (&ar); - bson_free (buf); -} - - -void -autoresponder_handle_destroy (autoresponder_handle_t *handle) -{ - if (handle->destructor) { - handle->destructor (handle->data); - } -} - -void -mock_server_set_bind_opts (mock_server_t *server, mock_server_bind_opts_t *opts) -{ - server->bind_opts = *opts; -} - -void -rs_response_to_ismaster ( - mock_server_t *server, int max_wire_version, bool primary, int has_tags, ...) -{ - va_list ap; - bson_string_t *hosts; - bool first; - mock_server_t *host; - const char *session_timeout; - char *ismaster_response; - - hosts = bson_string_new (""); - - va_start (ap, has_tags); - - first = true; - while ((host = va_arg (ap, mock_server_t *))) { - if (first) { - first = false; - } else { - bson_string_append (hosts, ","); - } - - bson_string_append_printf ( - hosts, "'%s'", mock_server_get_host_and_port (host)); - } - - va_end (ap); - - if (max_wire_version >= 6) { - session_timeout = ", 'logicalSessionTimeoutMinutes': 30"; - mock_server_auto_endsessions (server); - } else { - session_timeout = ""; - } - - ismaster_response = bson_strdup_printf ("{'ok': 1, " - " 'setName': 'rs'," - " 'ismaster': %s," - " 'secondary': %s," - " 'tags': {%s}," - " 'minWireVersion': 3," - " 'maxWireVersion': %d," - " 'hosts': [%s]" - " %s" - "}", - primary ? "true" : "false", - primary ? "false" : "true", - has_tags ? "'key': 'value'" : "", - max_wire_version, - hosts->str, - session_timeout); - - mock_server_auto_ismaster (server, "%s", ismaster_response); - - bson_free (ismaster_response); - bson_string_free (hosts, true); -} diff --git a/lib/mongoc/libmongoc/tests/mock_server/mock-server.h b/lib/mongoc/libmongoc/tests/mock_server/mock-server.h deleted file mode 100644 index fc8a25d91cdefb8ff8eec0744b0bb58d803584ee..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/mock-server.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2015 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 MOCK_SERVER_H -#define MOCK_SERVER_H - -#include <bson/bson.h> - -#include "mongoc/mongoc-uri.h" - -#ifdef MONGOC_ENABLE_SSL -#include "mongoc/mongoc-ssl.h" -#endif - -#include "request.h" - -typedef struct _mock_server_t mock_server_t; -typedef struct _autoresponder_handle_t autoresponder_handle_t; - -typedef struct _mock_server_bind_opts_t { - struct sockaddr_in *bind_addr; - size_t bind_addr_len; - int family; - int ipv6_only; -} mock_server_bind_opts_t; - -typedef bool (*autoresponder_t) (request_t *request, void *data); - -typedef void (*destructor_t) (void *data); - -mock_server_t * -mock_server_new (); - -mock_server_t * -mock_server_with_autoismaster (int32_t max_wire_version); - -mock_server_t * -mock_mongos_new (int32_t max_wire_version); - -mock_server_t * -mock_server_down (void); - -int -mock_server_autoresponds (mock_server_t *server, - autoresponder_t responder, - void *data, - destructor_t destructor); - -void -mock_server_remove_autoresponder (mock_server_t *server, int id); - -int -mock_server_auto_ismaster (mock_server_t *server, - const char *response_json, - ...); - -int -mock_server_auto_endsessions (mock_server_t *server); - -#ifdef MONGOC_ENABLE_SSL - -void -mock_server_set_ssl_opts (mock_server_t *server, mongoc_ssl_opt_t *opts); - -#endif - -void -mock_server_set_bind_opts (mock_server_t *server, - mock_server_bind_opts_t *opts); - -uint16_t -mock_server_run (mock_server_t *server); - -const mongoc_uri_t * -mock_server_get_uri (mock_server_t *server); - -const char * -mock_server_get_host_and_port (mock_server_t *server); - -uint16_t -mock_server_get_port (mock_server_t *server); - -int64_t -mock_server_get_request_timeout_msec (mock_server_t *server); - -void -mock_server_set_request_timeout_msec (mock_server_t *server, - int64_t request_timeout_msec); - -bool -mock_server_get_rand_delay (mock_server_t *server); - -void -mock_server_set_rand_delay (mock_server_t *server, bool rand_delay); - -double -mock_server_get_uptime_sec (mock_server_t *server); - -request_t * -mock_server_receives_request (mock_server_t *server); - -request_t * -mock_server_receives_command (mock_server_t *server, - const char *database_name, - mongoc_query_flags_t flags, - const char *command_json, - ...); - -request_t * -mock_server_receives_ismaster (mock_server_t *server); - -request_t * -mock_server_receives_query (mock_server_t *server, - const char *ns, - mongoc_query_flags_t flags, - uint32_t skip, - int32_t n_return, - const char *query_json, - const char *fields_json); - -request_t * -mock_server_receives_insert (mock_server_t *server, - const char *ns, - mongoc_insert_flags_t flags, - const char *doc_json); - -request_t * -mock_server_receives_bulk_insert (mock_server_t *server, - const char *ns, - mongoc_insert_flags_t flags, - int n); - -request_t * -mock_server_receives_update (mock_server_t *server, - const char *ns, - mongoc_update_flags_t flags, - const char *selector_json, - const char *update_json); - -request_t * -mock_server_receives_delete (mock_server_t *server, - const char *ns, - mongoc_remove_flags_t flags, - const char *selector_json); - -request_t * -mock_server_receives_getmore (mock_server_t *server, - const char *ns, - int32_t n_return, - int64_t cursor_id); - -request_t * -mock_server_receives_kill_cursors (mock_server_t *server, int64_t cursor_id); - -request_t * -_mock_server_receives_msg (mock_server_t *server, uint32_t flags, ...); -#define mock_server_receives_msg(_server, _flags, ...) \ - _mock_server_receives_msg (_server, _flags, __VA_ARGS__, NULL) - -void -mock_server_hangs_up (request_t *request); - -void -mock_server_resets (request_t *request); - -void -mock_server_replies (request_t *request, - mongoc_reply_flags_t flags, - int64_t cursor_id, - int32_t starting_from, - int32_t number_returned, - const char *docs_json); - -void -mock_server_replies_simple (request_t *request, const char *docs_json); - -void -mock_server_replies_ok_and_destroys (request_t *request); - -void -mock_server_replies_to_find (request_t *request, - mongoc_query_flags_t flags, - int64_t cursor_id, - int32_t number_returned, - const char *ns, - const char *reply_json, - bool is_command); - -void -mock_server_reply_multi (request_t *request, - mongoc_reply_flags_t flags, - const bson_t *docs, - int n_docs, - int64_t cursor_id); - -void -mock_server_destroy (mock_server_t *server); - -void -rs_response_to_ismaster (mock_server_t *server, - int max_wire_version, - bool primary, - int has_tags, - ...); - -#define RS_RESPONSE_TO_ISMASTER(server, primary, has_tags, ...) \ - rs_response_to_ismaster (server, primary, has_tags, __VA_ARGS__, NULL) - -#endif /* MOCK_SERVER_H */ diff --git a/lib/mongoc/libmongoc/tests/mock_server/request.c b/lib/mongoc/libmongoc/tests/mock_server/request.c deleted file mode 100644 index f52f65e8b6d38b8aca35a7742f630c3fadba0ddd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/request.c +++ /dev/null @@ -1,1141 +0,0 @@ -/* - * Copyright 2015 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 <mongoc/mongoc-rpc-private.h> -#include "mongoc/mongoc.h" - -#include "mock-server.h" -#include "../test-conveniences.h" -#include "../TestSuite.h" - - -static bool -is_command_ns (const char *ns); - -static void -request_from_query (request_t *request, const mongoc_rpc_t *rpc); - -static void -request_from_insert (request_t *request, const mongoc_rpc_t *rpc); - -static void -request_from_update (request_t *request, const mongoc_rpc_t *rpc); - -static void -request_from_delete (request_t *request, const mongoc_rpc_t *rpc); - -static void -request_from_killcursors (request_t *request, const mongoc_rpc_t *rpc); - -static void -request_from_getmore (request_t *request, const mongoc_rpc_t *rpc); - -static void -request_from_op_msg (request_t *request, const mongoc_rpc_t *rpc); - -static char * -query_flags_str (uint32_t flags); -static char * -insert_flags_str (uint32_t flags); -static char * -update_flags_str (uint32_t flags); -static char * -delete_flags_str (uint32_t flags); - -request_t * -request_new (const mongoc_buffer_t *buffer, - int32_t msg_len, - mock_server_t *server, - mongoc_stream_t *client, - uint16_t client_port, - sync_queue_t *replies) -{ - request_t *request = (request_t *) bson_malloc0 (sizeof *request); - uint8_t *data; - - data = (uint8_t *) bson_malloc ((size_t) msg_len); - memcpy (data, buffer->data, (size_t) msg_len); - request->data = data; - request->data_len = (size_t) msg_len; - request->replies = replies; - - if (!_mongoc_rpc_scatter (&request->request_rpc, data, (size_t) msg_len)) { - MONGOC_WARNING ("%s():%d: %s", BSON_FUNC, __LINE__, "Failed to scatter"); - bson_free (data); - bson_free (request); - return NULL; - } - - _mongoc_rpc_swab_from_le (&request->request_rpc); - - request->opcode = (mongoc_opcode_t) request->request_rpc.header.opcode; - request->server = server; - request->client = client; - request->client_port = client_port; - _mongoc_array_init (&request->docs, sizeof (bson_t *)); - - switch (request->opcode) { - case MONGOC_OPCODE_COMPRESSED: - break; - case MONGOC_OPCODE_QUERY: - request_from_query (request, &request->request_rpc); - break; - - case MONGOC_OPCODE_INSERT: - request_from_insert (request, &request->request_rpc); - break; - - case MONGOC_OPCODE_UPDATE: - request_from_update (request, &request->request_rpc); - break; - - case MONGOC_OPCODE_KILL_CURSORS: - request_from_killcursors (request, &request->request_rpc); - break; - - case MONGOC_OPCODE_GET_MORE: - request_from_getmore (request, &request->request_rpc); - break; - - case MONGOC_OPCODE_DELETE: - request_from_delete (request, &request->request_rpc); - break; - - case MONGOC_OPCODE_MSG: - request_from_op_msg (request, &request->request_rpc); - break; - - case MONGOC_OPCODE_REPLY: - default: - fprintf (stderr, "Unimplemented opcode %d\n", request->opcode); - abort (); - } - - return request; -} - -const bson_t * -request_get_doc (const request_t *request, int n) -{ - BSON_ASSERT (request); - return _mongoc_array_index (&request->docs, const bson_t *, n); -} - -bool -request_matches_flags (const request_t *request, mongoc_query_flags_t flags) -{ - const mongoc_rpc_t *rpc; - - BSON_ASSERT (request); - rpc = &request->request_rpc; - - if (rpc->query.flags != flags) { - test_error ("request's query flags are %s, expected %s", - query_flags_str (rpc->query.flags), - query_flags_str (flags)); - return false; - } - - return true; -} - -/* TODO: take file, line, function params from caller, wrap in macro */ -bool -request_matches_query (const request_t *request, - const char *ns, - mongoc_query_flags_t flags, - uint32_t skip, - int32_t n_return, - const char *query_json, - const char *fields_json, - bool is_command) -{ - const mongoc_rpc_t *rpc; - const bson_t *doc; - const bson_t *doc2; - char *doc_as_json; - bool n_return_equal; - bool ret = false; - - BSON_ASSERT (request); - rpc = &request->request_rpc; - - BSON_ASSERT (request->docs.len <= 2); - - if (request->docs.len) { - doc = request_get_doc (request, 0); - doc_as_json = bson_as_json (doc, NULL); - } else { - doc = NULL; - doc_as_json = NULL; - } - - if (!match_json ( - doc, is_command, __FILE__, __LINE__, BSON_FUNC, query_json)) { - /* match_json has logged the err */ - goto done; - } - - if (request->docs.len > 1) { - doc2 = request_get_doc (request, 1); - } else { - doc2 = NULL; - } - - if (!match_json (doc2, false, __FILE__, __LINE__, BSON_FUNC, fields_json)) { - /* match_json has logged the err */ - goto done; - } - - if (request->is_command && !is_command) { - test_error ("expected query, got command: %s", doc_as_json); - goto done; - } - - if (!request->is_command && is_command) { - test_error ("expected command, got query: %s", doc_as_json); - goto done; - } - - if (request->opcode != MONGOC_OPCODE_QUERY) { - test_error ("request's opcode does not match QUERY: %s", doc_as_json); - goto done; - } - - if (0 != strcmp (rpc->query.collection, ns)) { - test_error ("request's namespace is '%s', expected '%s': %s", - request->request_rpc.query.collection, - ns, - doc_as_json); - goto done; - } - - if (!request_matches_flags (request, flags)) { - test_error ("%s", doc_as_json); - goto done; - } - - if (rpc->query.skip != skip) { - test_error ("requests's skip = %d, expected %d: %s", - rpc->query.skip, - skip, - doc_as_json); - goto done; - } - - n_return_equal = (rpc->query.n_return == n_return); - - if (!n_return_equal && abs (rpc->query.n_return) == 1) { - /* quirk: commands from mongoc_client_command_simple have n_return 1, - * from mongoc_topology_scanner_t have n_return -1 - */ - n_return_equal = abs (rpc->query.n_return) == n_return; - } - - if (!n_return_equal) { - test_error ("requests's n_return = %d, expected %d: %s", - rpc->query.n_return, - n_return, - doc_as_json); - goto done; - } - - ret = true; - -done: - bson_free (doc_as_json); - return ret; -} - - -/* TODO: take file, line, function params from caller, wrap in macro */ -bool -request_matches_insert (const request_t *request, - const char *ns, - mongoc_insert_flags_t flags, - const char *doc_json) -{ - const mongoc_rpc_t *rpc; - const bson_t *doc; - - BSON_ASSERT (request); - rpc = &request->request_rpc; - - if (request->opcode != MONGOC_OPCODE_INSERT) { - test_error ("request's opcode does not match INSERT, got: %d", - request->opcode); - return false; - } - - if (strcmp (rpc->insert.collection, ns)) { - test_error ("insert's namespace is '%s', expected '%s'", - request->request_rpc.get_more.collection, - ns); - return false; - } - - if (rpc->insert.flags != flags) { - test_error ("request's insert flags are %s, expected %s", - insert_flags_str (rpc->insert.flags), - insert_flags_str (flags)); - return false; - } - - ASSERT_CMPINT ((int) request->docs.len, ==, 1); - doc = request_get_doc (request, 0); - if (!match_json (doc, false, __FILE__, __LINE__, BSON_FUNC, doc_json)) { - return false; - } - - return true; -} - - -/* TODO: take file, line, function params from caller, wrap in macro */ -bool -request_matches_bulk_insert (const request_t *request, - const char *ns, - mongoc_insert_flags_t flags, - int n) -{ - const mongoc_rpc_t *rpc; - - BSON_ASSERT (request); - rpc = &request->request_rpc; - - if (request->opcode != MONGOC_OPCODE_INSERT) { - test_error ("request's opcode does not match INSERT, got: %d", - request->opcode); - return false; - } - - if (strcmp (rpc->insert.collection, ns)) { - test_error ("insert's namespace is '%s', expected '%s'", - request->request_rpc.get_more.collection, - ns); - return false; - } - - if (rpc->insert.flags != flags) { - test_error ("request's insert flags are %s, expected %s", - insert_flags_str (rpc->insert.flags), - insert_flags_str (flags)); - return false; - } - - if ((int) request->docs.len != n) { - test_error ( - "expected %d docs inserted, got %d", n, (int) request->docs.len); - return false; - } - - return true; -} - - -/* TODO: take file, line, function params from caller, wrap in macro */ -bool -request_matches_update (const request_t *request, - const char *ns, - mongoc_update_flags_t flags, - const char *selector_json, - const char *update_json) -{ - const mongoc_rpc_t *rpc; - const bson_t *doc; - - BSON_ASSERT (request); - rpc = &request->request_rpc; - - if (request->opcode != MONGOC_OPCODE_UPDATE) { - test_error ("request's opcode does not match UPDATE, got: %d", - request->opcode); - return false; - } - - if (strcmp (rpc->update.collection, ns)) { - test_error ("update's namespace is '%s', expected '%s'", - request->request_rpc.update.collection, - ns); - return false; - } - - if (rpc->update.flags != flags) { - test_error ("request's update flags are %s, expected %s", - update_flags_str (rpc->update.flags), - update_flags_str (flags)); - return false; - } - - ASSERT_CMPINT ((int) request->docs.len, ==, 2); - doc = request_get_doc (request, 0); - if (!match_json (doc, false, __FILE__, __LINE__, BSON_FUNC, selector_json)) { - return false; - } - - doc = request_get_doc (request, 1); - if (!match_json (doc, false, __FILE__, __LINE__, BSON_FUNC, update_json)) { - return false; - } - - return true; -} - - -/* TODO: take file, line, function params from caller, wrap in macro */ -bool -request_matches_delete (const request_t *request, - const char *ns, - mongoc_remove_flags_t flags, - const char *selector_json) -{ - const mongoc_rpc_t *rpc; - const bson_t *doc; - - BSON_ASSERT (request); - rpc = &request->request_rpc; - - if (request->opcode != MONGOC_OPCODE_DELETE) { - test_error ("request's opcode does not match DELETE, got: %d", - request->opcode); - return false; - } - - if (strcmp (rpc->delete_.collection, ns)) { - test_error ("delete's namespace is '%s', expected '%s'", - request->request_rpc.delete_.collection, - ns); - return false; - } - - if (rpc->delete_.flags != flags) { - test_error ("request's delete flags are %s, expected %s", - delete_flags_str (rpc->delete_.flags), - delete_flags_str (flags)); - return false; - } - - ASSERT_CMPINT ((int) request->docs.len, ==, 1); - doc = request_get_doc (request, 0); - if (!match_json (doc, false, __FILE__, __LINE__, BSON_FUNC, selector_json)) { - return false; - } - - return true; -} - - -/* TODO: take file, line, function params from caller, wrap in macro */ -bool -request_matches_getmore (const request_t *request, - const char *ns, - int32_t n_return, - int64_t cursor_id) -{ - const mongoc_rpc_t *rpc; - - BSON_ASSERT (request); - rpc = &request->request_rpc; - - if (request->opcode != MONGOC_OPCODE_GET_MORE) { - test_error ("request's opcode does not match GET_MORE, got: %d", - request->opcode); - return false; - } - - if (strcmp (rpc->get_more.collection, ns)) { - test_error ("request's namespace is '%s', expected '%s'", - request->request_rpc.get_more.collection, - ns); - return false; - } - - if (rpc->get_more.n_return != n_return) { - test_error ("requests's n_return = %d, expected %d", - rpc->get_more.n_return, - n_return); - return false; - } - - if (rpc->get_more.cursor_id != cursor_id) { - test_error ("requests's cursor_id = %" PRId64 ", expected %" PRId64, - rpc->get_more.cursor_id, - cursor_id); - return false; - } - - return true; -} - - -/* TODO: take file, line, function params from caller, wrap in macro */ -bool -request_matches_kill_cursors (const request_t *request, int64_t cursor_id) -{ - const mongoc_rpc_t *rpc; - - BSON_ASSERT (request); - rpc = &request->request_rpc; - - if (request->opcode != MONGOC_OPCODE_KILL_CURSORS) { - test_error ("request's opcode does not match KILL_CURSORS, got: %d", - request->opcode); - return false; - } - - if (rpc->kill_cursors.n_cursors != 1) { - test_error ("request's n_cursors is %d, expected 1", - rpc->kill_cursors.n_cursors); - return false; - } - - if (rpc->kill_cursors.cursors[0] != cursor_id) { - test_error ("request's cursor_id %" PRId64 ", expected %" PRId64, - rpc->kill_cursors.cursors[0], - cursor_id); - return false; - } - - return true; -} - -/*-------------------------------------------------------------------------- - * - * request_matches_msg -- - * - * Test that a client OP_MSG matches a pattern. The OP_MSG consists - * of at least one document (the command body) and optional sequence - * of additional documents (e.g., documents in a bulk insert). The - * documents in the actual client message are compared pairwise to - * the patterns in @docs. - * - * Returns: - * True if the body and document sequence of the request match - * the given pattern. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -request_matches_msg (const request_t *request, - uint32_t flags, - const bson_t **docs, - size_t n_docs) -{ - const bson_t *doc; - const bson_t *pattern; - bool is_command_doc; - int i; - - BSON_ASSERT (request); - if (request->opcode != MONGOC_OPCODE_MSG) { - test_error ("%s", "request's opcode does not match OP_MSG"); - } - - BSON_ASSERT (request->docs.len >= 1); - - for (i = 0; i < n_docs; i++) { - pattern = docs[i]; - - /* make sure the pattern is reasonable, e.g. that we didn't pass a string - * instead of a bson_t* by mistake */ - BSON_ASSERT (bson_validate ( - pattern, BSON_VALIDATE_EMPTY_KEYS | BSON_VALIDATE_UTF8, NULL)); - - if (i > request->docs.len) { - fprintf (stderr, - "Expected at least %d documents in request, got %d\n", - i, - (int) request->docs.len); - return false; - } - - doc = request_get_doc (request, i); - /* pass is_command=true for first doc, including "find" command */ - is_command_doc = (i == 0); - assert_match_bson (doc, pattern, is_command_doc); - } - - if (n_docs < request->docs.len) { - fprintf (stderr, - "Expected %d documents in request, got %d\n", - (int) n_docs, - (int) request->docs.len); - return false; - } - - - if (flags != request->request_rpc.msg.flags) { - fprintf (stderr, - "Expected OP_MSG flags %u, got %u\n", - flags, - request->request_rpc.msg.flags); - return false; - } - - return true; -} - - -/*-------------------------------------------------------------------------- - * - * request_matches_msgv -- - * - * Variable-args version of request_matches_msg. - * - * Returns: - * True if the body and document sequence of the request match - * the given pattern. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -request_matches_msgv (const request_t *request, uint32_t flags, va_list *args) -{ - const bson_t **docs; - size_t n_docs, allocated; - bool r; - - n_docs = 0; - allocated = 1; - docs = bson_malloc (allocated * sizeof (bson_t *)); - while ((docs[n_docs] = va_arg (*args, const bson_t *))) { - n_docs++; - if (n_docs == allocated) { - allocated = bson_next_power_of_two (allocated + 1); - docs = bson_realloc (docs, allocated * sizeof (bson_t *)); - } - } - - r = request_matches_msg (request, flags, docs, n_docs); - bson_free (docs); - return r; -} - - -/*-------------------------------------------------------------------------- - * - * request_get_server_port -- - * - * Get the port of the server this request was sent to. - * - * Returns: - * A port number. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -uint16_t -request_get_server_port (request_t *request) -{ - return mock_server_get_port (request->server); -} - - -/*-------------------------------------------------------------------------- - * - * request_get_client_port -- - * - * Get the client port this request was sent from. - * - * Returns: - * A port number. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -uint16_t -request_get_client_port (request_t *request) -{ - return request->client_port; -} - - -/*-------------------------------------------------------------------------- - * - * request_destroy -- - * - * Free a request_t. - * - * Returns: - * None. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -void -request_destroy (request_t *request) -{ - size_t i; - bson_t *doc; - - for (i = 0; i < request->docs.len; i++) { - doc = _mongoc_array_index (&request->docs, bson_t *, i); - bson_destroy (doc); - } - - _mongoc_array_destroy (&request->docs); - bson_free (request->command_name); - bson_free (request->as_str); - bson_free (request->data); - bson_free (request); -} - - -static bool -is_command_ns (const char *ns) -{ - size_t len = strlen (ns); - const char *cmd = ".$cmd"; - size_t cmd_len = strlen (cmd); - - return len > cmd_len && !strncmp (ns + len - cmd_len, cmd, cmd_len); -} - - -static char * -query_flags_str (uint32_t flags) -{ - int flag = 1; - bson_string_t *str = bson_string_new (""); - bool begun = false; - - if (flags == MONGOC_QUERY_NONE) { - bson_string_append (str, "0"); - } else { - while (flag <= MONGOC_QUERY_PARTIAL) { - flag <<= 1; - - if (flags & flag) { - if (begun) { - bson_string_append (str, "|"); - } - - begun = true; - - switch (flag) { - case MONGOC_QUERY_TAILABLE_CURSOR: - bson_string_append (str, "TAILABLE"); - break; - case MONGOC_QUERY_SLAVE_OK: - bson_string_append (str, "SLAVE_OK"); - break; - case MONGOC_QUERY_OPLOG_REPLAY: - bson_string_append (str, "OPLOG_REPLAY"); - break; - case MONGOC_QUERY_NO_CURSOR_TIMEOUT: - bson_string_append (str, "NO_TIMEOUT"); - break; - case MONGOC_QUERY_AWAIT_DATA: - bson_string_append (str, "AWAIT_DATA"); - break; - case MONGOC_QUERY_EXHAUST: - bson_string_append (str, "EXHAUST"); - break; - case MONGOC_QUERY_PARTIAL: - bson_string_append (str, "PARTIAL"); - break; - case MONGOC_QUERY_NONE: - default: - BSON_ASSERT (false); - } - } - } - } - - return bson_string_free (str, false); /* detach buffer */ -} - - -static void -request_from_query (request_t *request, const mongoc_rpc_t *rpc) -{ - int32_t len; - bson_t *query; - bson_t *fields; - bson_iter_t iter; - bson_string_t *query_as_str = bson_string_new ("OP_QUERY "); - char *str; - - memcpy (&len, rpc->query.query, 4); - len = BSON_UINT32_FROM_LE (len); - query = bson_new_from_data (rpc->query.query, (size_t) len); - BSON_ASSERT (query); - _mongoc_array_append_val (&request->docs, query); - - bson_string_append_printf (query_as_str, "%s ", rpc->query.collection); - - if (is_command_ns (request->request_rpc.query.collection)) { - request->is_command = true; - - if (bson_iter_init (&iter, query) && bson_iter_next (&iter)) { - request->command_name = bson_strdup (bson_iter_key (&iter)); - } else { - fprintf (stderr, - "WARNING: no command name for %s\n", - request->request_rpc.query.collection); - } - } - - str = bson_as_json (query, NULL); - bson_string_append (query_as_str, str); - bson_free (str); - - if (rpc->query.fields) { - memcpy (&len, rpc->query.fields, 4); - len = BSON_UINT32_FROM_LE (len); - fields = bson_new_from_data (rpc->query.fields, (size_t) len); - BSON_ASSERT (fields); - _mongoc_array_append_val (&request->docs, fields); - - str = bson_as_json (fields, NULL); - bson_string_append (query_as_str, " fields="); - bson_string_append (query_as_str, str); - bson_free (str); - } - - bson_string_append (query_as_str, " flags="); - - str = query_flags_str (rpc->query.flags); - bson_string_append (query_as_str, str); - bson_free (str); - - if (rpc->query.skip) { - bson_string_append_printf ( - query_as_str, " skip=%d", (int) rpc->query.skip); - } - - if (rpc->query.n_return) { - bson_string_append_printf ( - query_as_str, " n_return=%d", (int) rpc->query.n_return); - } - - request->as_str = bson_string_free (query_as_str, false); -} - - -static char * -insert_flags_str (uint32_t flags) -{ - if (flags == MONGOC_INSERT_NONE) { - return bson_strdup ("0"); - } else { - return bson_strdup ("CONTINUE_ON_ERROR"); - } -} - - -static uint32_t -length_prefix (const uint8_t *data) -{ - uint32_t len_le; - - memcpy (&len_le, data, sizeof (len_le)); - - return BSON_UINT32_FROM_LE (len_le); -} - - -static void -request_from_insert (request_t *request, const mongoc_rpc_t *rpc) -{ - uint8_t *pos = (uint8_t *) request->request_rpc.insert.documents->iov_base; - uint8_t *end = request->data + request->data_len; - bson_string_t *insert_as_str = bson_string_new ("OP_INSERT"); - bson_t *doc; - size_t n_documents; - size_t i; - char *str; - - while (pos < end) { - uint32_t len = length_prefix (pos); - doc = bson_new_from_data (pos, len); - BSON_ASSERT (doc); - _mongoc_array_append_val (&request->docs, doc); - pos += len; - } - - n_documents = request->docs.len; - - bson_string_append_printf (insert_as_str, " %d ", (int) n_documents); - - for (i = 0; i < n_documents; i++) { - str = bson_as_json (request_get_doc (request, (int) i), NULL); - BSON_ASSERT (str); - bson_string_append (insert_as_str, str); - bson_free (str); - - if (i < n_documents - 1) { - bson_string_append (insert_as_str, ", "); - } - } - - bson_string_append (insert_as_str, " flags="); - - str = insert_flags_str (rpc->insert.flags); - bson_string_append (insert_as_str, str); - bson_free (str); - - request->as_str = bson_string_free (insert_as_str, false); -} - - -static char * -update_flags_str (uint32_t flags) -{ - int flag = 1; - bson_string_t *str = bson_string_new (""); - bool begun = false; - - if (flags == MONGOC_UPDATE_NONE) { - bson_string_append (str, "0"); - } else { - while (flag <= MONGOC_UPDATE_MULTI_UPDATE) { - flag <<= 1; - - if (flags & flag) { - if (begun) { - bson_string_append (str, "|"); - } - - begun = true; - - switch (flag) { - case MONGOC_UPDATE_UPSERT: - bson_string_append (str, "UPSERT"); - break; - case MONGOC_UPDATE_MULTI_UPDATE: - bson_string_append (str, "MULTI"); - break; - case MONGOC_UPDATE_NONE: - default: - BSON_ASSERT (false); - } - } - } - } - - return bson_string_free (str, false); /* detach buffer */ -} - - -static void -request_from_update (request_t *request, const mongoc_rpc_t *rpc) -{ - int32_t len; - bson_t *doc; - bson_string_t *update_as_str = bson_string_new ("OP_UPDATE "); - char *str; - - memcpy (&len, rpc->update.selector, 4); - len = BSON_UINT32_FROM_LE (len); - doc = bson_new_from_data (rpc->update.selector, (size_t) len); - BSON_ASSERT (doc); - _mongoc_array_append_val (&request->docs, doc); - - str = bson_as_json (doc, NULL); - bson_string_append (update_as_str, str); - bson_free (str); - - bson_string_append (update_as_str, ", "); - - memcpy (&len, rpc->update.update, 4); - len = BSON_UINT32_FROM_LE (len); - doc = bson_new_from_data (rpc->update.update, (size_t) len); - BSON_ASSERT (doc); - _mongoc_array_append_val (&request->docs, doc); - - str = bson_as_json (doc, NULL); - bson_string_append (update_as_str, str); - bson_free (str); - - bson_string_append (update_as_str, " flags="); - - str = update_flags_str (rpc->update.flags); - bson_string_append (update_as_str, str); - bson_free (str); - - request->as_str = bson_string_free (update_as_str, false); -} - - -static char * -delete_flags_str (uint32_t flags) -{ - if (flags == MONGOC_DELETE_NONE) { - return bson_strdup ("0"); - } else { - return bson_strdup ("SINGLE_REMOVE"); - } -} - - -static void -request_from_delete (request_t *request, const mongoc_rpc_t *rpc) -{ - int32_t len; - bson_t *doc; - bson_string_t *delete_as_str = bson_string_new ("OP_DELETE "); - char *str; - - memcpy (&len, rpc->delete_.selector, 4); - len = BSON_UINT32_FROM_LE (len); - doc = bson_new_from_data (rpc->delete_.selector, (size_t) len); - BSON_ASSERT (doc); - _mongoc_array_append_val (&request->docs, doc); - - str = bson_as_json (doc, NULL); - bson_string_append (delete_as_str, str); - bson_free (str); - - bson_string_append (delete_as_str, " flags="); - - str = delete_flags_str (rpc->delete_.flags); - bson_string_append (delete_as_str, str); - bson_free (str); - - request->as_str = bson_string_free (delete_as_str, false); -} - - -static void -request_from_killcursors (request_t *request, const mongoc_rpc_t *rpc) -{ - /* protocol allows multiple cursor ids but we only implement one */ - BSON_ASSERT (rpc->kill_cursors.n_cursors == 1); - request->as_str = bson_strdup_printf ("OP_KILLCURSORS %" PRId64, - rpc->kill_cursors.cursors[0]); -} - - -static void -request_from_getmore (request_t *request, const mongoc_rpc_t *rpc) -{ - request->as_str = - bson_strdup_printf ("OP_GETMORE %s %" PRId64 " n_return=%d", - rpc->get_more.collection, - rpc->get_more.cursor_id, - rpc->get_more.n_return); -} - - -static void -parse_op_msg_doc (request_t *request, - const uint8_t *data, - int32_t len, - bson_string_t *msg_as_str) -{ - int32_t data_len; - int32_t doc_len; - bson_t *doc; - const uint8_t *pos; - char *str; - - if (len == -1) { - data_len = length_prefix (data); - } else { - data_len = len; - } - - pos = data; - while (pos < data + data_len) { - if (pos > data) { - bson_string_append (msg_as_str, ", "); - } - - doc_len = length_prefix (pos); - doc = bson_new_from_data (pos, (size_t) doc_len); - BSON_ASSERT (doc); - _mongoc_array_append_val (&request->docs, doc); - - str = bson_as_json (doc, NULL); - bson_string_append (msg_as_str, str); - bson_free (str); - - pos += doc_len; - } -} - - -static void -request_from_op_msg (request_t *request, const mongoc_rpc_t *rpc) -{ - const mongoc_rpc_section_t *section; - int32_t section_no; - const char *identifier; - int32_t id_len; - const bson_t *doc; - bson_iter_t iter; - bson_string_t *msg_as_str = bson_string_new ("OP_MSG"); - - BSON_ASSERT (rpc->msg.n_sections <= 2); - for (section_no = 0; section_no < rpc->msg.n_sections; section_no++) { - bson_string_append (msg_as_str, (section_no > 0 ? ", " : " ")); - section = &rpc->msg.sections[section_no]; - switch (section->payload_type) { - case 0: - /* a single BSON document */ - parse_op_msg_doc ( - request, section->payload.bson_document, -1, msg_as_str); - break; - case 1: - /* a sequence of BSON documents */ - identifier = section->payload.sequence.identifier; - id_len = (int32_t) strlen (identifier); - bson_string_append (msg_as_str, identifier); - bson_string_append (msg_as_str, ": ["); - /* a sequence has 4-byte length prefix, a string with NIL, then docs */ - parse_op_msg_doc (request, - section->payload.sequence.bson_documents, - section->payload.sequence.size - id_len - 1 - 4, - msg_as_str); - - bson_string_append (msg_as_str, "]"); - break; - default: - fprintf ( - stderr, "Unimplemented payload type %d\n", section->payload_type); - abort (); - } - } - - request->as_str = bson_string_free (msg_as_str, false); - request->is_command = true; /* true for all OP_MSG requests */ - - if (request->docs.len) { - doc = request_get_doc (request, 0); - if (bson_iter_init (&iter, doc) && bson_iter_next (&iter)) { - request->command_name = bson_strdup (bson_iter_key (&iter)); - } - } -} diff --git a/lib/mongoc/libmongoc/tests/mock_server/request.h b/lib/mongoc/libmongoc/tests/mock_server/request.h deleted file mode 100644 index 6b652bb3d9250ea8c96c2c03549ed8f4657f1688..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/request.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2015 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 REQUEST_H -#define REQUEST_H - -#include <bson/bson.h> -#include <mongoc/mongoc-buffer-private.h> - -#include "mongoc/mongoc.h" - -#include "mongoc/mongoc-rpc-private.h" -#include "sync-queue.h" - -struct _mock_server_t; /* forward declaration */ - -typedef struct _request_t { - uint8_t *data; - size_t data_len; - mongoc_rpc_t request_rpc; - mongoc_opcode_t opcode; /* copied from rpc for convenience */ - struct _mock_server_t *server; - mongoc_stream_t *client; - uint16_t client_port; - bool is_command; - char *command_name; - char *as_str; - mongoc_array_t docs; /* array of bson_t pointers */ - sync_queue_t *replies; -} request_t; - - -request_t * -request_new (const mongoc_buffer_t *buffer, - int32_t msg_len, - struct _mock_server_t *server, - mongoc_stream_t *client, - uint16_t client_port, - sync_queue_t *replies); - -const bson_t * -request_get_doc (const request_t *request, int n); - -bool -request_matches_flags (const request_t *request, mongoc_query_flags_t flags); - -bool -request_matches_query (const request_t *request, - const char *ns, - mongoc_query_flags_t flags, - uint32_t skip, - int32_t n_return, - const char *query_json, - const char *fields_json, - bool is_command); - -bool -request_matches_insert (const request_t *request, - const char *ns, - mongoc_insert_flags_t flags, - const char *doc_json); - -bool -request_matches_bulk_insert (const request_t *request, - const char *ns, - mongoc_insert_flags_t flags, - int n); - -bool -request_matches_update (const request_t *request, - const char *ns, - mongoc_update_flags_t flags, - const char *selector_json, - const char *update_json); - -bool -request_matches_delete (const request_t *request, - const char *ns, - mongoc_remove_flags_t flags, - const char *selector_json); - -bool -request_matches_getmore (const request_t *request, - const char *ns, - int32_t n_return, - int64_t cursor_id); - -bool -request_matches_kill_cursors (const request_t *request, int64_t cursor_id); - -bool -request_matches_msg (const request_t *request, - uint32_t flags, - const bson_t **docs, - size_t n_docs); - -bool -request_matches_msgv (const request_t *request, uint32_t flags, va_list *args); - -uint16_t -request_get_server_port (request_t *request); - -uint16_t -request_get_client_port (request_t *request); - -void -request_destroy (request_t *request); - -#endif /* REQUEST_H */ diff --git a/lib/mongoc/libmongoc/tests/mock_server/sync-queue.c b/lib/mongoc/libmongoc/tests/mock_server/sync-queue.c deleted file mode 100644 index b6e4f94d05e8548c20cd9c9dcb20ec3a8cb29d84..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/sync-queue.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2015 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 "mongoc/mongoc-array-private.h" -#include "mongoc/mongoc-thread-private.h" - -#include "sync-queue.h" - - -struct _sync_queue_t { - mongoc_array_t array; - mongoc_cond_t cond; - bson_mutex_t mutex; -}; - - -sync_queue_t * -q_new () -{ - sync_queue_t *q = (sync_queue_t *) bson_malloc (sizeof (sync_queue_t)); - - _mongoc_array_init (&q->array, sizeof (void *)); - mongoc_cond_init (&q->cond); - bson_mutex_init (&q->mutex); - - return q; -} - -void -q_put (sync_queue_t *q, void *item) -{ - bson_mutex_lock (&q->mutex); - _mongoc_array_append_val (&q->array, item); - mongoc_cond_signal (&q->cond); - bson_mutex_unlock (&q->mutex); -} - - -/* call holding the lock */ -static void * -_get (sync_queue_t *q) -{ - void **data; - void *item = NULL; - size_t i; - - if (q->array.len) { - data = (void **) q->array.data; - item = data[0]; - - /* shift the queue left */ - q->array.len--; - for (i = 0; i < q->array.len; i++) { - data[i] = data[i + 1]; - } - } - - return item; -} - - -void * -q_get (sync_queue_t *q, int64_t timeout_msec) -{ - void *item = NULL; - int64_t remaining_usec = timeout_msec * 1000; - int64_t deadline = bson_get_monotonic_time () + timeout_msec * 1000; - - bson_mutex_lock (&q->mutex); - if (timeout_msec) { - while (!q->array.len && remaining_usec > 0) { - mongoc_cond_timedwait (&q->cond, &q->mutex, remaining_usec / 1000); - remaining_usec = deadline - bson_get_monotonic_time (); - } - } else { - /* no deadline */ - while (!q->array.len) { - mongoc_cond_wait (&q->cond, &q->mutex); - } - } - - item = _get (q); - bson_mutex_unlock (&q->mutex); - - return item; -} - - -void * -q_get_nowait (sync_queue_t *q) -{ - void *item; - - bson_mutex_lock (&q->mutex); - item = _get (q); - bson_mutex_unlock (&q->mutex); - - return item; -} - - -void -q_destroy (sync_queue_t *q) -{ - _mongoc_array_destroy (&q->array); - mongoc_cond_destroy (&q->cond); - bson_mutex_destroy (&q->mutex); - bson_free (q); -} diff --git a/lib/mongoc/libmongoc/tests/mock_server/sync-queue.h b/lib/mongoc/libmongoc/tests/mock_server/sync-queue.h deleted file mode 100644 index 5efc9061aab2d5bfb43b5c49f7858fde3ae56b71..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/mock_server/sync-queue.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2015 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 <stddef.h> - -#ifndef SYNC_QUEUE_H -#define SYNC_QUEUE_H - - -typedef struct _sync_queue_t sync_queue_t; - -sync_queue_t * -q_new (); - -void -q_put (sync_queue_t *q, void *item); - -void * -q_get (sync_queue_t *q, int64_t timeout_msec); - -void * -q_get_nowait (sync_queue_t *q); - -void -q_destroy (sync_queue_t *q); - -#endif /* SYNC_QUEUE_H */ diff --git a/lib/mongoc/libmongoc/tests/release_files/empty-file.txt b/lib/mongoc/libmongoc/tests/release_files/empty-file.txt deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/lib/mongoc/libmongoc/tests/release_files/example-etc-fedora-release.txt b/lib/mongoc/libmongoc/tests/release_files/example-etc-fedora-release.txt deleted file mode 100644 index 99b511c46c2ee476bc301464db3966336e343c40..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/release_files/example-etc-fedora-release.txt +++ /dev/null @@ -1 +0,0 @@ -Fedora release 8 (Werewolf) diff --git a/lib/mongoc/libmongoc/tests/release_files/example-etc-os-release-ubuntu1604.txt b/lib/mongoc/libmongoc/tests/release_files/example-etc-os-release-ubuntu1604.txt deleted file mode 100644 index 18483dd5e44c1d56bf97dcd2fda2f12fba37fcc7..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/release_files/example-etc-os-release-ubuntu1604.txt +++ /dev/null @@ -1,10 +0,0 @@ -NAME="Ubuntu" -VERSION="16.04.1 LTS (Xenial Xerus)" -ID=ubuntu -ID_LIKE=debian -PRETTY_NAME="Ubuntu 16.04.1 LTS" -VERSION_ID="16.04" -HOME_URL="http://www.ubuntu.com/" -SUPPORT_URL="http://help.ubuntu.com/" -BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" -UBUNTU_CODENAME=xenial diff --git a/lib/mongoc/libmongoc/tests/release_files/example-etc-os-release.txt b/lib/mongoc/libmongoc/tests/release_files/example-etc-os-release.txt deleted file mode 100644 index 573fed68fc864b48b483e46151cfa7eabd0869f1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/release_files/example-etc-os-release.txt +++ /dev/null @@ -1,9 +0,0 @@ -NAME=Fedora -VERSION="17 (Beefy Miracle)" -ID=fedora -VERSION_ID=17 -PRETTY_NAME="Fedora 17 (Beefy Miracle)" -ANSI_COLOR="0;34" -CPE_NAME="cpe:/o:fedoraproject:fedora:17" -HOME_URL="https://fedoraproject.org/" -BUG_REPORT_URL="https://bugzilla.redhat.com/" diff --git a/lib/mongoc/libmongoc/tests/release_files/example-etc-xyz-release-no-delimiter.txt b/lib/mongoc/libmongoc/tests/release_files/example-etc-xyz-release-no-delimiter.txt deleted file mode 100644 index ed804b0e86e5bb171bc7e0a6c1e8083bc5c24444..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/release_files/example-etc-xyz-release-no-delimiter.txt +++ /dev/null @@ -1 +0,0 @@ -This one just has name, not that R word diff --git a/lib/mongoc/libmongoc/tests/release_files/example-key-value-file.txt b/lib/mongoc/libmongoc/tests/release_files/example-key-value-file.txt deleted file mode 100644 index 674fd294e6fa09d75837435a3dc39682ed2539ad..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/release_files/example-key-value-file.txt +++ /dev/null @@ -1,101 +0,0 @@ -normalkey=normalval -key=first value -key=second value -a-key-without-a-value= -just-a-key -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -key=some value -lastkey=lastval diff --git a/lib/mongoc/libmongoc/tests/release_files/example-lsb-file-with-super-long-line.txt b/lib/mongoc/libmongoc/tests/release_files/example-lsb-file-with-super-long-line.txt deleted file mode 100644 index 50428f9347ba6619e7ed0b6f6290a70b227ae8a8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/release_files/example-lsb-file-with-super-long-line.txt +++ /dev/null @@ -1,3 +0,0 @@ -DISTRIB_RELEASE=12.04 -this-is-to-test-dealing-with-a-weird-file-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -DISTRIB_ID=Ubuntu diff --git a/lib/mongoc/libmongoc/tests/release_files/example-lsb-file.txt b/lib/mongoc/libmongoc/tests/release_files/example-lsb-file.txt deleted file mode 100644 index 6d2cea4e492e237fbdea77eab9537439107f51fc..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/release_files/example-lsb-file.txt +++ /dev/null @@ -1,6 +0,0 @@ -DISTRIB_CODENAME=precise -DISTRIB_RELEASE=12.04 -DISTRIB_DESCRIPTION="Ubuntu 12.04.4 LTS" -this-is-to-test-dealing-with-a-weird-file-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -x= -DISTRIB_ID=Ubuntu diff --git a/lib/mongoc/libmongoc/tests/ssl-test.c b/lib/mongoc/libmongoc/tests/ssl-test.c deleted file mode 100644 index f1cb2a66f3614845b712651bcad5f4938ec064ea..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/ssl-test.c +++ /dev/null @@ -1,325 +0,0 @@ -#include <bson/bson.h> -#include <errno.h> - -#include "mongoc/mongoc-config.h" -#ifdef MONGOC_ENABLE_SSL_OPENSSL -#include <openssl/ssl.h> -#include <openssl/err.h> -#endif - -#include "mongoc/mongoc-stream-tls.h" - -#include "ssl-test.h" -#include "TestSuite.h" - -#define TIMEOUT 10 * 1000 - -#define NUM_IOVECS 2000 - -#define LOCALHOST "127.0.0.1" - -/** this function is meant to be run from ssl_test as a child thread - * - * It: - * 1. spins up - * 2. binds and listens to a random port - * 3. notifies the client of its port through a condvar - * 4. accepts a request - * 5. reads a 32 bit length - * 6. reads a string of that length - * 7. echoes it back to the client - * 8. shuts down - */ -static void * -ssl_test_server (void *ptr) -{ - ssl_test_data_t *data = (ssl_test_data_t *) ptr; - - mongoc_stream_t *sock_stream; - mongoc_stream_t *ssl_stream; - mongoc_socket_t *listen_sock; - mongoc_socket_t *conn_sock; - mongoc_socklen_t sock_len; - char buf[4 * NUM_IOVECS]; - ssize_t r; - bson_error_t error; - mongoc_iovec_t iov; - struct sockaddr_in server_addr = {0}; - int len; - - iov.iov_base = buf; - iov.iov_len = sizeof buf; - - listen_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (listen_sock); - - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - server_addr.sin_port = htons (0); - - r = mongoc_socket_bind ( - listen_sock, (struct sockaddr *) &server_addr, sizeof server_addr); - BSON_ASSERT (r == 0); - - sock_len = sizeof (server_addr); - r = mongoc_socket_getsockname ( - listen_sock, (struct sockaddr *) &server_addr, &sock_len); - BSON_ASSERT (r == 0); - - r = mongoc_socket_listen (listen_sock, 10); - BSON_ASSERT (r == 0); - - bson_mutex_lock (&data->cond_mutex); - data->server_port = ntohs (server_addr.sin_port); - mongoc_cond_signal (&data->cond); - bson_mutex_unlock (&data->cond_mutex); - - conn_sock = mongoc_socket_accept (listen_sock, -1); - BSON_ASSERT (conn_sock); - - sock_stream = mongoc_stream_socket_new (conn_sock); - BSON_ASSERT (sock_stream); - ssl_stream = - mongoc_stream_tls_new_with_hostname (sock_stream, NULL, data->server, 0); - if (!ssl_stream) { -#ifdef MONGOC_ENABLE_SSL_OPENSSL - unsigned long err = ERR_get_error (); -#else - unsigned long err = 42; -#endif - BSON_ASSERT (err); - - data->server_result->ssl_err = err; - data->server_result->result = SSL_TEST_SSL_INIT; -#ifdef MONGOC_ENABLE_SSL_OPENSSL - MONGOC_ERROR ("ERRORED (line: %d): %s\n", - __LINE__, - ERR_error_string (ERR_get_error (), NULL)); -#endif - mongoc_stream_destroy (sock_stream); - mongoc_socket_destroy (listen_sock); - - return NULL; - } - BSON_ASSERT (ssl_stream); - - r = mongoc_stream_tls_handshake_block ( - ssl_stream, data->host, TIMEOUT, &error); - - if (!r) { - unsigned long err = 43; - - MONGOC_ERROR ("ERRORED (line: %d): %s\n", __LINE__, error.message); -#ifdef MONGOC_ENABLE_SSL_OPENSSL - MONGOC_ERROR ("msg: %s\n", ERR_error_string (ERR_get_error (), NULL)); -#endif - data->server_result->ssl_err = err; - data->server_result->result = SSL_TEST_SSL_HANDSHAKE; - - mongoc_socket_destroy (listen_sock); - mongoc_stream_destroy (ssl_stream); - - return NULL; - } - - r = mongoc_stream_readv (ssl_stream, &iov, 1, 4, TIMEOUT); - if (r < 0) { - data->server_result->err = errno; - data->server_result->result = SSL_TEST_TIMEOUT; - MONGOC_ERROR ( - "ERRORED (line: %d): %s\n", __LINE__, "mongoc_stream_readv failed."); - - mongoc_stream_destroy (ssl_stream); - mongoc_socket_destroy (listen_sock); - - return NULL; - } - - BSON_ASSERT (r == 4); - memcpy (&len, iov.iov_base, r); - - r = mongoc_stream_readv (ssl_stream, &iov, 1, len, TIMEOUT); - BSON_ASSERT (r == len); - - iov.iov_len = r; - mongoc_stream_writev (ssl_stream, &iov, 1, TIMEOUT); - - mongoc_stream_destroy (ssl_stream); - - mongoc_socket_destroy (listen_sock); - - data->server_result->result = SSL_TEST_SUCCESS; - - return NULL; -} - -/** this function is meant to be run from ssl_test as a child thread - * - * It: - * 1. spins up - * 2. waits on a condvar until the server is up - * 3. connects to the server's port - * 4. writes a 4 bytes length - * 5. writes a string of length size - * 6. reads a response back of the given length - * 7. confirms that its the same as what was written - * 8. shuts down - */ -static void * -ssl_test_client (void *ptr) -{ - ssl_test_data_t *data = (ssl_test_data_t *) ptr; - mongoc_stream_t *sock_stream; - mongoc_stream_t *ssl_stream; - mongoc_socket_t *conn_sock; - int i; - char buf[1024]; - ssize_t r; - mongoc_iovec_t riov; - mongoc_iovec_t wiov; - mongoc_iovec_t wiov_many[NUM_IOVECS]; - struct sockaddr_in server_addr = {0}; - int len; - bson_error_t error; - - riov.iov_base = buf; - riov.iov_len = sizeof buf; - - conn_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (conn_sock); - - bson_mutex_lock (&data->cond_mutex); - while (!data->server_port) { - mongoc_cond_wait (&data->cond, &data->cond_mutex); - } - bson_mutex_unlock (&data->cond_mutex); - - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons (data->server_port); - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - - r = mongoc_socket_connect ( - conn_sock, (struct sockaddr *) &server_addr, sizeof (server_addr), -1); - if (r != 0) { - fprintf (stderr, - "mongoc_socket_connect returned %zd: \"%s\"", - r, - strerror (errno)); - abort (); - } - - sock_stream = mongoc_stream_socket_new (conn_sock); - BSON_ASSERT (sock_stream); - ssl_stream = mongoc_stream_tls_new_with_hostname ( - sock_stream, data->host, data->client, 1); - if (!ssl_stream) { -#ifdef MONGOC_ENABLE_SSL_OPENSSL - unsigned long err = ERR_get_error (); -#else - unsigned long err = 44; -#endif - BSON_ASSERT (err); - - data->client_result->ssl_err = err; - data->client_result->result = SSL_TEST_SSL_INIT; - MONGOC_ERROR ("ERRORED (line: %d): %s\n", - __LINE__, - "mongoc_stream_tls_new_with_hostname failed."); - - mongoc_stream_destroy (sock_stream); - - return NULL; - } - BSON_ASSERT (ssl_stream); - - r = mongoc_stream_tls_handshake_block ( - ssl_stream, data->host, TIMEOUT, &error); - - if (!r) { - unsigned long err = 45; - - data->client_result->ssl_err = err; - data->client_result->result = SSL_TEST_SSL_HANDSHAKE; - MONGOC_ERROR ("ERRORED (line: %d): %s\n", __LINE__, error.message); - - mongoc_stream_destroy (ssl_stream); - return NULL; - } - - len = 4 * NUM_IOVECS; - - wiov.iov_base = (void *) &len; - wiov.iov_len = 4; - r = mongoc_stream_writev (ssl_stream, &wiov, 1, TIMEOUT); - - BSON_ASSERT (r == wiov.iov_len); - - for (i = 0; i < NUM_IOVECS; i++) { - wiov_many[i].iov_base = (void *) "foo"; - wiov_many[i].iov_len = 4; - } - - r = mongoc_stream_writev (ssl_stream, wiov_many, NUM_IOVECS, TIMEOUT); - BSON_ASSERT (r == wiov_many[0].iov_len * NUM_IOVECS); - - riov.iov_len = 1; - - r = mongoc_stream_readv (ssl_stream, &riov, 1, 1, TIMEOUT); - BSON_ASSERT (r == 1); - BSON_ASSERT (memcmp (riov.iov_base, "f", 1) == 0); - - riov.iov_len = 3; - - r = mongoc_stream_readv (ssl_stream, &riov, 1, 3, TIMEOUT); - BSON_ASSERT (r == 3); - BSON_ASSERT (memcmp (riov.iov_base, "oo", 3) == 0); - - mongoc_stream_destroy (ssl_stream); - - data->client_result->result = SSL_TEST_SUCCESS; - - return NULL; -} - - -/** This is the testing function for the ssl-test lib - * - * The basic idea is that you spin up a client and server, which will - * communicate over a mongoc-stream-tls, with varying mongoc_ssl_opt's. The - * client and server speak a simple echo protocol, so all we're really testing - * here is that any given configuration succeeds or fails as it should - */ -void -ssl_test (mongoc_ssl_opt_t *client, - mongoc_ssl_opt_t *server, - const char *host, - ssl_test_result_t *client_result, - ssl_test_result_t *server_result) -{ - ssl_test_data_t data = {0}; - bson_thread_t threads[2]; - int i, r; - - data.server = server; - data.client = client; - data.client_result = client_result; - data.server_result = server_result; - data.host = host; - - bson_mutex_init (&data.cond_mutex); - mongoc_cond_init (&data.cond); - - r = bson_thread_create (threads, &ssl_test_server, &data); - BSON_ASSERT (r == 0); - - r = bson_thread_create (threads + 1, &ssl_test_client, &data); - BSON_ASSERT (r == 0); - - for (i = 0; i < 2; i++) { - r = bson_thread_join (threads[i]); - BSON_ASSERT (r == 0); - } - - bson_mutex_destroy (&data.cond_mutex); - mongoc_cond_destroy (&data.cond); -} diff --git a/lib/mongoc/libmongoc/tests/ssl-test.h b/lib/mongoc/libmongoc/tests/ssl-test.h deleted file mode 100644 index 382a0a234d618a525bb17d60f0ad02a723c6fac1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/ssl-test.h +++ /dev/null @@ -1,43 +0,0 @@ -#include <mongoc/mongoc.h> - -#include <mongoc/mongoc-thread-private.h> - -typedef enum ssl_test_behavior { - SSL_TEST_BEHAVIOR_NORMAL, - SSL_TEST_BEHAVIOR_HANGUP_AFTER_HANDSHAKE, - SSL_TEST_BEHAVIOR_STALL_BEFORE_HANDSHAKE, -} ssl_test_behavior_t; - -typedef enum ssl_test_state { - SSL_TEST_CRASH, - SSL_TEST_SUCCESS, - SSL_TEST_SSL_INIT, - SSL_TEST_SSL_HANDSHAKE, - SSL_TEST_TIMEOUT, -} ssl_test_state_t; - -typedef struct ssl_test_result { - ssl_test_state_t result; - int err; - unsigned long ssl_err; -} ssl_test_result_t; - -typedef struct ssl_test_data { - mongoc_ssl_opt_t *client; - mongoc_ssl_opt_t *server; - ssl_test_behavior_t behavior; - int64_t handshake_stall_ms; - const char *host; - unsigned short server_port; - mongoc_cond_t cond; - bson_mutex_t cond_mutex; - ssl_test_result_t *client_result; - ssl_test_result_t *server_result; -} ssl_test_data_t; - -void -ssl_test (mongoc_ssl_opt_t *client, - mongoc_ssl_opt_t *server, - const char *host, - ssl_test_result_t *client_result, - ssl_test_result_t *server_result); diff --git a/lib/mongoc/libmongoc/tests/test-conveniences.c b/lib/mongoc/libmongoc/tests/test-conveniences.c deleted file mode 100644 index bec183124de6d7dc510bf38cc1ce4b3c743d3d19..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-conveniences.c +++ /dev/null @@ -1,1785 +0,0 @@ -/* - * Copyright 2015 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 <bson/bson.h> - -#include "bson/bson-types.h" - -#include "mongoc/mongoc-array-private.h" -/* For strcasecmp on Windows */ -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-concern.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-client-private.h" - -#include "test-conveniences.h" -#include "TestSuite.h" - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - - -static bool gConveniencesInitialized = false; -static mongoc_array_t gTmpBsonArray; - -static char *gHugeString; -static size_t gHugeStringLength; -static char *gFourMBString; - -static void -test_conveniences_cleanup (); - - -static void -test_conveniences_init () -{ - if (!gConveniencesInitialized) { - _mongoc_array_init (&gTmpBsonArray, sizeof (bson_t *)); - atexit (test_conveniences_cleanup); - gConveniencesInitialized = true; - } -} - - -static void -test_conveniences_cleanup () -{ - int i; - bson_t *doc; - - if (gConveniencesInitialized) { - for (i = 0; i < gTmpBsonArray.len; i++) { - doc = _mongoc_array_index (&gTmpBsonArray, bson_t *, i); - bson_destroy (doc); - } - - _mongoc_array_destroy (&gTmpBsonArray); - } - - bson_free (gHugeString); -} - - -void -value_init_from_doc (bson_value_t *value, const bson_t *doc) -{ - BSON_ASSERT (doc); - - value->value_type = BSON_TYPE_DOCUMENT; - value->value.v_doc.data = bson_malloc ((size_t) doc->len); - memcpy (value->value.v_doc.data, bson_get_data (doc), (size_t) doc->len); - value->value.v_doc.data_len = doc->len; -} - - -MONGOC_PRINTF_FORMAT (1, 2) -bson_t * -tmp_bson (const char *json, ...) -{ - va_list args; - bson_error_t error; - char *formatted; - char *double_quoted; - bson_t *doc; - - test_conveniences_init (); - - if (json) { - va_start (args, json); - formatted = bson_strdupv_printf (json, args); - va_end (args); - - double_quoted = single_quotes_to_double (formatted); - doc = bson_new_from_json ((const uint8_t *) double_quoted, -1, &error); - - if (!doc) { - fprintf (stderr, "%s\n", error.message); - abort (); - } - - bson_free (formatted); - bson_free (double_quoted); - - } else { - doc = bson_new (); - } - - _mongoc_array_append_val (&gTmpBsonArray, doc); - - return doc; -} - - -/*-------------------------------------------------------------------------- - * - * bson_iter_bson -- - * - * Statically init a bson_t from an iter at an array or document. - * - *-------------------------------------------------------------------------- - */ -void -bson_iter_bson (const bson_iter_t *iter, bson_t *bson) -{ - uint32_t len; - const uint8_t *data; - - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (iter) || - BSON_ITER_HOLDS_ARRAY (iter)); - - if (BSON_ITER_HOLDS_DOCUMENT (iter)) { - bson_iter_document (iter, &len, &data); - } else { - bson_iter_array (iter, &len, &data); - } - - BSON_ASSERT (bson_init_static (bson, data, len)); -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_utf8 -- - * - * Return a string by key, or BSON_ASSERT and abort. - * - *-------------------------------------------------------------------------- - */ -const char * -bson_lookup_utf8 (const bson_t *b, const char *key) -{ - bson_iter_t iter; - bson_iter_t descendent; - - bson_iter_init (&iter, b); - BSON_ASSERT (bson_iter_find_descendant (&iter, key, &descendent)); - BSON_ASSERT (BSON_ITER_HOLDS_UTF8 (&descendent)); - - return bson_iter_utf8 (&descendent, NULL); -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_value -- - * - * Return a bson_value_t or BSON_ASSERT and abort. - * - *-------------------------------------------------------------------------- - */ -void -bson_lookup_value (const bson_t *b, const char *key, bson_value_t *value) -{ - bson_iter_t iter; - bson_iter_t descendent; - - BSON_ASSERT (bson_iter_init (&iter, b)); - BSON_ASSERT (bson_iter_find_descendant (&iter, key, &descendent)); - bson_value_copy (bson_iter_value (&descendent), value); -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_doc -- - * - * Find a subdocument by key and return it by static-initializing - * the passed-in bson_t "doc". There is no need to bson_destroy - * "doc". Asserts and aborts if the key is absent or not a subdoc. - * - *-------------------------------------------------------------------------- - */ -void -bson_lookup_doc (const bson_t *b, const char *key, bson_t *doc) -{ - bson_iter_t iter; - bson_iter_t descendent; - - bson_iter_init (&iter, b); - BSON_ASSERT (bson_iter_find_descendant (&iter, key, &descendent)); - bson_iter_bson (&descendent, doc); -} - -void -bson_lookup_doc_null_ok (const bson_t *b, const char *key, bson_t *doc) -{ - bson_iter_t iter; - bson_iter_t descendent; - - BSON_ASSERT (bson_iter_init (&iter, b)); - BSON_ASSERT (bson_iter_find_descendant (&iter, key, &descendent)); - if (!BSON_ITER_HOLDS_NULL (&descendent)) { - bson_iter_bson (&descendent, doc); - } else { - bson_init (doc); - } -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_bool -- - * - * Return a bool by key, or BSON_ASSERT and abort. - * - *-------------------------------------------------------------------------- - */ -bool -bson_lookup_bool (const bson_t *b, const char *key) -{ - bson_iter_t iter; - bson_iter_t descendent; - - bson_iter_init (&iter, b); - BSON_ASSERT (bson_iter_find_descendant (&iter, key, &descendent)); - BSON_ASSERT (BSON_ITER_HOLDS_BOOL (&descendent)); - - return bson_iter_bool (&descendent); -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_int32 -- - * - * Return an int32_t by key, or BSON_ASSERT and abort. - * - *-------------------------------------------------------------------------- - */ -int32_t -bson_lookup_int32 (const bson_t *b, const char *key) -{ - bson_iter_t iter; - bson_iter_t descendent; - - bson_iter_init (&iter, b); - BSON_ASSERT (bson_iter_find_descendant (&iter, key, &descendent)); - BSON_ASSERT (BSON_ITER_HOLDS_INT32 (&descendent)); - - return bson_iter_int32 (&descendent); -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_int64 -- - * - * Return an int64_t by key, or BSON_ASSERT and abort. - * - *-------------------------------------------------------------------------- - */ -int64_t -bson_lookup_int64 (const bson_t *b, const char *key) -{ - bson_iter_t iter; - bson_iter_t descendent; - - bson_iter_init (&iter, b); - BSON_ASSERT (bson_iter_find_descendant (&iter, key, &descendent)); - BSON_ASSERT (BSON_ITER_HOLDS_INT64 (&descendent)); - - return bson_iter_int64 (&descendent); -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_read_concern -- - * - * Find a subdocument like {level: "majority"} and interpret it as a - * mongoc_read_concern_t, or BSON_ASSERT and abort. - * - *-------------------------------------------------------------------------- - */ -mongoc_read_concern_t * -bson_lookup_read_concern (const bson_t *b, const char *key) -{ - bson_t doc; - mongoc_read_concern_t *rc = mongoc_read_concern_new (); - - bson_lookup_doc (b, key, &doc); - mongoc_read_concern_set_level (rc, bson_lookup_utf8 (&doc, "level")); - - return rc; -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_write_concern -- - * - * Find a subdocument like {w: <int32>} and interpret it as a - * mongoc_write_concern_t, or BSON_ASSERT and abort. - * - *-------------------------------------------------------------------------- - */ -mongoc_write_concern_t * -bson_lookup_write_concern (const bson_t *b, const char *key) -{ - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t doc; - bson_iter_t iter; - bson_iter_t w; - - bson_lookup_doc (b, key, &doc); - BSON_ASSERT (bson_iter_init (&iter, &doc)); - - /* current command monitoring tests always have "w" but may also have - * "wtimeout" and "j" fields. */ - ASSERT_CMPUINT32 (bson_count_keys (&doc), >=, (uint32_t) 1); - BSON_ASSERT (bson_iter_find_descendant (&iter, "w", &w)); - - if (BSON_ITER_HOLDS_NUMBER (&w)) { - mongoc_write_concern_set_w (wc, (int32_t) bson_iter_as_int64 (&w)); - } else if (!strcmp (bson_iter_utf8 (&w, NULL), "majority")) { - mongoc_write_concern_set_wmajority (wc, 0); - } else { - mongoc_write_concern_set_wtag (wc, bson_iter_utf8 (&w, NULL)); - } - - if (bson_has_field (&doc, "wtimeout")) { - mongoc_write_concern_set_wtimeout_int64 ( - wc, bson_lookup_int32 (&doc, "wtimeout")); - } - - if (bson_has_field (&doc, "j")) { - mongoc_write_concern_set_journal (wc, bson_lookup_bool (&doc, "j")); - } - - return wc; -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_read_prefs -- - * - * Find a subdocument like {mode: "mode"} and interpret it as a - * mongoc_read_prefs_t, or BSON_ASSERT and abort. - * - *-------------------------------------------------------------------------- - */ -mongoc_read_prefs_t * -bson_lookup_read_prefs (const bson_t *b, const char *key) -{ - bson_t doc; - const char *str; - mongoc_read_mode_t mode; - - bson_lookup_doc (b, key, &doc); - str = bson_lookup_utf8 (&doc, "mode"); - - if (0 == strcasecmp ("primary", str)) { - mode = MONGOC_READ_PRIMARY; - } else if (0 == strcasecmp ("primarypreferred", str)) { - mode = MONGOC_READ_PRIMARY_PREFERRED; - } else if (0 == strcasecmp ("secondary", str)) { - mode = MONGOC_READ_SECONDARY; - } else if (0 == strcasecmp ("secondarypreferred", str)) { - mode = MONGOC_READ_SECONDARY_PREFERRED; - } else if (0 == strcasecmp ("nearest", str)) { - mode = MONGOC_READ_NEAREST; - } else { - test_error ("Bad readPreference: {\"mode\": \"%s\"}.", str); - abort (); - } - - return mongoc_read_prefs_new (mode); -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_database_opts -- - * - * Interpret a subdocument as database options. - * - *-------------------------------------------------------------------------- - */ -void -bson_lookup_database_opts (const bson_t *b, - const char *key, - mongoc_database_t *database) -{ - bson_t doc; - mongoc_read_concern_t *rc; - mongoc_write_concern_t *wc; - mongoc_read_prefs_t *prefs; - - bson_lookup_doc (b, key, &doc); - - if (bson_has_field (&doc, "readConcern")) { - rc = bson_lookup_read_concern (&doc, "readConcern"); - mongoc_database_set_read_concern (database, rc); - mongoc_read_concern_destroy (rc); - } - - if (bson_has_field (&doc, "writeConcern")) { - wc = bson_lookup_write_concern (&doc, "writeConcern"); - mongoc_database_set_write_concern (database, wc); - mongoc_write_concern_destroy (wc); - } - - if (bson_has_field (&doc, "readPreference")) { - prefs = bson_lookup_read_prefs (&doc, "readPreference"); - mongoc_database_set_read_prefs (database, prefs); - mongoc_read_prefs_destroy (prefs); - } -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_collection_opts -- - * - * Interpret a subdocument as collection options. - * - *-------------------------------------------------------------------------- - */ -void -bson_lookup_collection_opts (const bson_t *b, - const char *key, - mongoc_collection_t *collection) -{ - bson_t doc; - mongoc_read_concern_t *rc; - mongoc_write_concern_t *wc; - mongoc_read_prefs_t *prefs; - - bson_lookup_doc (b, key, &doc); - - if (bson_has_field (&doc, "readConcern")) { - rc = bson_lookup_read_concern (&doc, "readConcern"); - mongoc_collection_set_read_concern (collection, rc); - mongoc_read_concern_destroy (rc); - } - - if (bson_has_field (&doc, "writeConcern")) { - wc = bson_lookup_write_concern (&doc, "writeConcern"); - mongoc_collection_set_write_concern (collection, wc); - mongoc_write_concern_destroy (wc); - } - - if (bson_has_field (&doc, "readPreference")) { - prefs = bson_lookup_read_prefs (&doc, "readPreference"); - mongoc_collection_set_read_prefs (collection, prefs); - mongoc_read_prefs_destroy (prefs); - } -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_txn_opts -- - * - * Interpret a subdocument as transaction options. - * - *-------------------------------------------------------------------------- - */ -mongoc_transaction_opt_t * -bson_lookup_txn_opts (const bson_t *b, const char *key) -{ - bson_t doc; - mongoc_transaction_opt_t *opts; - mongoc_read_concern_t *rc; - mongoc_write_concern_t *wc; - mongoc_read_prefs_t *prefs; - int64_t max_commit_time_ms; - - bson_lookup_doc (b, key, &doc); - opts = mongoc_transaction_opts_new (); - - if (bson_has_field (&doc, "readConcern")) { - rc = bson_lookup_read_concern (&doc, "readConcern"); - mongoc_transaction_opts_set_read_concern (opts, rc); - mongoc_read_concern_destroy (rc); - } - - if (bson_has_field (&doc, "writeConcern")) { - wc = bson_lookup_write_concern (&doc, "writeConcern"); - mongoc_transaction_opts_set_write_concern (opts, wc); - mongoc_write_concern_destroy (wc); - } - - if (bson_has_field (&doc, "readPreference")) { - prefs = bson_lookup_read_prefs (&doc, "readPreference"); - mongoc_transaction_opts_set_read_prefs (opts, prefs); - mongoc_read_prefs_destroy (prefs); - } - - if (bson_has_field (&doc, "maxCommitTimeMS")) { - max_commit_time_ms = bson_lookup_int32 (&doc, "maxCommitTimeMS"); - mongoc_transaction_opts_set_max_commit_time_ms (opts, max_commit_time_ms); - } - - return opts; -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_session_opts -- - * - * Interpret a subdocument as client session options. - * - *-------------------------------------------------------------------------- - */ -mongoc_session_opt_t * -bson_lookup_session_opts (const bson_t *b, const char *key) -{ - bson_t doc; - mongoc_session_opt_t *opts; - - bson_lookup_doc (b, key, &doc); - opts = mongoc_session_opts_new (); - - mongoc_session_opts_set_causal_consistency ( - opts, _mongoc_lookup_bool (&doc, "causalConsistency", true)); - - if (bson_has_field (&doc, "defaultTransactionOptions")) { - mongoc_transaction_opt_t *txn_opts; - - txn_opts = bson_lookup_txn_opts (&doc, "defaultTransactionOptions"); - mongoc_session_opts_set_default_transaction_opts (opts, txn_opts); - mongoc_transaction_opts_destroy (txn_opts); - } - - return opts; -} - - -/*-------------------------------------------------------------------------- - * - * bson_lookup_session -- - * - * Interpret a subdocument as a client session with options. - * - *-------------------------------------------------------------------------- - */ -mongoc_client_session_t * -bson_lookup_session (const bson_t *b, const char *key, mongoc_client_t *client) -{ - mongoc_session_opt_t *opts; - mongoc_client_session_t *session; - bson_error_t error; - - opts = bson_lookup_session_opts (b, key); - session = mongoc_client_start_session (client, opts, &error); - ASSERT_OR_PRINT (session, error); - mongoc_session_opts_destroy (opts); - return session; -} - - -static bool -get_exists_operator (const bson_value_t *value, bool *exists); - -static bool -get_empty_operator (const bson_value_t *value, bool *exists); - -static bool -get_type_operator (const bson_value_t *value, bson_type_t *out); - -static bool -is_empty_doc_or_array (const bson_value_t *value); - -static bool -find (bson_iter_t *iter, - const bson_t *doc, - const char *key, - bool is_command, - bool is_first, - bool retain_dots_in_keys); - - -/*-------------------------------------------------------------------------- - * - * single_quotes_to_double -- - * - * Copy str with single-quotes replaced by double. - * - * Returns: - * A string you must bson_free. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -char * -single_quotes_to_double (const char *str) -{ - char *result = bson_strdup (str); - char *p; - - for (p = result; *p; p++) { - if (*p == '\'') { - *p = '"'; - } - } - - return result; -} - - -/*-------------------------------------------------------------------------- - * - * match_json -- - * - * Call match_bson on "doc" and "json_pattern". - * For convenience, single-quotes are synonymous with double-quotes. - * - * A NULL doc or NULL json_pattern means "{}". - * - * Returns: - * True or false. - * - * Side effects: - * Logs if no match. Aborts if json is malformed. - * - *-------------------------------------------------------------------------- - */ - -MONGOC_PRINTF_FORMAT (6, 7) -bool -match_json (const bson_t *doc, - bool is_command, - const char *filename, - int lineno, - const char *funcname, - const char *json_pattern, - ...) -{ - va_list args; - char *json_pattern_formatted; - char *double_quoted; - bson_error_t error; - bson_t *pattern; - match_ctx_t ctx = {{0}}; - bool matches; - - va_start (args, json_pattern); - json_pattern_formatted = - bson_strdupv_printf (json_pattern ? json_pattern : "{}", args); - va_end (args); - - double_quoted = single_quotes_to_double (json_pattern_formatted); - pattern = bson_new_from_json ((const uint8_t *) double_quoted, -1, &error); - - if (!pattern) { - fprintf (stderr, "couldn't parse JSON: %s\n", error.message); - abort (); - } - - ctx.is_command = is_command; - matches = match_bson_with_ctx (doc, pattern, &ctx); - - if (!matches) { - char *as_string = - doc ? bson_as_canonical_extended_json (doc, NULL) : NULL; - fprintf (stderr, - "ASSERT_MATCH failed with document:\n\n" - "%s\n" - "pattern:\n%s\n" - "%s\n" - "%s:%d %s()\n", - as_string ? as_string : "{}", - double_quoted, - ctx.errmsg, - filename, - lineno, - funcname); - bson_free (as_string); - } - - bson_destroy (pattern); - bson_free (json_pattern_formatted); - bson_free (double_quoted); - - return matches; -} - - -/*-------------------------------------------------------------------------- - * - * match_bson -- - * - * Does "doc" match "pattern"? - * - * See match_bson_with_ctx for details. - * - * Returns: - * True or false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -match_bson (const bson_t *doc, const bson_t *pattern, bool is_command) -{ - match_ctx_t ctx = {{0}}; - - ctx.strict_numeric_types = true; - ctx.is_command = is_command; - - return match_bson_with_ctx (doc, pattern, &ctx); -} - -/* - *-------------------------------------------------------------------------- - * - * assert_match_bson -- - * - * Test helper that wraps match_bson. Fails the test if there - * is no found match. - * - * Returns: - * Nothing. - * - * Side effects: - * abort()s if there is no match. - * - *-------------------------------------------------------------------------- - */ -void -assert_match_bson (const bson_t *doc, const bson_t *pattern, bool is_command) -{ - match_ctx_t ctx = {{0}}; - - ctx.strict_numeric_types = true; - ctx.is_command = is_command; - - if (!match_bson_with_ctx (doc, pattern, &ctx)) { - test_error ("Expected: %s\n, Got: %s\n, %s\n", - bson_as_canonical_extended_json (pattern, NULL), - bson_as_canonical_extended_json (doc, NULL), - ctx.errmsg); - } -} - - -MONGOC_PRINTF_FORMAT (2, 3) -void -match_err (match_ctx_t *ctx, const char *fmt, ...) -{ - va_list args; - char *formatted; - - BSON_ASSERT (ctx); - - va_start (args, fmt); - formatted = bson_strdupv_printf (fmt, args); - va_end (args); - - bson_snprintf ( - ctx->errmsg, sizeof ctx->errmsg, "%s: %s", ctx->path, formatted); - - bson_free (formatted); -} - - -/* When matching two docs, and preparing to recurse to match two subdocs with - * the given key, derive context for matching them from the current context. */ -static void -derive (match_ctx_t *ctx, match_ctx_t *derived, const char *key) -{ - BSON_ASSERT (ctx); - BSON_ASSERT (derived); - BSON_ASSERT (key); - - derived->strict_numeric_types = ctx->strict_numeric_types; - - if (strlen (ctx->path) > 0) { - bson_snprintf ( - derived->path, sizeof derived->path, "%s.%s", ctx->path, key); - } else { - bson_snprintf (derived->path, sizeof derived->path, "%s", key); - } - derived->retain_dots_in_keys = ctx->retain_dots_in_keys; - derived->allow_placeholders = ctx->allow_placeholders; - derived->visitor_ctx = ctx->visitor_ctx; - derived->visitor_fn = ctx->visitor_fn; - derived->is_command = false; - derived->errmsg[0] = 0; -} - - -/*-------------------------------------------------------------------------- - * - * match_bson_with_ctx -- - * - * Does "doc" match "pattern"? - * - * mongoc_matcher_t prohibits $-prefixed keys, which is something - * we need to test in e.g. test_mongoc_client_read_prefs, so this - * does *not* use mongoc_matcher_t. Instead, "doc" matches "pattern" - * if its key-value pairs are a simple superset of pattern's. Order - * matters. - * - * The only special pattern syntaxes are: - * "field": {"$exists": true/false} - * "field": {"$empty": true/false} - * "field": {"$$type": "type string"} - * - * The first key matches case-insensitively if ctx->is_command. - * - * An optional match visitor (match_visitor_fn and match_visitor_ctx) - * can be set in ctx to provide custom matching behavior. - * - * A NULL doc or NULL pattern means "{}". - * - * Returns: - * True or false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -bool -match_bson_with_ctx (const bson_t *doc, const bson_t *pattern, match_ctx_t *ctx) -{ - bson_iter_t pattern_iter; - const char *key; - const bson_value_t *value; - bool is_first = true; - bool is_exists_operator; - bool is_empty_operator; - bool is_type_operator; - bool exists; - bool empty; - bson_type_t bson_type; - bool found; - bson_iter_t doc_iter; - bson_value_t doc_value; - match_ctx_t derived; - - if (bson_empty0 (pattern)) { - /* matches anything */ - return true; - } - - BSON_ASSERT (bson_iter_init (&pattern_iter, pattern)); - - while (bson_iter_next (&pattern_iter)) { - key = bson_iter_key (&pattern_iter); - value = bson_iter_value (&pattern_iter); - - found = find (&doc_iter, - doc, - key, - ctx->is_command, - is_first, - ctx->retain_dots_in_keys); - if (found) { - bson_value_copy (bson_iter_value (&doc_iter), &doc_value); - } - - /* is value {"$exists": true} or {"$exists": false} ? */ - is_exists_operator = get_exists_operator (value, &exists); - - /* is value {"$empty": true} or {"$empty": false} ? */ - is_empty_operator = get_empty_operator (value, &empty); - - /* is value {"$$type": "string" } ? */ - is_type_operator = get_type_operator (value, &bson_type); - - derive (ctx, &derived, key); - - if (ctx->visitor_fn) { - match_action_t action = - ctx->visitor_fn (ctx, &pattern_iter, found ? &doc_iter : NULL); - if (action == MATCH_ACTION_ABORT) { - goto fail; - } else if (action == MATCH_ACTION_SKIP) { - goto next; - } - } - - if (value->value_type == BSON_TYPE_NULL && found) { - /* pattern has "key": null, and "key" is in doc */ - if (doc_value.value_type != BSON_TYPE_NULL) { - match_err (&derived, "%s should be null or absent", key); - goto fail; - } - } else if (is_exists_operator) { - if (exists != found) { - match_err (&derived, "%s found", found ? "" : "not"); - goto fail; - } - } else if (!found) { - match_err (&derived, "not found"); - goto fail; - } else if (is_empty_operator) { - if (empty != is_empty_doc_or_array (&doc_value)) { - match_err (&derived, "%s found", empty ? "" : " not"); - goto fail; - } - } else if (is_type_operator) { - if (doc_value.value_type != bson_type) { - match_err (&derived, "incorrect type"); - goto fail; - } - } else if (!match_bson_value (&doc_value, value, &derived)) { - goto fail; - } - - next: - is_first = false; - if (found) { - bson_value_destroy (&doc_value); - } - } - - return true; - -fail: - if (found) { - bson_value_destroy (&doc_value); - } - - if (strlen (derived.errmsg) > 0) { - strcpy (ctx->errmsg, derived.errmsg); - } - - return false; -} - - -/*-------------------------------------------------------------------------- - * - * find -- - * - * Find the value for a key. - * - * Returns: - * Whether the key was found. - * - * Side effects: - * Copies the found value into "iter_out". - * - *-------------------------------------------------------------------------- - */ - -static bool -find (bson_iter_t *iter_out, - const bson_t *doc, - const char *key, - bool is_command, - bool is_first, - bool retain_dots_in_keys) -{ - bson_iter_t iter; - bson_iter_t descendent; - - bson_iter_init (&iter, doc); - - if (!retain_dots_in_keys && strchr (key, '.')) { - if (!bson_iter_find_descendant (&iter, key, &descendent)) { - return false; - } - - memcpy (iter_out, &descendent, sizeof (bson_iter_t)); - return true; - } else if (is_command && is_first) { - if (!bson_iter_find_case (&iter, key)) { - return false; - } - } else if (!bson_iter_find (&iter, key)) { - return false; - } - - memcpy (iter_out, &iter, sizeof (bson_iter_t)); - return true; -} - - -bool -bson_init_from_value (bson_t *b, const bson_value_t *v) -{ - BSON_ASSERT (v->value_type == BSON_TYPE_ARRAY || - v->value_type == BSON_TYPE_DOCUMENT); - - return bson_init_static (b, v->value.v_doc.data, v->value.v_doc.data_len); -} - - -static bool -_is_operator (const char *op_name, const bson_value_t *value, bool *op_val) -{ - bson_t bson; - bson_iter_t iter; - - if (value->value_type == BSON_TYPE_DOCUMENT && - bson_init_from_value (&bson, value) && - bson_iter_init_find (&iter, &bson, op_name)) { - *op_val = bson_iter_as_bool (&iter); - return true; - } - - return false; -} - - -/*-------------------------------------------------------------------------- - * - * get_exists_operator -- - * - * Is value a subdocument like {"$exists": bool}? - * - * Returns: - * True if the value is a subdocument with the first key "$exists", - * or if value is BSON null. - * - * Side effects: - * If the function returns true, *exists is set to true or false, - * the value of the bool. - * - *-------------------------------------------------------------------------- - */ - -static bool -get_exists_operator (const bson_value_t *value, bool *exists) -{ - if (_is_operator ("$exists", value, exists)) { - return true; - } - - if (value->value_type == BSON_TYPE_NULL) { - *exists = false; - return true; - } - - return false; -} - - -/*-------------------------------------------------------------------------- - * - * get_empty_operator -- - * - * Is value a subdocument like {"$empty": bool}? - * - * Returns: - * True if the value is a subdocument with the first key "$empty". - * - * Side effects: - * If the function returns true, *empty is set to true or false, - * the value of the bool. - * - *-------------------------------------------------------------------------- - */ - -bool -get_empty_operator (const bson_value_t *value, bool *empty) -{ - return _is_operator ("$empty", value, empty); -} - - -/*-------------------------------------------------------------------------- - * - * get_type_operator -- - * - * Is value a subdocument like {"$$type": "BSON type string"}? - * - * Returns: - * True if the value is a subdocument with the first key "$$type", - * and sets the @bson_type. - * - * Side effects: - * If the function returns true, *@bson_type is set. - * - *-------------------------------------------------------------------------- - */ - -static bool -get_type_operator (const bson_value_t *value, bson_type_t *out) -{ - bson_t bson; - bson_iter_t iter; - const char *value_string; - - /* See list of aliases on this page: - * https://docs.mongodb.com/manual/reference/bson-types/ */ - if (value->value_type == BSON_TYPE_DOCUMENT && - bson_init_from_value (&bson, value) && - bson_iter_init_find (&iter, &bson, "$$type")) { - value_string = bson_iter_utf8 (&iter, NULL); - if (0 == strcasecmp ("double", value_string)) { - *out = BSON_TYPE_DOUBLE; - } else if (0 == strcasecmp ("string", value_string)) { - *out = BSON_TYPE_UTF8; - } else if (0 == strcasecmp ("object", value_string)) { - *out = BSON_TYPE_DOCUMENT; - } else if (0 == strcasecmp ("array", value_string)) { - *out = BSON_TYPE_ARRAY; - } else if (0 == strcasecmp ("binData", value_string)) { - *out = BSON_TYPE_BINARY; - } else if (0 == strcasecmp ("undefined", value_string)) { - *out = BSON_TYPE_UNDEFINED; - } else if (0 == strcasecmp ("objectId", value_string)) { - *out = BSON_TYPE_OID; - } else if (0 == strcasecmp ("bool", value_string)) { - *out = BSON_TYPE_BOOL; - } else if (0 == strcasecmp ("date", value_string)) { - *out = BSON_TYPE_DATE_TIME; - } else if (0 == strcasecmp ("null", value_string)) { - *out = BSON_TYPE_NULL; - } else if (0 == strcasecmp ("regex", value_string)) { - *out = BSON_TYPE_REGEX; - } else if (0 == strcasecmp ("dbPointer", value_string)) { - *out = BSON_TYPE_DBPOINTER; - } else if (0 == strcasecmp ("javascript", value_string)) { - *out = BSON_TYPE_CODE; - } else if (0 == strcasecmp ("symbol", value_string)) { - *out = BSON_TYPE_SYMBOL; - } else if (0 == strcasecmp ("javascriptWithScope", value_string)) { - *out = BSON_TYPE_CODEWSCOPE; - } else if (0 == strcasecmp ("int", value_string)) { - *out = BSON_TYPE_INT32; - } else if (0 == strcasecmp ("timestamp", value_string)) { - *out = BSON_TYPE_TIMESTAMP; - } else if (0 == strcasecmp ("long", value_string)) { - *out = BSON_TYPE_INT64; - } else if (0 == strcasecmp ("decimal", value_string)) { - *out = BSON_TYPE_DECIMAL128; - } else if (0 == strcasecmp ("minKey", value_string)) { - *out = BSON_TYPE_MINKEY; - } else if (0 == strcasecmp ("maxKey", value_string)) { - *out = BSON_TYPE_MAXKEY; - } else { - fprintf (stderr, "unrecognized $$type value: %s\n", value_string); - abort (); - } - return true; - } - - return false; -} - - -/*-------------------------------------------------------------------------- - * - * is_empty_doc_or_array -- - * - * Is value the subdocument {} or the array []? - * - *-------------------------------------------------------------------------- - */ - -static bool -is_empty_doc_or_array (const bson_value_t *value) -{ - bson_t doc; - - if (!(value->value_type == BSON_TYPE_ARRAY || - value->value_type == BSON_TYPE_DOCUMENT)) { - return false; - } - BSON_ASSERT (bson_init_static ( - &doc, value->value.v_doc.data, value->value.v_doc.data_len)); - - return bson_count_keys (&doc) == 0; -} - - -static bool -match_bson_arrays (const bson_t *array, const bson_t *pattern, match_ctx_t *ctx) -{ - uint32_t array_count; - uint32_t pattern_count; - bson_iter_t array_iter; - bson_iter_t pattern_iter; - const bson_value_t *array_value; - const bson_value_t *pattern_value; - match_ctx_t derived; - - array_count = bson_count_keys (array); - pattern_count = bson_count_keys (pattern); - - if (array_count != pattern_count) { - match_err (ctx, - "expected %" PRIu32 " keys, not %" PRIu32, - pattern_count, - array_count); - return false; - } - - BSON_ASSERT (bson_iter_init (&array_iter, array)); - BSON_ASSERT (bson_iter_init (&pattern_iter, pattern)); - - while (bson_iter_next (&array_iter)) { - BSON_ASSERT (bson_iter_next (&pattern_iter)); - array_value = bson_iter_value (&array_iter); - pattern_value = bson_iter_value (&pattern_iter); - - derive (ctx, &derived, bson_iter_key (&array_iter)); - - if (!match_bson_value (array_value, pattern_value, &derived)) { - return false; - } - } - - return true; -} - - -static bool -is_number_type (bson_type_t t) -{ - if (t == BSON_TYPE_DOUBLE || t == BSON_TYPE_INT32 || t == BSON_TYPE_INT64) { - return true; - } - - return false; -} - - -int64_t -bson_value_as_int64 (const bson_value_t *value) -{ - if (value->value_type == BSON_TYPE_DOUBLE) { - return (int64_t) value->value.v_double; - } else if (value->value_type == BSON_TYPE_INT32) { - return (int64_t) value->value.v_int32; - } else if (value->value_type == BSON_TYPE_INT64) { - return value->value.v_int64; - } else { - test_error ("bson_value_as_int64 called on value of type %d", - value->value_type); - abort (); - } -} - - -bool -match_bson_value (const bson_value_t *doc, - const bson_value_t *pattern, - match_ctx_t *ctx) -{ - bson_t subdoc; - bson_t pattern_subdoc; - int64_t doc_int64; - int64_t pattern_int64; - bool ret; - - if (ctx && ctx->allow_placeholders) { - /* The change streams spec tests use the value 42 as a placeholder. */ - bool is_placeholder = false; - if (is_number_type (pattern->value_type) && - bson_value_as_int64 (pattern) == 42) { - is_placeholder = true; - } - if (pattern->value_type == BSON_TYPE_UTF8 && - !strcmp (pattern->value.v_utf8.str, "42")) { - is_placeholder = true; - } - if (is_placeholder) { - return true; - } - } - - if (is_number_type (doc->value_type) && - is_number_type (pattern->value_type) && ctx && - !ctx->strict_numeric_types) { - doc_int64 = bson_value_as_int64 (doc); - pattern_int64 = bson_value_as_int64 (pattern); - - if (doc_int64 != pattern_int64) { - match_err (ctx, - "expected %" PRId64 ", got %" PRId64, - pattern_int64, - doc_int64); - return false; - } - - return true; - } - - if (doc->value_type != pattern->value_type) { - match_err (ctx, - "expected type %s, got %s", - _mongoc_bson_type_to_str (pattern->value_type), - _mongoc_bson_type_to_str (doc->value_type)); - return false; - } - - switch (doc->value_type) { - case BSON_TYPE_ARRAY: - case BSON_TYPE_DOCUMENT: - - if (!bson_init_from_value (&subdoc, doc)) { - return false; - } - - if (!bson_init_from_value (&pattern_subdoc, pattern)) { - bson_destroy (&subdoc); - return false; - } - - if (doc->value_type == BSON_TYPE_ARRAY) { - ret = match_bson_arrays (&subdoc, &pattern_subdoc, ctx); - } else { - ret = match_bson_with_ctx (&subdoc, &pattern_subdoc, ctx); - } - - bson_destroy (&subdoc); - bson_destroy (&pattern_subdoc); - - return ret; - - case BSON_TYPE_BINARY: - ret = doc->value.v_binary.data_len == pattern->value.v_binary.data_len && - !memcmp (doc->value.v_binary.data, - pattern->value.v_binary.data, - doc->value.v_binary.data_len); - break; - - case BSON_TYPE_BOOL: - ret = doc->value.v_bool == pattern->value.v_bool; - - if (!ret) { - match_err (ctx, - "expected %d, got %d", - pattern->value.v_bool, - doc->value.v_bool); - } - - return ret; - - case BSON_TYPE_CODE: - ret = doc->value.v_code.code_len == pattern->value.v_code.code_len && - !memcmp (doc->value.v_code.code, - pattern->value.v_code.code, - doc->value.v_code.code_len); - - break; - - case BSON_TYPE_CODEWSCOPE: - ret = doc->value.v_codewscope.code_len == - pattern->value.v_codewscope.code_len && - !memcmp (doc->value.v_codewscope.code, - pattern->value.v_codewscope.code, - doc->value.v_codewscope.code_len) && - doc->value.v_codewscope.scope_len == - pattern->value.v_codewscope.scope_len && - !memcmp (doc->value.v_codewscope.scope_data, - pattern->value.v_codewscope.scope_data, - doc->value.v_codewscope.scope_len); - - break; - - case BSON_TYPE_DATE_TIME: - ret = doc->value.v_datetime == pattern->value.v_datetime; - - if (!ret) { - match_err (ctx, - "expected %" PRId64 ", got %" PRId64, - pattern->value.v_datetime, - doc->value.v_datetime); - } - - return ret; - - case BSON_TYPE_DOUBLE: - ret = doc->value.v_double == pattern->value.v_double; - - if (!ret) { - match_err (ctx, - "expected %f, got %f", - pattern->value.v_double, - doc->value.v_double); - } - - return ret; - - case BSON_TYPE_INT32: - ret = doc->value.v_int32 == pattern->value.v_int32; - - if (!ret) { - match_err (ctx, - "expected %" PRId32 ", got %" PRId32, - pattern->value.v_int32, - doc->value.v_int32); - } - - return ret; - - case BSON_TYPE_INT64: - ret = doc->value.v_int64 == pattern->value.v_int64; - - if (!ret) { - match_err (ctx, - "expected %" PRId64 ", got %" PRId64, - pattern->value.v_int64, - doc->value.v_int64); - } - - return ret; - - case BSON_TYPE_OID: - ret = bson_oid_equal (&doc->value.v_oid, &pattern->value.v_oid); - break; - - case BSON_TYPE_REGEX: - ret = - !strcmp (doc->value.v_regex.regex, pattern->value.v_regex.regex) && - !strcmp (doc->value.v_regex.options, pattern->value.v_regex.options); - - break; - - case BSON_TYPE_SYMBOL: - ret = doc->value.v_symbol.len == pattern->value.v_symbol.len && - !strncmp (doc->value.v_symbol.symbol, - pattern->value.v_symbol.symbol, - doc->value.v_symbol.len); - - break; - - case BSON_TYPE_TIMESTAMP: - ret = doc->value.v_timestamp.timestamp == - pattern->value.v_timestamp.timestamp && - doc->value.v_timestamp.increment == - pattern->value.v_timestamp.increment; - - break; - - case BSON_TYPE_UTF8: - ret = doc->value.v_utf8.len == pattern->value.v_utf8.len && - !strncmp (doc->value.v_utf8.str, - pattern->value.v_utf8.str, - doc->value.v_utf8.len); - - if (!ret) { - match_err (ctx, - "expected \"%s\", got \"%s\"", - pattern->value.v_utf8.str, - doc->value.v_utf8.str); - } - - return ret; - - - /* these are empty types, if "a" and "b" are the same type they're equal */ - case BSON_TYPE_EOD: - case BSON_TYPE_MAXKEY: - case BSON_TYPE_MINKEY: - case BSON_TYPE_NULL: - case BSON_TYPE_UNDEFINED: - return true; - - case BSON_TYPE_DBPOINTER: - test_error ("DBPointer comparison not implemented"); - abort (); - case BSON_TYPE_DECIMAL128: - test_error ("Decimal128 comparison not implemented"); - abort (); - default: - test_error ("unexpected value type %d: %s", - doc->value_type, - _mongoc_bson_type_to_str (doc->value_type)); - abort (); - } - - if (!ret) { - match_err (ctx, - "%s values mismatch", - _mongoc_bson_type_to_str (pattern->value_type)); - } - - return ret; -} - -bool -mongoc_write_concern_append_bad (mongoc_write_concern_t *write_concern, - bson_t *command) -{ - mongoc_write_concern_t *wc = mongoc_write_concern_copy (write_concern); - - if (!bson_append_document ( - command, "writeConcern", 12, _mongoc_write_concern_get_bson (wc))) { - MONGOC_ERROR ("Could not append writeConcern to command."); - mongoc_write_concern_destroy (wc); - return false; - } - - mongoc_write_concern_destroy (wc); - return true; -} - - -static void -init_huge_string (mongoc_client_t *client) -{ - int32_t max_bson_size; - - BSON_ASSERT (client); - - if (!gHugeString) { - max_bson_size = mongoc_cluster_get_max_bson_obj_size (&client->cluster); - BSON_ASSERT (max_bson_size > 0); - gHugeStringLength = (size_t) max_bson_size - 36; - gHugeString = (char *) bson_malloc (gHugeStringLength + 1); - BSON_ASSERT (gHugeString); - memset (gHugeString, 'a', gHugeStringLength); - gHugeString[gHugeStringLength] = '\0'; - } -} - - -const char * -huge_string (mongoc_client_t *client) -{ - init_huge_string (client); - return gHugeString; -} - - -size_t -huge_string_length (mongoc_client_t *client) -{ - init_huge_string (client); - return gHugeStringLength; -} - - -static void -init_four_mb_string () -{ - if (!gFourMBString) { - gFourMBString = (char *) bson_malloc (FOUR_MB + 1); - BSON_ASSERT (gFourMBString); - memset (gFourMBString, 'a', FOUR_MB); - gFourMBString[FOUR_MB] = '\0'; - } -} - - -const char * -four_mb_string () -{ - init_four_mb_string (); - return gFourMBString; -} - - -static bool -find_key (void *current, void *key) -{ - return !strcmp ((const char *) current, (const char *) key); -} - - -static void -key_dtor (void *item, void *ctx) -{ - /* mongoc_set_t requires a dtor, there's nothing to destroy */ -} - - -void -assert_no_duplicate_keys (const bson_t *doc) -{ - mongoc_set_t *keys; - bson_iter_t iter; - bson_t subdoc; - - keys = mongoc_set_new (8, key_dtor, NULL); - BSON_ASSERT (bson_iter_init (&iter, doc)); - - while (bson_iter_next (&iter)) { - if (mongoc_set_find_item ( - keys, find_key, (void *) bson_iter_key (&iter))) { - fprintf (stderr, - "Duplicate key \"%s\" in document:\n%s", - bson_iter_key (&iter), - bson_as_json (doc, NULL)); - abort (); - } - - mongoc_set_add (keys, 0 /* index */, (void *) bson_iter_key (&iter)); - - if (BSON_ITER_HOLDS_DOCUMENT (&iter) || BSON_ITER_HOLDS_ARRAY (&iter)) { - bson_iter_bson (&iter, &subdoc); - assert_no_duplicate_keys (&subdoc); - } - } - - mongoc_set_destroy (keys); -} - - -void -match_in_array (const bson_t *doc, const bson_t *array, match_ctx_t *ctx) -{ - bson_iter_t array_iter; - bool found = false; - - BSON_ASSERT (bson_iter_init (&array_iter, array)); - - while (bson_iter_next (&array_iter)) { - bson_t array_elem; - - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&array_iter)); - bson_iter_bson (&array_iter, &array_elem); - - if (match_bson_with_ctx (&array_elem, doc, ctx)) { - found = true; - } - - bson_destroy (&array_elem); - } - if (!found) { - test_error ("could not match: %s\n\n" - "in array:\n%s\n\n", - bson_as_canonical_extended_json (doc, NULL), - bson_as_canonical_extended_json (array, NULL)); - } -} - -bson_t * -bson_with_all_types () -{ - bson_t *bson = tmp_bson ("{}"); - bson_oid_t oid; - bson_decimal128_t dec; - - BSON_ASSERT (bson_decimal128_from_string ("1.23456789", &dec)); - bson_oid_init_from_string (&oid, "000000000000000000000000"); - BSON_ASSERT (BSON_APPEND_DOUBLE (bson, "double", 1.0)); - BSON_ASSERT (BSON_APPEND_UTF8 (bson, "string", "string_example")); - BSON_ASSERT ( - BSON_APPEND_DOCUMENT (bson, "document", tmp_bson ("{'x': 'y'}"))); - BSON_ASSERT (BSON_APPEND_ARRAY (bson, "document", tmp_bson ("{'0': 'x'}"))); - BSON_ASSERT (BSON_APPEND_BINARY ( - bson, "binary", BSON_SUBTYPE_BINARY, (uint8_t *) "data", 4)); - BSON_ASSERT (BSON_APPEND_UNDEFINED (bson, "undefined")); - BSON_ASSERT (BSON_APPEND_OID (bson, "oid", &oid)); - BSON_ASSERT (BSON_APPEND_BOOL (bson, "bool", true)); - BSON_ASSERT (BSON_APPEND_DATE_TIME (bson, "datetime", 123)); - BSON_ASSERT (BSON_APPEND_NULL (bson, "null")); - BSON_ASSERT (BSON_APPEND_REGEX (bson, "regex", "a+", NULL)); - BSON_ASSERT (BSON_APPEND_DBPOINTER (bson, "dbpointer", "collection", &oid)); - BSON_ASSERT (BSON_APPEND_CODE (bson, "code", "var x = 1;")); - BSON_ASSERT (BSON_APPEND_SYMBOL (bson, "symbol", "symbol_example")); - BSON_ASSERT (BSON_APPEND_CODE (bson, "code", "var x = 1;")); - BSON_ASSERT (BSON_APPEND_CODE_WITH_SCOPE ( - bson, "code_w_scope", "var x = 1;", tmp_bson ("{}"))); - BSON_ASSERT (BSON_APPEND_INT32 (bson, "int32", 1)); - BSON_ASSERT (BSON_APPEND_TIMESTAMP (bson, "timestamp", 2, 3)); - BSON_ASSERT (BSON_APPEND_INT64 (bson, "int64", 4)); - BSON_ASSERT (BSON_APPEND_DECIMAL128 (bson, "decimal128", &dec)); - BSON_ASSERT (BSON_APPEND_MINKEY (bson, "minkey")); - BSON_ASSERT (BSON_APPEND_MAXKEY (bson, "maxkey")); - /* and an empty key, as it so often is an edge case. */ - BSON_ASSERT (BSON_APPEND_INT32 (bson, "", -1)); - return bson; -} - -const char * -json_with_all_types () -{ - const char *json = "{\n" - " \"double\": {\n" - " \"$numberDouble\": \"1.0\"\n" - " },\n" - " \"string\": \"string_example\",\n" - " \"document\": {\n" - " \"x\": \"y\"\n" - " },\n" - " \"document\": [\"x\"],\n" - " \"binary\": {\n" - " \"$binary\": {\n" - " \"base64\": \"ZGF0YQ==\",\n" - " \"subType\": \"00\"\n" - " }\n" - " },\n" - " \"undefined\": {\n" - " \"$undefined\": true\n" - " },\n" - " \"oid\": {\n" - " \"$oid\": \"000000000000000000000000\"\n" - " },\n" - " \"bool\": true,\n" - " \"datetime\": {\n" - " \"$date\": {\n" - " \"$numberLong\": \"123\"\n" - " }\n" - " },\n" - " \"null\": null,\n" - " \"regex\": {\n" - " \"$regularExpression\": {\n" - " \"pattern\": \"a+\",\n" - " \"options\": \"\"\n" - " }\n" - " },\n" - " \"dbpointer\": {\n" - " \"$dbPointer\": {\n" - " \"$ref\": \"collection\",\n" - " \"$id\": {\n" - " \"$oid\": \"000000000000000000000000\"\n" - " }\n" - " }\n" - " },\n" - " \"code\": {\n" - " \"$code\": \"var x = 1;\"\n" - " },\n" - " \"symbol\": {\n" - " \"$symbol\": \"symbol_example\"\n" - " },\n" - " \"code\": {\n" - " \"$code\": \"var x = 1;\"\n" - " },\n" - " \"code_w_scope\": {\n" - " \"$code\": \"var x = 1;\",\n" - " \"$scope\": {}\n" - " },\n" - " \"int32\": {\n" - " \"$numberInt\": \"1\"\n" - " },\n" - " \"timestamp\": {\n" - " \"$timestamp\": {\n" - " \"t\": 2,\n" - " \"i\": 3\n" - " }\n" - " },\n" - " \"int64\": {\n" - " \"$numberLong\": \"4\"\n" - " },\n" - " \"decimal128\": {\n" - " \"$numberDecimal\": \"1.23456789\"\n" - " },\n" - " \"minkey\": {\n" - " \"$minKey\": 1\n" - " },\n" - " \"maxkey\": {\n" - " \"$maxKey\": 1\n" - " },\n" - " \"\": {\n" - " \"$numberInt\": \"-1\"\n" - " }\n" - "}"; - return json; -} diff --git a/lib/mongoc/libmongoc/tests/test-conveniences.h b/lib/mongoc/libmongoc/tests/test-conveniences.h deleted file mode 100644 index 6e0e6f46639f96c79b7600d07874ca65c3ea1f2f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-conveniences.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2015 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 TEST_CONVENIENCES_H -#define TEST_CONVENIENCES_H - -#include <bson/bson.h> - -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-read-prefs-private.h" -#include "mongoc/mongoc-client-private.h" - -bson_t * -tmp_bson (const char *json, ...); - -void -bson_iter_bson (const bson_iter_t *iter, bson_t *bson); - -/* create a bson_t containing all types of values, and an empty key. The - * returned bson_t does not need to be freed. This corresponds to the same - * document in json_with_all_types. */ -bson_t * -bson_with_all_types (); - -/* returns a json string with all types of values, and an empty key. This - * corresponds to the same document in bson_with_all_types. */ -const char * -json_with_all_types (); - - -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - -#ifdef _WIN32 -#define realpath(path, expanded) \ - GetFullPathName (path, PATH_MAX, expanded, NULL) -#endif - -const char * -bson_lookup_utf8 (const bson_t *b, const char *key); - -void -value_init_from_doc (bson_value_t *value, const bson_t *doc); - -void -bson_lookup_value (const bson_t *b, const char *key, bson_value_t *value); - -void -bson_lookup_doc (const bson_t *b, const char *key, bson_t *doc); - -void -bson_lookup_doc_null_ok (const bson_t *b, const char *key, bson_t *doc); - -bool -bson_lookup_bool (const bson_t *b, const char *key); - -int32_t -bson_lookup_int32 (const bson_t *b, const char *key); - -int64_t -bson_lookup_int64 (const bson_t *b, const char *key); - -mongoc_read_concern_t * -bson_lookup_read_concern (const bson_t *b, const char *key); - -mongoc_write_concern_t * -bson_lookup_write_concern (const bson_t *b, const char *key); - -mongoc_read_prefs_t * -bson_lookup_read_prefs (const bson_t *b, const char *key); - -void -bson_lookup_database_opts (const bson_t *b, - const char *key, - mongoc_database_t *database); - -void -bson_lookup_collection_opts (const bson_t *b, - const char *key, - mongoc_collection_t *collection); - -mongoc_transaction_opt_t * -bson_lookup_txn_opts (const bson_t *b, const char *key); - -mongoc_session_opt_t * -bson_lookup_session_opts (const bson_t *b, const char *key); - -mongoc_client_session_t * -bson_lookup_session (const bson_t *b, const char *key, mongoc_client_t *client); - -bool -bson_init_from_value (bson_t *b, const bson_value_t *v); - -char * -single_quotes_to_double (const char *str); - -/* match_action_t determines if default check for a field is overridden. */ -typedef enum { - MATCH_ACTION_SKIP, /* do not use the default check. */ - MATCH_ACTION_ABORT, /* an error occurred, stop checking. */ - MATCH_ACTION_CONTINUE /* use the default check. */ -} match_action_t; - -struct _match_ctx_t; -/* doc_iter may be null if the pattern field is not found. */ -typedef match_action_t (*match_visitor_fn) (struct _match_ctx_t *ctx, - bson_iter_t *pattern_iter, - bson_iter_t *doc_iter); - -typedef struct _match_ctx_t { - char errmsg[1000]; - bool strict_numeric_types; - /* if retain_dots_in_keys is true, then don't consider a path with dots to - * indicate recursing into a sub document. */ - bool retain_dots_in_keys; - /* if allow_placeholders is true, treats 42 and "42" as placeholders. I.e. - * comparing 42 to anything is ok. */ - bool allow_placeholders; - /* path is the dot separated breadcrumb trail of keys. */ - char path[1000]; - /* if visitor_fn is not NULL, this is called on for every key in the pattern. - * The returned match_action_t can override the default match behavior. */ - match_visitor_fn visitor_fn; - void *visitor_ctx; - /* if is_command is true, then compare the first key case insensitively. */ - bool is_command; -} match_ctx_t; - -void -assert_match_bson (const bson_t *doc, const bson_t *pattern, bool is_command); - -bool -match_bson (const bson_t *doc, const bson_t *pattern, bool is_command); - -int64_t -bson_value_as_int64 (const bson_value_t *value); - -bool -match_bson_value (const bson_value_t *doc, - const bson_value_t *pattern, - match_ctx_t *ctx); - -bool -match_bson_with_ctx (const bson_t *doc, - const bson_t *pattern, - match_ctx_t *ctx); - -bool -match_json (const bson_t *doc, - bool is_command, - const char *filename, - int lineno, - const char *funcname, - const char *json_pattern, - ...); - -#define ASSERT_MATCH(doc, ...) \ - do { \ - BSON_ASSERT ( \ - match_json (doc, false, __FILE__, __LINE__, BSON_FUNC, __VA_ARGS__)); \ - } while (0) - -bool -mongoc_write_concern_append_bad (mongoc_write_concern_t *write_concern, - bson_t *command); - -#define FOUR_MB 1024 * 1024 * 4 - -const char * -huge_string (mongoc_client_t *client); - -size_t -huge_string_length (mongoc_client_t *client); - -const char * -four_mb_string (); - -void -assert_no_duplicate_keys (const bson_t *doc); - -void -match_in_array (const bson_t *doc, const bson_t *array, match_ctx_t *ctx); - -void -match_err (match_ctx_t *ctx, const char *fmt, ...); - -#endif /* TEST_CONVENIENCES_H */ diff --git a/lib/mongoc/libmongoc/tests/test-happy-eyeballs.c b/lib/mongoc/libmongoc/tests/test-happy-eyeballs.c deleted file mode 100644 index 2cc382afaa01b7b7370a514a01b986defbaf2939..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-happy-eyeballs.c +++ /dev/null @@ -1,591 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-socket-private.h> -#include <mongoc/mongoc-host-list-private.h> -#include <mongoc/mongoc-util-private.h> -#include <mongoc/mongoc-stream-private.h> -#include <mongoc/utlist.h> - -#include "mongoc/mongoc-client-private.h" - -#include "TestSuite.h" -#include "mock_server/mock-server.h" -#include "test-libmongoc.h" - -#define TIMEOUT 20000 /* milliseconds */ - -/* happy eyeballs (he) testing. */ -typedef struct he_testcase_server { - /* { "ipv4", "ipv6", NULL } */ - char *type; - /* if true, this closes the server socket before the client establishes - * connection. */ - bool close_before_connection; - /* how long before the mock server calls `listen` on the server socket. - * this delays the client from establishing a connection. */ - int listen_delay_ms; -} he_testcase_server_t; - -typedef struct he_testcase_client { - /* { "ipv4", "ipv6", "both" } */ - char *type; - int64_t dns_cache_timeout_ms; -} he_testcase_client_t; - -typedef struct he_testcase_expected { - /* { "ipv4", "ipv6", "neither" }. which connection succeeds (if any). */ - char *conn_succeeds_to; - /* how many async commands should be created at the start. */ - int initial_acmds; - /* bounds for the server selection to finish. */ - int duration_min_ms; - int duration_max_ms; -} he_testcase_expected_t; - -typedef struct he_testcase_state { - mock_server_t *mock_server; - mongoc_host_list_t host; - mongoc_topology_scanner_t *ts; - int64_t start; - int last_duration; /* set if timing fails, so it can be retried once. */ -} he_testcase_state_t; - -typedef struct he_testcase { - he_testcase_client_t client; - he_testcase_server_t servers[2]; - he_testcase_expected_t expected; - he_testcase_state_t state; -} he_testcase_t; - -typedef ssize_t (*poll_fn_t) (mongoc_stream_poll_t *streams, - size_t nstreams, - int32_t timeout); - -static poll_fn_t gOriginalPoll; -static he_testcase_t *gCurrentTestCase; - -/* if the server testcase specifies a delay or hangup, overwrite the poll - * response. */ -static int -_override_poll_response (he_testcase_server_t *server, - mongoc_stream_poll_t *poller) -{ - if (server->listen_delay_ms) { - int64_t now = bson_get_monotonic_time (); - if (gCurrentTestCase->state.start + server->listen_delay_ms * 1000 > - now) { - /* should still "sleep". */ - int delta = 0; - if (poller->revents) { - delta = -1; - } - poller->revents = 0; - return delta; - } - } - if (server->close_before_connection) { - poller->revents = POLLHUP; - } - return 0; -} - -/* get the server testcase that this client stream is connected to (if one - * exists). */ -static he_testcase_server_t * -_server_for_client (mongoc_stream_t *stream) -{ - int i; - mongoc_socket_t *sock; - char *stream_type = "ipv4"; - - BSON_ASSERT (stream->type == MONGOC_STREAM_SOCKET); - sock = mongoc_stream_socket_get_socket ((mongoc_stream_socket_t *) stream); - if (sock->domain == AF_INET6) { - stream_type = "ipv6"; - } - - for (i = 0; i < 2; i++) { - const char *server_type = gCurrentTestCase->servers[i].type; - if (!server_type) { - break; - } - if (strcmp (server_type, stream_type) == 0) { - return gCurrentTestCase->servers + i; - } - } - return NULL; -} - -static ssize_t -_mock_poll (mongoc_stream_poll_t *streams, size_t nstreams, int32_t timeout) -{ - int i; - ssize_t starting_nactive; - /* call the real poll first. */ - /* TODO CDRIVER-2542: ZSeries appears to have excessive delay with repeated - * calls to poll. As a workaround, set the poll timeout to 5ms. */ - ssize_t nactive = gOriginalPoll (streams, nstreams, 5); - starting_nactive = nactive; - - /* check if any of the poll responses need to be overwritten. */ - for (i = 0; i < nstreams; i++) { - mongoc_stream_t *stream = - mongoc_stream_get_root_stream ((streams + i)->stream); - he_testcase_server_t *server = _server_for_client (stream); - - if (server) { - nactive += _override_poll_response (server, streams + i); - } - } - if (starting_nactive > 0 && nactive == 0) { - /* if there were active poll responses which were all silenced, - * sleep for a little while since subsequent calls to poll may not have - * any delay. */ - _mongoc_usleep (5 * 1000); - } - return nactive; -} - -static mongoc_stream_t * -_mock_initiator (mongoc_async_cmd_t *acmd) -{ - mongoc_stream_t *stream = _mongoc_topology_scanner_tcp_initiate (acmd); - /* override poll */ - gOriginalPoll = stream->poll; - stream->poll = _mock_poll; - return stream; -} - -static void -_test_scanner_callback (uint32_t id, - const bson_t *bson, - int64_t rtt_msec, - void *data, - const bson_error_t *error /* IN */) -{ - he_testcase_t *testcase = (he_testcase_t *) data; - int should_succeed = strcmp (testcase->expected.conn_succeeds_to, "neither"); - if (should_succeed) { - ASSERT_OR_PRINT (!error->code, (*error)); - } else { - ASSERT_ERROR_CONTAINS ((*error), - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "connection refused"); - } -} - -static void -_init_host (mongoc_host_list_t *host, uint16_t port, const char *type) -{ - char *host_str, *host_and_port; - bool free_host_str = false; - - if (strcmp (type, "ipv4") == 0) { - host_str = "127.0.0.1"; - } else if (strcmp (type, "ipv6") == 0) { - host_str = "[::1]"; - } else { - host_str = test_framework_getenv ("MONGOC_TEST_IPV4_AND_IPV6_HOST"); - if (host_str) { - free_host_str = true; - } else { - /* default to localhost. */ - host_str = "localhost"; - } - } - - host_and_port = bson_strdup_printf ("%s:%hu", host_str, port); - BSON_ASSERT (_mongoc_host_list_from_string (host, host_and_port)); - if (free_host_str) { - bson_free (host_str); - } - /* we should only have one host. */ - BSON_ASSERT (!host->next); - bson_free (host_and_port); -} - -static void -_testcase_setup (he_testcase_t *testcase) -{ - mock_server_t *mock_server = NULL; - mock_server_bind_opts_t opts = {0}; - struct sockaddr_in ipv4_addr = {0}; - struct sockaddr_in6 ipv6_addr = {0}; - char *server_type = "both"; - - /* if there is only one server, use that type. */ - if (testcase->servers[0].type && !testcase->servers[1].type) { - server_type = testcase->servers[0].type; - } - - if (strcmp ("both", server_type) == 0) { - opts.bind_addr_len = sizeof (ipv6_addr); - opts.family = AF_INET6; - opts.ipv6_only = 0; - ipv6_addr.sin6_family = AF_INET6; - ipv6_addr.sin6_port = htons (0); - ipv6_addr.sin6_addr = in6addr_any; - opts.bind_addr = (struct sockaddr_in *) &ipv6_addr; - } else if (strcmp ("ipv4", server_type) == 0) { - opts.bind_addr_len = sizeof (ipv4_addr); - opts.family = AF_INET; - opts.ipv6_only = 0; - ipv4_addr.sin_family = AF_INET; - ipv4_addr.sin_port = htons (0); - BSON_ASSERT (inet_pton (AF_INET, "127.0.0.1", &ipv4_addr.sin_addr)); - opts.bind_addr = &ipv4_addr; - } else if (strcmp ("ipv6", server_type) == 0) { - opts.bind_addr_len = sizeof (ipv6_addr); - opts.family = AF_INET6; - opts.ipv6_only = 1; - ipv6_addr.sin6_family = AF_INET6; - ipv6_addr.sin6_port = htons (0); - BSON_ASSERT (inet_pton (AF_INET6, "::1", &ipv6_addr.sin6_addr)); - opts.bind_addr = (struct sockaddr_in *) &ipv6_addr; - } - - mock_server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_set_bind_opts (mock_server, &opts); - mock_server_run (mock_server); - - _init_host (&testcase->state.host, - mock_server_get_port (mock_server), - testcase->client.type); - - testcase->state.ts = mongoc_topology_scanner_new ( - NULL, NULL, &_test_scanner_callback, testcase, TIMEOUT); - - testcase->state.mock_server = mock_server; - - if (testcase->client.dns_cache_timeout_ms > 0) { - _mongoc_topology_scanner_set_dns_cache_timeout ( - testcase->state.ts, testcase->client.dns_cache_timeout_ms); - } -} - -static void -_testcase_teardown (he_testcase_t *testcase) -{ - mock_server_destroy (testcase->state.mock_server); - mongoc_topology_scanner_destroy (testcase->state.ts); -} - -static void -_check_stream (mongoc_stream_t *stream, const char *expected, char *message) -{ - /* check the socket that the scanner found. */ - char *actual = "neither"; - if (stream) { - mongoc_socket_t *sock = - mongoc_stream_socket_get_socket ((mongoc_stream_socket_t *) stream); - actual = (sock->domain == AF_INET) ? "ipv4" : "ipv6"; - } - - ASSERT_WITH_MSG (strcmp (expected, actual) == 0, - "%s: expected %s stream but got %s stream\n", - message, - expected, - actual); -} - -static void -_testcase_run (he_testcase_t *testcase) -{ - /* construct mock servers. */ - mongoc_topology_scanner_t *ts = testcase->state.ts; - mongoc_topology_scanner_node_t *node; - he_testcase_expected_t *expected = &testcase->expected; - uint64_t duration_ms; - mongoc_async_cmd_t *iter; - - gCurrentTestCase = testcase; - testcase->state.start = bson_get_monotonic_time (); - - mongoc_topology_scanner_add ( - ts, &testcase->state.host, 1 /* any server id is ok. */); - mongoc_topology_scanner_scan (ts, 1); - /* how many commands should we have initially? */ - ASSERT_CMPINT ((int) (ts->async->ncmds), ==, expected->initial_acmds); - - DL_FOREACH (ts->async->cmds, iter) - { - iter->initiator = _mock_initiator; - } - - mongoc_topology_scanner_work (ts); - - duration_ms = (bson_get_monotonic_time () - testcase->state.start) / (1000); - -#ifndef _WIN32 - /* Note: do not check time on Windows. Windows waits 1 second before refusing - * connection to unused ports: - * https://support.microsoft.com/en-us/help/175523/info-winsock-tcp-connection-performance-to-unused-ports - */ - if (!test_suite_valgrind ()) { - bool within_expected_duration = - duration_ms >= expected->duration_min_ms && - duration_ms < expected->duration_max_ms; - if (!within_expected_duration) { - /* this is a timing failure, this may have been a fluke, retry once. */ - ASSERT_WITH_MSG (!testcase->state.last_duration, - "Timing failed twice. Expected to take between %dms " - "and %dms. First duration was %dms, second was %dms.", - expected->duration_min_ms, - expected->duration_max_ms, - testcase->state.last_duration, - (int) duration_ms); - testcase->state.last_duration = duration_ms; - } else { - /* clear the last duration in case succeeded on second try. */ - testcase->state.last_duration = 0; - } - } -#endif - - node = mongoc_topology_scanner_get_node (ts, 1); - _check_stream (node->stream, - expected->conn_succeeds_to, - "checking client's final connection"); -} - -#define CLIENT(client) \ - { \ - #client \ - } - -#define CLIENT_WITH_DNS_CACHE_TIMEOUT(type, timeout) \ - { \ - #type, timeout \ - } -#define HANGUP true -#define LISTEN false -#define SERVER(type, hangup) \ - { \ - #type, hangup \ - } -#define DELAYED_SERVER(type, hangup, delay) \ - { \ - #type, hangup, delay \ - } -#define SERVERS(...) \ - { \ - __VA_ARGS__ \ - } -#define DELAY_MS(val) val -#define DURATION_MS(min, max) (min), (max) -#define EXPECT(type, num_acmds, duration) \ - { \ - #type, num_acmds, duration \ - } -#define NCMDS(n) (n) - -static void -_run_testcase (void *ctx) -{ - he_testcase_t *testcase = (he_testcase_t *) ctx; -retry: - _testcase_setup (testcase); - _testcase_run (testcase); - _testcase_teardown (testcase); - if (testcase->state.last_duration) { - goto retry; - } -} - -static void -test_happy_eyeballs_dns_cache (void) -{ -#define E 1000 - he_testcase_t testcase = { - CLIENT_WITH_DNS_CACHE_TIMEOUT (both, 1000), - SERVERS (SERVER (ipv4, LISTEN), SERVER (ipv6, LISTEN)), - EXPECT (ipv6, NCMDS (2), DURATION_MS (0, E)), - }; - _testcase_setup (&testcase); - _testcase_run (&testcase); - /* disconnect the node so we perform another DNS lookup. */ - mongoc_topology_scanner_node_disconnect (testcase.state.ts->nodes, false); - - /* after running once, the topology scanner should have cached the DNS - * result for IPv6. It should complete immediately. */ - testcase.expected.initial_acmds = 1; - _testcase_run (&testcase); - - /* disconnect the node so we perform another DNS lookup. */ - mongoc_topology_scanner_node_disconnect (testcase.state.ts->nodes, false); - - /* wait for DNS cache to expire. */ - _mongoc_usleep (2000 * 1000); - - /* after running once, the topology scanner should have cached the DNS - * result for IPv6. It should complete immediately. */ - testcase.expected.initial_acmds = 2; - _testcase_run (&testcase); - - _testcase_teardown (&testcase); -#undef E -} - -void -test_happy_eyeballs_retirement () -{ - /* test connecting to a retired node that fails to initiate a connection. */ -} - -void -test_happy_eyeballs_install (TestSuite *suite) -{ -#define E 1000 /* epsilon. wiggle room for time constraints. */ -#define HE 250 /* delay before ipv4 if ipv6 does not finish. */ - int i, ntests; - - /* This tests conformity to RFC-6555 (Happy Eyeballs) when the topology - * scanner connects to a single server. The expected behavior is as follows: - * - if a hostname has both A and AAAA records, attempt to connect to IPv6 - * immediately, and schedule a delayed IPv4 connection attempt 250ms after. - * - if IPv6 fails, schedule the IPv4 connection attempt immediately. - * - whichever connection attempt succeeds first cancels the other. - * - * The testcases are specified in terms of the client and server. - * Client - * - what address is trying connect (e.g. 127.0.0.1, ::1, localhost)? - * Server - * - is the server listening on IPv4, IPv6, or both? - * - will it delay connection to any of these connections? - * - will it hang up on these connections immediately? - * */ - static he_testcase_t he_testcases[] = { - /* client ipv4. */ - { - CLIENT (ipv4), - SERVERS (SERVER (ipv4, LISTEN)), - EXPECT (ipv4, NCMDS (1), DURATION_MS (0, E)), - }, - { - CLIENT (ipv4), - SERVERS (SERVER (ipv6, LISTEN)), - EXPECT (neither, NCMDS (1), DURATION_MS (0, E)), - }, - {CLIENT (ipv4), - SERVERS (SERVER (ipv4, LISTEN), SERVER (ipv6, HANGUP)), - EXPECT (ipv4, NCMDS (1), DURATION_MS (0, E))}, - { - CLIENT (ipv4), - SERVERS (SERVER (ipv4, HANGUP), SERVER (ipv6, HANGUP)), - EXPECT (neither, NCMDS (1), DURATION_MS (0, E)), - }, - /* client ipv6. */ - { - CLIENT (ipv6), - SERVERS (SERVER (ipv4, LISTEN)), - EXPECT (neither, NCMDS (1), DURATION_MS (0, E)), - }, - { - CLIENT (ipv6), - SERVERS (SERVER (ipv6, LISTEN)), - EXPECT (ipv6, NCMDS (1), DURATION_MS (0, E)), - }, - { - CLIENT (ipv6), - SERVERS (SERVER (ipv4, LISTEN), SERVER (ipv6, LISTEN)), - EXPECT (ipv6, NCMDS (1), DURATION_MS (0, E)), - }, - { - CLIENT (ipv6), - SERVERS (SERVER (ipv4, LISTEN), SERVER (ipv6, HANGUP)), - EXPECT (neither, NCMDS (1), DURATION_MS (0, E)), - }, - /* client both ipv4 and ipv6. */ - { - CLIENT (both), - SERVERS (SERVER (ipv4, LISTEN)), - /* no delay, ipv6 fails immediately and ipv4 succeeds. */ - EXPECT (ipv4, NCMDS (2), DURATION_MS (0, E)), - }, - { - CLIENT (both), - SERVERS (SERVER (ipv6, LISTEN)), - /* no delay, ipv6 succeeds immediately. */ - EXPECT (ipv6, NCMDS (2), DURATION_MS (0, E)), - }, - { - CLIENT (both), - SERVERS (SERVER (ipv4, LISTEN), SERVER (ipv6, LISTEN)), - /* no delay, ipv6 succeeds immediately. */ - EXPECT (ipv6, NCMDS (2), DURATION_MS (0, E)), - }, - { - CLIENT (both), - SERVERS (SERVER (ipv4, LISTEN), SERVER (ipv6, HANGUP)), - /* no delay, ipv6 fails immediately and ipv4 succeeds. */ - EXPECT (ipv4, NCMDS (2), DURATION_MS (0, E)), - }, - /* when both client is connecting to both ipv4 and ipv6 and server is - * listening on both ipv4 and ipv6, test delaying the connections at - * various times. */ - /* ipv6 {succeeds, fails} before ipv4 starts and {succeeds, fails} */ - - {CLIENT (both), - SERVERS (SERVER (ipv4, HANGUP), SERVER (ipv6, HANGUP)), - EXPECT (neither, NCMDS (2), DURATION_MS (0, E))}, - /* ipv6 {succeeds, fails} after ipv4 starts but before ipv4 {succeeds, - fails} */ - { - CLIENT (both), - SERVERS (DELAYED_SERVER (ipv4, LISTEN, DELAY_MS (2 * HE)), - DELAYED_SERVER (ipv6, LISTEN, HE)), - EXPECT (ipv6, NCMDS (2), DURATION_MS (HE, HE + E)), - }, - { - CLIENT (both), - SERVERS (DELAYED_SERVER (ipv4, LISTEN, DELAY_MS (2 * HE)), - DELAYED_SERVER (ipv6, HANGUP, DELAY_MS (HE))), - EXPECT (ipv4, NCMDS (2), DURATION_MS (2 * HE, 2 * HE + E)), - }, - { - CLIENT (both), - SERVERS (DELAYED_SERVER (ipv4, HANGUP, DELAY_MS (2 * HE)), - DELAYED_SERVER (ipv6, HANGUP, DELAY_MS (HE))), - EXPECT (neither, NCMDS (2), DURATION_MS (2 * HE, 2 * HE + E)), - }, - /* ipv4 {succeeds,fails} after ipv6 {succeeds, fails}. */ - { - CLIENT (both), - SERVERS (SERVER (ipv4, LISTEN), - DELAYED_SERVER (ipv6, LISTEN, DELAY_MS (HE + E))), - /* ipv6 is delayed too long, ipv4 succeeds. */ - EXPECT (ipv4, NCMDS (2), DURATION_MS (HE, HE + E)), - }, - { - CLIENT (both), - SERVERS (SERVER (ipv4, HANGUP), - DELAYED_SERVER (ipv6, LISTEN, DELAY_MS (HE + E))), - /* ipv6 is delayed, but ipv4 fails. */ - EXPECT (ipv6, NCMDS (2), DURATION_MS (HE + E, HE + 2 * E)), - }, - { - CLIENT (both), - SERVERS (SERVER (ipv4, HANGUP), - DELAYED_SERVER (ipv6, HANGUP, DELAY_MS (HE + E))), - EXPECT (neither, NCMDS (2), DURATION_MS (HE + E, HE + 2 * E)), - }, - }; -#undef HE -#undef E - ntests = sizeof (he_testcases) / sizeof (he_testcases[0]); - for (i = 0; i < ntests; i++) { - char *name = bson_strdup_printf ("/TOPOLOGY/happy_eyeballs/%d", i); - TestSuite_AddFull (suite, - name, - _run_testcase, - NULL, - he_testcases + i, - test_framework_skip_if_no_dual_ip_hostname, - TestSuite_CheckMockServerAllowed); - bson_free (name); - } - TestSuite_AddMockServerTest (suite, - "/TOPOLOGY/happy_eyeballs/dns_cache/", - test_happy_eyeballs_dns_cache, - test_framework_skip_if_no_dual_ip_hostname); -} diff --git a/lib/mongoc/libmongoc/tests/test-libmongoc.c b/lib/mongoc/libmongoc/tests/test-libmongoc.c deleted file mode 100644 index 518942c6aea025a39f6490ea6218bb889fe23119..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-libmongoc.c +++ /dev/null @@ -1,2466 +0,0 @@ -/* - * Copyright 2013 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 <bson/bson.h> -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-host-list-private.h> - -#include "mongoc/mongoc-server-description.h" -#include "mongoc/mongoc-server-description-private.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-util-private.h" - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - -/* libbson */ - - -extern void -test_atomic_install (TestSuite *suite); -extern void -test_bcon_basic_install (TestSuite *suite); -extern void -test_bcon_extract_install (TestSuite *suite); -extern void -test_bson_corpus_install (TestSuite *suite); -extern void -test_bson_install (TestSuite *suite); -extern void -test_bson_version_install (TestSuite *suite); -extern void -test_clock_install (TestSuite *suite); -extern void -test_decimal128_install (TestSuite *suite); -extern void -test_endian_install (TestSuite *suite); -extern void -test_bson_error_install (TestSuite *suite); -extern void -test_iso8601_install (TestSuite *suite); -extern void -test_iter_install (TestSuite *suite); -extern void -test_json_install (TestSuite *suite); -extern void -test_oid_install (TestSuite *suite); -extern void -test_reader_install (TestSuite *suite); -extern void -test_string_install (TestSuite *suite); -extern void -test_utf8_install (TestSuite *suite); -extern void -test_value_install (TestSuite *suite); -extern void -test_writer_install (TestSuite *suite); - -/* libmongoc */ - -extern void -test_aggregate_install (TestSuite *suite); -extern void -test_array_install (TestSuite *suite); -extern void -test_async_install (TestSuite *suite); -extern void -test_buffer_install (TestSuite *suite); -extern void -test_bulk_install (TestSuite *suite); -extern void -test_change_stream_install (TestSuite *suite); -extern void -test_client_install (TestSuite *suite); -extern void -test_client_max_staleness_install (TestSuite *suite); -extern void -test_client_pool_install (TestSuite *suite); -extern void -test_cluster_install (TestSuite *suite); -extern void -test_collection_install (TestSuite *suite); -extern void -test_collection_find_install (TestSuite *suite); -extern void -test_collection_find_with_opts_install (TestSuite *suite); -extern void -test_connection_uri_install (TestSuite *suite); -extern void -test_command_monitoring_install (TestSuite *suite); -extern void -test_cursor_install (TestSuite *suite); -extern void -test_database_install (TestSuite *suite); -extern void -test_dns_install (TestSuite *suite); -extern void -test_error_install (TestSuite *suite); -extern void -test_exhaust_install (TestSuite *suite); -extern void -test_find_and_modify_install (TestSuite *suite); -extern void -test_gridfs_bucket_install (TestSuite *suite); -extern void -test_gridfs_file_page_install (TestSuite *suite); -extern void -test_gridfs_install (TestSuite *suite); -extern void -test_linux_distro_scanner_install (TestSuite *suite); -extern void -test_list_install (TestSuite *suite); -extern void -test_log_install (TestSuite *suite); -extern void -test_matcher_install (TestSuite *suite); -extern void -test_mongos_pinning_install (TestSuite *suite); -extern void -test_handshake_install (TestSuite *suite); -extern void -test_queue_install (TestSuite *suite); -extern void -test_primary_stepdown_install (TestSuite *suite); -extern void -test_read_concern_install (TestSuite *suite); -extern void -test_read_write_concern_install (TestSuite *suite); -extern void -test_read_prefs_install (TestSuite *suite); -extern void -test_retryable_writes_install (TestSuite *suite); -extern void -test_retryable_reads_install (TestSuite *suite); -extern void -test_rpc_install (TestSuite *suite); -extern void -test_samples_install (TestSuite *suite); -extern void -test_scram_install (TestSuite *suite); -extern void -test_sdam_install (TestSuite *suite); -extern void -test_sdam_monitoring_install (TestSuite *suite); -extern void -test_server_selection_install (TestSuite *suite); -extern void -test_session_install (TestSuite *suite); -extern void -test_server_selection_errors_install (TestSuite *suite); -extern void -test_set_install (TestSuite *suite); -extern void -test_opts_install (TestSuite *suite); -extern void -test_socket_install (TestSuite *suite); -extern void -test_stream_install (TestSuite *suite); -extern void -test_thread_install (TestSuite *suite); -extern void -test_topology_install (TestSuite *suite); -extern void -test_topology_description_install (TestSuite *suite); -extern void -test_topology_reconcile_install (TestSuite *suite); -extern void -test_transactions_install (TestSuite *suite); -extern void -test_topology_scanner_install (TestSuite *suite); -extern void -test_uri_install (TestSuite *suite); -extern void -test_usleep_install (TestSuite *suite); -extern void -test_util_install (TestSuite *suite); -extern void -test_version_install (TestSuite *suite); -extern void -test_with_transaction_install (TestSuite *suite); -extern void -test_write_command_install (TestSuite *suite); -extern void -test_write_concern_install (TestSuite *suite); -#ifdef MONGOC_ENABLE_SSL -extern void -test_stream_tls_install (TestSuite *suite); -extern void -test_x509_install (TestSuite *suite); -extern void -test_stream_tls_error_install (TestSuite *suite); -#endif -#ifdef MONGOC_ENABLE_SASL_CYRUS -extern void -test_cyrus_install (TestSuite *suite); -#endif -extern void -test_happy_eyeballs_install (TestSuite *suite); -extern void -test_counters_install (TestSuite *suite); -extern void -test_crud_install (TestSuite *suite); -extern void -test_apm_install (TestSuite *suite); -extern void -test_client_side_encryption_install (TestSuite *suite); - -typedef struct { - mongoc_log_level_t level; - char *msg; -} log_entry_t; - -static bson_mutex_t captured_logs_mutex; -static mongoc_array_t captured_logs; -static bool capturing_logs; -#ifdef MONGOC_ENABLE_SSL -static mongoc_ssl_opt_t gSSLOptions; -#endif - - -static log_entry_t * -log_entry_create (mongoc_log_level_t level, const char *msg) -{ - log_entry_t *log_entry; - - log_entry = bson_malloc (sizeof (log_entry_t)); - log_entry->level = level; - log_entry->msg = bson_strdup (msg); - - return log_entry; -} - - -static void -log_entry_destroy (log_entry_t *log_entry) -{ - bson_free (log_entry->msg); - bson_free (log_entry); -} - - -void -capture_logs (bool capture) -{ - capturing_logs = capture; - clear_captured_logs (); -} - - -void -clear_captured_logs (void) -{ - size_t i; - log_entry_t *log_entry; - - bson_mutex_lock (&captured_logs_mutex); - for (i = 0; i < captured_logs.len; i++) { - log_entry = _mongoc_array_index (&captured_logs, log_entry_t *, i); - log_entry_destroy (log_entry); - } - - captured_logs.len = 0; - bson_mutex_unlock (&captured_logs_mutex); -} - - -bool -has_captured_log (mongoc_log_level_t level, const char *msg) -{ - size_t i; - log_entry_t *log_entry; - - bson_mutex_lock (&captured_logs_mutex); - - for (i = 0; i < captured_logs.len; i++) { - log_entry = _mongoc_array_index (&captured_logs, log_entry_t *, i); - if (level == log_entry->level && strstr (log_entry->msg, msg)) { - bson_mutex_unlock (&captured_logs_mutex); - return true; - } - } - - bson_mutex_unlock (&captured_logs_mutex); - - return false; -} - - -bool -has_captured_logs (void) -{ - bool ret; - - bson_mutex_lock (&captured_logs_mutex); - ret = 0 != captured_logs.len; - bson_mutex_unlock (&captured_logs_mutex); - - return ret; -} - - -void -assert_all_captured_logs_have_prefix (const char *prefix) -{ - size_t i; - log_entry_t *log_entry; - - bson_mutex_lock (&captured_logs_mutex); - - for (i = 0; i < captured_logs.len; i++) { - log_entry = _mongoc_array_index (&captured_logs, log_entry_t *, i); - ASSERT_STARTSWITH (log_entry->msg, prefix); - } - - bson_mutex_unlock (&captured_logs_mutex); -} - - -void -print_captured_logs (const char *prefix) -{ - size_t i; - log_entry_t *log_entry; - - bson_mutex_lock (&captured_logs_mutex); - for (i = 0; i < captured_logs.len; i++) { - log_entry = _mongoc_array_index (&captured_logs, log_entry_t *, i); - if (prefix) { - fprintf (stderr, - "%s%s %s\n", - prefix, - mongoc_log_level_str (log_entry->level), - log_entry->msg); - } else { - fprintf (stderr, - "%s %s\n", - mongoc_log_level_str (log_entry->level), - log_entry->msg); - } - } - bson_mutex_unlock (&captured_logs_mutex); -} - - -#define DEFAULT_FUTURE_TIMEOUT_MS 10 * 1000 - -int64_t -get_future_timeout_ms () -{ - return test_framework_getenv_int64 ("MONGOC_TEST_FUTURE_TIMEOUT_MS", - DEFAULT_FUTURE_TIMEOUT_MS); -} - -static void -log_handler (mongoc_log_level_t log_level, - const char *log_domain, - const char *message, - void *user_data) -{ - TestSuite *suite; - log_entry_t *log_entry; - - suite = (TestSuite *) user_data; - - if (log_level < MONGOC_LOG_LEVEL_INFO) { - if (capturing_logs) { - log_entry = log_entry_create (log_level, message); - bson_mutex_lock (&captured_logs_mutex); - _mongoc_array_append_val (&captured_logs, log_entry); - bson_mutex_unlock (&captured_logs_mutex); - return; - } - - if (!suite->silent) { - mongoc_log_default_handler (log_level, log_domain, message, NULL); - } - } -} - - -mongoc_database_t * -get_test_database (mongoc_client_t *client) -{ - return mongoc_client_get_database (client, "test"); -} - - -char * -gen_collection_name (const char *str) -{ - return bson_strdup_printf ("%s_%u_%u", - str, - (unsigned) bson_get_monotonic_time (), - (unsigned) gettestpid ()); -} - - -mongoc_collection_t * -get_test_collection (mongoc_client_t *client, const char *prefix) -{ - mongoc_collection_t *ret; - char *str; - - str = gen_collection_name (prefix); - ret = mongoc_client_get_collection (client, "test", str); - bson_free (str); - - return ret; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_env -- - * - * Get the value of an environment variable. - * - * Returns: - * A string you must bson_free, or NULL if the variable is not set. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_getenv (const char *name) -{ -#ifdef _MSC_VER - char buf[1024]; - size_t buflen; - - if ((0 == getenv_s (&buflen, buf, sizeof buf, name)) && buflen) { - return bson_strdup (buf); - } else { - return NULL; - } -#else - - if (getenv (name) && strlen (getenv (name))) { - return bson_strdup (getenv (name)); - } else { - return NULL; - } - -#endif -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_getenv_bool -- - * - * Check if an environment variable is set. - * - * Returns: - * True if the variable is set, or set to "on", false if it is not set - * or set to "off". - * - * Side effects: - * Logs and aborts if there is another value like "yes" or "true". - * - *-------------------------------------------------------------------------- - */ -bool -test_framework_getenv_bool (const char *name) -{ - char *value = test_framework_getenv (name); - bool ret = false; - - if (value) { - if (!strcasecmp (value, "off")) { - ret = false; - } else if (!strcasecmp (value, "") || !strcasecmp (value, "on")) { - ret = true; - } else { - fprintf (stderr, - "Unrecognized value for %s: \"%s\". Use \"on\" or \"off\".\n", - name, - value); - abort (); - } - } - - bson_free (value); - return ret; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_getenv_int64 -- - * - * Get a number from an environment variable. - * - * Returns: - * The number, or default. - * - * Side effects: - * Logs and aborts if there is a non-numeric value. - * - *-------------------------------------------------------------------------- - */ -int64_t -test_framework_getenv_int64 (const char *name, int64_t default_value) -{ - char *value = test_framework_getenv (name); - char *endptr; - int64_t ret; - - if (value) { - errno = 0; - ret = bson_ascii_strtoll (value, &endptr, 10); - if (errno) { - perror (bson_strdup_printf ("Parsing %s from environment", name)); - abort (); - } - - bson_free (value); - return ret; - } - - return default_value; -} - - -static char * -test_framework_get_unix_domain_socket_path (void) -{ - char *path = test_framework_getenv ("MONGOC_TEST_UNIX_DOMAIN_SOCKET"); - - if (path) { - return path; - } - - return bson_strdup_printf ("/tmp/mongodb-%d.sock", - test_framework_get_port ()); -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_unix_domain_socket_path_escaped -- - * - * Get the path to Unix Domain Socket .sock of the test MongoDB server, - * URI-escaped ("/" is replaced with "%2F"). - * - * Returns: - * A string you must bson_free. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_get_unix_domain_socket_path_escaped (void) -{ - char *path = test_framework_get_unix_domain_socket_path (), *c = path; - bson_string_t *escaped = bson_string_new (NULL); - - /* Connection String Spec: "The host information cannot contain an unescaped - * slash ("/"), if it does then an exception MUST be thrown informing users - * that paths must be URL encoded." - * - * Even though the C Driver does not currently enforce the spec, let's pass - * a correctly escaped URI. - */ - do { - if (*c == '/') { - bson_string_append (escaped, "%2F"); - } else { - bson_string_append_c (escaped, *c); - } - } while (*(++c)); - - bson_string_append_c (escaped, '\0'); - bson_free (path); - - return bson_string_free (escaped, false /* free_segment */); -} - -static char * -_uri_str_from_env (void) -{ - return test_framework_getenv ("MONGOC_TEST_URI"); -} - -static mongoc_uri_t * -_uri_from_env (void) -{ - char *env_uri_str; - mongoc_uri_t *uri; - - env_uri_str = _uri_str_from_env (); - if (env_uri_str) { - uri = mongoc_uri_new (env_uri_str); - bson_free (env_uri_str); - return uri; - } - - return NULL; -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_host -- - * - * Get the hostname of the test MongoDB server. - * - * Returns: - * A string you must bson_free. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_get_host (void) -{ - mongoc_uri_t *env_uri; - const mongoc_host_list_t *hosts; - char *host; - - /* MONGOC_TEST_URI takes precedence */ - env_uri = _uri_from_env (); - if (env_uri) { - /* choose first host */ - hosts = mongoc_uri_get_hosts (env_uri); - host = bson_strdup (hosts->host); - mongoc_uri_destroy (env_uri); - return host; - } - - host = test_framework_getenv ("MONGOC_TEST_HOST"); - - return host ? host : bson_strdup ("localhost"); -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_port -- - * - * Get the port number of the test MongoDB server. - * - * Returns: - * The port number, 27017 by default. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -uint16_t -test_framework_get_port (void) -{ - mongoc_uri_t *env_uri; - const mongoc_host_list_t *hosts; - char *port_str; - unsigned long port = MONGOC_DEFAULT_PORT; - - /* MONGOC_TEST_URI takes precedence */ - env_uri = _uri_from_env (); - if (env_uri) { - /* choose first port */ - hosts = mongoc_uri_get_hosts (env_uri); - port = hosts->port; - mongoc_uri_destroy (env_uri); - } else { - port_str = test_framework_getenv ("MONGOC_TEST_PORT"); - if (port_str && strlen (port_str)) { - port = strtoul (port_str, NULL, 10); - if (port == 0 || port > UINT16_MAX) { - /* parse err or port out of range -- mongod prohibits port 0 */ - port = MONGOC_DEFAULT_PORT; - } - } - - bson_free (port_str); - } - - return (uint16_t) port; -} - -char * -test_framework_get_host_and_port (void) -{ - char *host = test_framework_get_host (); - uint16_t port = test_framework_get_port (); - char *host_and_port; - if (strchr (host, ':')) { - /* wrap IPv6 address in square brackets. */ - host_and_port = bson_strdup_printf ("[%s]:%hu", host, port); - } else { - host_and_port = bson_strdup_printf ("%s:%hu", host, port); - } - bson_free (host); - return host_and_port; -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_admin_user -- - * - * Get the username of an admin user on the test MongoDB server. - * - * Returns: - * A string you must bson_free, or NULL. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_get_admin_user (void) -{ - char *retval = NULL; - mongoc_uri_t *env_uri = _uri_from_env (); - - /* MONGOC_TEST_URI takes precedence */ - if (env_uri) { - const char *tmp = mongoc_uri_get_username (env_uri); - - if (tmp) { - retval = bson_strdup (tmp); - } - mongoc_uri_destroy (env_uri); - } - if (!retval) { - retval = test_framework_getenv ("MONGOC_TEST_USER"); - } - - return retval; -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_admin_password -- - * - * Get the password of an admin user on the test MongoDB server. - * - * Returns: - * A string you must bson_free, or NULL. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_get_admin_password (void) -{ - char *retval = NULL; - mongoc_uri_t *env_uri = _uri_from_env (); - - /* MONGOC_TEST_URI takes precedence */ - if (env_uri) { - const char *tmp = mongoc_uri_get_password (env_uri); - - if (tmp) { - retval = bson_strdup (tmp); - } - mongoc_uri_destroy (env_uri); - } - if (!retval) { - retval = test_framework_getenv ("MONGOC_TEST_PASSWORD"); - } - - return retval; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_user_password -- - * - * Get the username and password of an admin user on the test MongoDB - * server. - * - * Returns: - * True if username and password environment variables are set. - * - * Side effects: - * Sets passed-in string pointers to strings you must free, or NULL. - * Logs and aborts if user or password is set in the environment - * but not both, or if user and password are set but SSL is not - * compiled in (SSL is required for SCRAM-SHA-1, see CDRIVER-520). - * - *-------------------------------------------------------------------------- - */ -static bool -test_framework_get_user_password (char **user, char **password) -{ - /* TODO: uri-escape username and password */ - *user = test_framework_get_admin_user (); - *password = test_framework_get_admin_password (); - - if ((*user && !*password) || (!*user && *password)) { - fprintf (stderr, - "Specify both MONGOC_TEST_USER and" - " MONGOC_TEST_PASSWORD, or neither\n"); - abort (); - } - -#ifndef MONGOC_ENABLE_CRYPTO - if (*user && *password) { - fprintf (stderr, - "You need to configure with ENABLE_SSL" - " when providing user+password (for SCRAM-SHA-1)\n"); - abort (); - } -#endif - - return *user != NULL; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_add_user_password -- - * - * Copy a connection string, with user and password added. - * - * Returns: - * A string you must bson_free. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_add_user_password (const char *uri_str, - const char *user, - const char *password) -{ - return bson_strdup_printf ( - "mongodb://%s:%s@%s", user, password, uri_str + strlen ("mongodb://")); -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_add_user_password_from_env -- - * - * Add password of an admin user on the test MongoDB server. - * - * Returns: - * A string you must bson_free. - * - * Side effects: - * Same as test_framework_get_user_password. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_add_user_password_from_env (const char *uri_str) -{ - char *user; - char *password; - char *uri_str_auth; - - if (test_framework_get_user_password (&user, &password)) { - uri_str_auth = test_framework_add_user_password (uri_str, user, password); - - bson_free (user); - bson_free (password); - } else { - uri_str_auth = bson_strdup (uri_str); - } - - return uri_str_auth; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_compressors -- - * - * Get the list of compressors to enable - * - * Returns: - * A string you must bson_free, or NULL if the variable is not set. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_get_compressors () -{ - return test_framework_getenv ("MONGOC_TEST_COMPRESSORS"); -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_has_compressors -- - * - * Check if the test suite has been configured to use compression - * - * Returns: - * true if compressors should be used. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -bool -test_framework_has_compressors () -{ - bool retval; - char *compressors = test_framework_get_compressors (); - - retval = !!compressors; - bson_free (compressors); - - return retval; -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_ssl -- - * - * Should we connect to the test MongoDB server over SSL? - * - * Returns: - * True if any MONGOC_TEST_SSL_* environment variables are set. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -bool -test_framework_get_ssl (void) -{ - char *ssl_option_names[] = {"MONGOC_TEST_SSL_PEM_FILE", - "MONGOC_TEST_SSL_PEM_PWD", - "MONGOC_TEST_SSL_CA_FILE", - "MONGOC_TEST_SSL_CA_DIR", - "MONGOC_TEST_SSL_CRL_FILE", - "MONGOC_TEST_SSL_WEAK_CERT_VALIDATION"}; - char *ssl_option_value; - size_t i; - - for (i = 0; i < sizeof ssl_option_names / sizeof (char *); i++) { - ssl_option_value = test_framework_getenv (ssl_option_names[i]); - - if (ssl_option_value) { - bson_free (ssl_option_value); - return true; - } - } - - return test_framework_getenv_bool ("MONGOC_TEST_SSL"); -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_unix_domain_socket_uri_str -- - * - * Get the connection string (unix domain socket style) of the test - * MongoDB server based on the variables set in the environment. - * Does *not* call isMaster to discover your actual topology. - * - * Returns: - * A string you must bson_free. - * - * Side effects: - * Same as test_framework_get_user_password. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_get_unix_domain_socket_uri_str () -{ - char *path; - char *test_uri_str; - char *test_uri_str_auth; - - path = test_framework_get_unix_domain_socket_path_escaped (); - test_uri_str = bson_strdup_printf ( - "mongodb://%s/%s", path, test_framework_get_ssl () ? "?ssl=true" : ""); - - test_uri_str_auth = test_framework_add_user_password_from_env (test_uri_str); - - bson_free (path); - bson_free (test_uri_str); - - return test_uri_str_auth; -} - - -/* - *-------------------------------------------------------------------------- - * - * call_ismaster_with_host_and_port -- - * - * Call isMaster on a server, possibly over SSL. - * - * Side effects: - * Fills reply with ismaster response. Logs and aborts on error. - * - *-------------------------------------------------------------------------- - */ -static void -call_ismaster_with_host_and_port (char *host_and_port, bson_t *reply) -{ - char *user; - char *password; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_t *client; - bson_error_t error; - - if (test_framework_get_user_password (&user, &password)) { - uri_str = - bson_strdup_printf ("mongodb://%s:%s@%s%s", - user, - password, - host_and_port, - test_framework_get_ssl () ? "/?ssl=true" : ""); - bson_free (user); - bson_free (password); - } else { - uri_str = - bson_strdup_printf ("mongodb://%s%s", - host_and_port, - test_framework_get_ssl () ? "/?ssl=true" : ""); - } - - uri = mongoc_uri_new (uri_str); - BSON_ASSERT (uri); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_CONNECTTIMEOUTMS, 10000); - mongoc_uri_set_option_as_int32 ( - uri, MONGOC_URI_SERVERSELECTIONTIMEOUTMS, 10000); - mongoc_uri_set_option_as_bool ( - uri, MONGOC_URI_SERVERSELECTIONTRYONCE, false); - if (test_framework_has_compressors ()) { - char *compressors = test_framework_get_compressors (); - - mongoc_uri_set_compressors (uri, compressors); - bson_free (compressors); - } - - client = mongoc_client_new_from_uri (uri); -#ifdef MONGOC_ENABLE_SSL - test_framework_set_ssl_opts (client); -#endif - - if (!mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'isMaster': 1}"), NULL, reply, &error)) { - fprintf (stderr, "error calling ismaster: '%s'\n", error.message); - fprintf (stderr, "URI = %s\n", uri_str); - abort (); - } - - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - bson_free (uri_str); -} - -/* - *-------------------------------------------------------------------------- - * - * call_ismaster -- - * - * Call isMaster on the test server, possibly over SSL, using host - * and port from the environment. - * - * Side effects: - * Fills reply with ismaster response. Logs and aborts on error. - * - *-------------------------------------------------------------------------- - */ -static void -call_ismaster (bson_t *reply) -{ - char *host_and_port = test_framework_get_host_and_port (); - - call_ismaster_with_host_and_port (host_and_port, reply); - - bson_free (host_and_port); -} - - -static char * -set_name (bson_t *ismaster_response) -{ - bson_iter_t iter; - - if (bson_iter_init_find (&iter, ismaster_response, "setName")) { - return bson_strdup (bson_iter_utf8 (&iter, NULL)); - } else { - return NULL; - } -} - - -static bool -uri_str_has_db (bson_string_t *uri_string) -{ - const char *after_scheme; - - ASSERT_STARTSWITH (uri_string->str, "mongodb://"); - after_scheme = uri_string->str + strlen ("mongodb://"); - return strchr (after_scheme, '/') != NULL; -} - - -static void -add_option_to_uri_str (bson_string_t *uri_string, - const char *option, - const char *value) -{ - if (strchr (uri_string->str, '?')) { - /* already has some options */ - bson_string_append_c (uri_string, '&'); - } else if (uri_str_has_db (uri_string)) { - /* like "mongodb://host/db" */ - bson_string_append_c (uri_string, '?'); - } else { - /* like "mongodb://host" */ - bson_string_append_printf (uri_string, "/?"); - } - - bson_string_append_printf (uri_string, "%s=%s", option, value); -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_uri_str_no_auth -- - * - * Get the connection string of the test MongoDB topology -- - * standalone, replica set, mongos, or mongoses -- along with - * SSL options, but not username and password. Calls calls isMaster with - * that connection string to discover your topology, and - * returns an appropriate connection string for the topology - * type. - * - * database_name is optional. - * - * Returns: - * A string you must bson_free. - * - * Side effects: - * Same as test_framework_get_user_password. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_get_uri_str_no_auth (const char *database_name) -{ - char *env_uri_str; - bson_t ismaster_response; - bson_string_t *uri_string; - char *name; - bson_iter_t iter; - bson_iter_t hosts_iter; - bool first; - char *host; - uint16_t port; - - env_uri_str = _uri_str_from_env (); - if (env_uri_str) { - uri_string = bson_string_new (env_uri_str); - if (database_name) { - if (uri_string->str[uri_string->len - 1] != '/') { - bson_string_append (uri_string, "/"); - } - bson_string_append (uri_string, database_name); - } - bson_free (env_uri_str); - } else { - /* construct a direct connection or replica set connection URI */ - call_ismaster (&ismaster_response); - uri_string = bson_string_new ("mongodb://"); - - if ((name = set_name (&ismaster_response))) { - /* make a replica set URI */ - bson_iter_init_find (&iter, &ismaster_response, "hosts"); - bson_iter_recurse (&iter, &hosts_iter); - first = true; - - /* append "host1,host2,host3" */ - while (bson_iter_next (&hosts_iter)) { - BSON_ASSERT (BSON_ITER_HOLDS_UTF8 (&hosts_iter)); - if (!first) { - bson_string_append (uri_string, ","); - } - - bson_string_append (uri_string, bson_iter_utf8 (&hosts_iter, NULL)); - first = false; - } - - bson_string_append (uri_string, "/"); - if (database_name) { - bson_string_append (uri_string, database_name); - } - - add_option_to_uri_str (uri_string, MONGOC_URI_REPLICASET, name); - bson_free (name); - } else { - host = test_framework_get_host (); - port = test_framework_get_port (); - bson_string_append_printf (uri_string, "%s:%hu", host, port); - bson_string_append (uri_string, "/"); - if (database_name) { - bson_string_append (uri_string, database_name); - } - - bson_free (host); - } - - if (test_framework_get_ssl ()) { - add_option_to_uri_str (uri_string, MONGOC_URI_SSL, "true"); - } - - bson_destroy (&ismaster_response); - } - - if (test_framework_has_compressors ()) { - char *compressors = test_framework_get_compressors (); - - add_option_to_uri_str (uri_string, MONGOC_URI_COMPRESSORS, compressors); - bson_free (compressors); - } - /* make tests a little more resilient to transient errors */ - add_option_to_uri_str ( - uri_string, MONGOC_URI_SERVERSELECTIONTRYONCE, "false"); - - return bson_string_free (uri_string, false); -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_uri_str -- - * - * Get the connection string of the test MongoDB topology -- - * standalone, replica set, mongos, or mongoses -- along with - * SSL options, username and password. - * - * Returns: - * A string you must bson_free. - * - * Side effects: - * Same as test_framework_get_user_password. - * - *-------------------------------------------------------------------------- - */ -char * -test_framework_get_uri_str () -{ - char *uri_str_no_auth; - char *uri_str; - - /* no_auth also contains compressors. */ - - uri_str_no_auth = test_framework_get_uri_str_no_auth (NULL); - uri_str = test_framework_add_user_password_from_env (uri_str_no_auth); - - bson_free (uri_str_no_auth); - - return uri_str; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_uri -- - * - * Like test_framework_get_uri_str (). Get the URI of the test - * MongoDB server. - * - * Returns: - * A mongoc_uri_t* you must destroy. - * - * Side effects: - * Same as test_framework_get_user_password. - * - *-------------------------------------------------------------------------- - */ -mongoc_uri_t * -test_framework_get_uri () -{ - char *test_uri_str = test_framework_get_uri_str (); - mongoc_uri_t *uri = mongoc_uri_new (test_uri_str); - - BSON_ASSERT (uri); - bson_free (test_uri_str); - - return uri; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_mongos_count -- - * - * Returns the number of servers in the test framework's MongoDB URI. - * - *-------------------------------------------------------------------------- - */ - -size_t -test_framework_mongos_count (void) -{ - mongoc_uri_t *uri = test_framework_get_uri (); - const mongoc_host_list_t *h; - size_t count = 0; - - BSON_ASSERT (uri); - h = mongoc_uri_get_hosts (uri); - while (h) { - ++count; - h = h->next; - } - - mongoc_uri_destroy (uri); - - return count; -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_replset_name -- - * - * Returns the replica set name or NULL. You must free the string. - * - *-------------------------------------------------------------------------- - */ - -char * -test_framework_replset_name (void) -{ - bson_t reply; - bson_iter_t iter; - char *replset_name; - - call_ismaster (&reply); - if (!bson_iter_init_find (&iter, &reply, "setName")) { - return NULL; - } - - replset_name = bson_strdup (bson_iter_utf8 (&iter, NULL)); - bson_destroy (&reply); - - return replset_name; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_replset_member_count -- - * - * Returns the number of replica set members (including arbiters). - * - *-------------------------------------------------------------------------- - */ - -size_t -test_framework_replset_member_count (void) -{ - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - bool r; - bson_iter_t iter, array; - size_t count = 0; - - client = test_framework_client_new (); - r = mongoc_client_command_simple (client, - "admin", - tmp_bson ("{'replSetGetStatus': 1}"), - NULL, - &reply, - &error); - - if (r) { - if (bson_iter_init_find (&iter, &reply, "members") && - BSON_ITER_HOLDS_ARRAY (&iter)) { - bson_iter_recurse (&iter, &array); - while (bson_iter_next (&array)) { - ++count; - } - } - } else if (!strstr (error.message, "not running with --replSet") && - !strstr (error.message, - "replSetGetStatus is not supported through mongos")) { - /* failed for some other reason */ - ASSERT_OR_PRINT (false, error); - } - - bson_destroy (&reply); - mongoc_client_destroy (client); - - return count; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_data_nodes_count -- - * - * Returns the number of replica set members (excluding arbiters), - * or number of mongos servers or 1 for a standalone. - * - *-------------------------------------------------------------------------- - */ - -size_t -test_framework_data_nodes_count (void) -{ - bson_t reply; - bson_iter_t iter, array; - size_t count = 0; - - - call_ismaster (&reply); - if (!bson_iter_init_find (&iter, &reply, "hosts")) { - bson_destroy (&reply); - return test_framework_mongos_count (); - } - - BSON_ASSERT (bson_iter_recurse (&iter, &array)); - while (bson_iter_next (&array)) { - ++count; - } - - bson_destroy (&reply); - - return count; -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_server_count -- - * - * Returns the number of mongos servers or replica set members, - * or 1 if the server is standalone. - * - *-------------------------------------------------------------------------- - */ -size_t -test_framework_server_count (void) -{ - size_t count = 0; - - count = test_framework_replset_member_count (); - if (count > 0) { - return count; - } - - return test_framework_mongos_count (); -} - -/* - *-------------------------------------------------------------------------- - * - * test_framework_set_ssl_opts -- - * - * Configure a client to connect to the test MongoDB server. - * - * Returns: - * None. - * - * Side effects: - * Logs and aborts if any MONGOC_TEST_SSL_* environment variables are - * set but the driver is not built with SSL enabled. - * - *-------------------------------------------------------------------------- - */ -void -test_framework_set_ssl_opts (mongoc_client_t *client) -{ - BSON_ASSERT (client); - - if (test_framework_get_ssl ()) { -#ifndef MONGOC_ENABLE_SSL - fprintf (stderr, - "SSL test config variables are specified in the environment, but" - " SSL isn't enabled\n"); - abort (); -#else - mongoc_client_set_ssl_opts (client, &gSSLOptions); -#endif - } -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_client_new -- - * - * Get a client connected to the test MongoDB topology. - * - * Returns: - * A client you must mongoc_client_destroy. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -mongoc_client_t * -test_framework_client_new () -{ - char *test_uri_str = test_framework_get_uri_str (); - mongoc_client_t *client = mongoc_client_new (test_uri_str); - - BSON_ASSERT (client); - test_framework_set_ssl_opts (client); - - bson_free (test_uri_str); - - return client; -} - - -#ifdef MONGOC_ENABLE_SSL -/* - *-------------------------------------------------------------------------- - * - * test_framework_get_ssl_opts -- - * - * Get options for connecting to mongod over SSL (even if mongod - * isn't actually SSL-enabled). - * - * Returns: - * A pointer to constant global SSL-test options. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -const mongoc_ssl_opt_t * -test_framework_get_ssl_opts (void) -{ - return &gSSLOptions; -} -#endif - -/* - *-------------------------------------------------------------------------- - * - * test_framework_set_pool_ssl_opts -- - * - * Configure a client pool to connect to the test MongoDB server. - * - * Returns: - * None. - * - * Side effects: - * Logs and aborts if any MONGOC_TEST_SSL_* environment variables are - * set but the driver is not built with SSL enabled. - * - *-------------------------------------------------------------------------- - */ -void -test_framework_set_pool_ssl_opts (mongoc_client_pool_t *pool) -{ - BSON_ASSERT (pool); - - if (test_framework_get_ssl ()) { -#ifndef MONGOC_ENABLE_SSL - fprintf (stderr, - "SSL test config variables are specified in the environment, but" - " SSL isn't enabled\n"); - abort (); -#else - mongoc_client_pool_set_ssl_opts (pool, &gSSLOptions); -#endif - } -} - - -/* - *-------------------------------------------------------------------------- - * - * test_framework_client_pool_new -- - * - * Get a client pool connected to the test MongoDB topology. - * - * Returns: - * A pool you must destroy. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -mongoc_client_pool_t * -test_framework_client_pool_new () -{ - mongoc_uri_t *test_uri = test_framework_get_uri (); - mongoc_client_pool_t *pool = mongoc_client_pool_new (test_uri); - - BSON_ASSERT (pool); - test_framework_set_pool_ssl_opts (pool); - - mongoc_uri_destroy (test_uri); - BSON_ASSERT (pool); - return pool; -} - -#ifdef MONGOC_ENABLE_SSL -static void -test_framework_global_ssl_opts_init (void) -{ - memcpy (&gSSLOptions, mongoc_ssl_opt_get_default (), sizeof gSSLOptions); - - gSSLOptions.pem_file = test_framework_getenv ("MONGOC_TEST_SSL_PEM_FILE"); - gSSLOptions.pem_pwd = test_framework_getenv ("MONGOC_TEST_SSL_PEM_PWD"); - gSSLOptions.ca_file = test_framework_getenv ("MONGOC_TEST_SSL_CA_FILE"); - gSSLOptions.ca_dir = test_framework_getenv ("MONGOC_TEST_SSL_CA_DIR"); - gSSLOptions.crl_file = test_framework_getenv ("MONGOC_TEST_SSL_CRL_FILE"); - gSSLOptions.weak_cert_validation = - test_framework_getenv_bool ("MONGOC_TEST_SSL_WEAK_CERT_VALIDATION"); -} - -static void -test_framework_global_ssl_opts_cleanup (void) -{ - bson_free ((void *) gSSLOptions.pem_file); - bson_free ((void *) gSSLOptions.pem_pwd); - bson_free ((void *) gSSLOptions.ca_file); - bson_free ((void *) gSSLOptions.ca_dir); - bson_free ((void *) gSSLOptions.crl_file); -} -#endif - - -bool -test_framework_is_mongos (void) -{ - bson_t reply; - bson_iter_t iter; - bool is_mongos; - - call_ismaster (&reply); - - is_mongos = (bson_iter_init_find (&iter, &reply, "msg") && - BSON_ITER_HOLDS_UTF8 (&iter) && - !strcasecmp (bson_iter_utf8 (&iter, NULL), "isdbgrid")); - - bson_destroy (&reply); - - return is_mongos; -} - - -bool -test_framework_is_replset (void) -{ - return test_framework_replset_member_count () > 0; -} - -bool -test_framework_server_is_secondary (mongoc_client_t *client, uint32_t server_id) -{ - bson_t reply; - bson_iter_t iter; - mongoc_server_description_t *sd; - bson_error_t error; - bool ret; - - sd = mongoc_topology_server_by_id (client->topology, server_id, &error); - ASSERT_OR_PRINT (sd, error); - - call_ismaster_with_host_and_port (sd->host.host_and_port, &reply); - - ret = bson_iter_init_find (&iter, &reply, "secondary") && - bson_iter_as_bool (&iter); - - bson_destroy (&reply); - - mongoc_server_description_destroy (sd); - - return ret; -} - - -bool -test_framework_clustertime_supported (void) -{ - bson_t reply; - bool has_cluster_time; - - call_ismaster (&reply); - has_cluster_time = bson_has_field (&reply, "$clusterTime"); - bson_destroy (&reply); - - return has_cluster_time && - test_framework_max_wire_version_at_least (WIRE_VERSION_OP_MSG); -} - - -int64_t -test_framework_session_timeout_minutes (void) -{ - bson_t reply; - bson_iter_t iter; - int64_t timeout = -1; - - if (!TestSuite_CheckLive ()) { - return -1; - } - - call_ismaster (&reply); - if (bson_iter_init_find (&iter, &reply, "logicalSessionTimeoutMinutes")) { - timeout = bson_iter_as_int64 (&iter); - } - - bson_destroy (&reply); - - return timeout; -} - - -void -test_framework_get_max_wire_version (int64_t *max_version) -{ - bson_t reply; - bson_iter_t iter; - - call_ismaster (&reply); - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "maxWireVersion")); - *max_version = bson_iter_as_int64 (&iter); - - bson_destroy (&reply); -} - -static bool -_test_framework_has_auth (void) -{ - char *user; - -#ifndef MONGOC_ENABLE_SSL - /* requires SSL for SCRAM implementation, can't test auth */ - return false; -#endif - - /* checks if the MONGOC_TEST_USER env var is set */ - user = test_framework_get_admin_user (); - bson_free (user); - if (user) { - return true; - } else { - return false; - } -} - - -int -test_framework_skip_if_auth (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - - if (_test_framework_has_auth ()) { - return 0; - } - - return 1; -} - - -int -test_framework_skip_if_no_auth (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - - if (!_test_framework_has_auth ()) { - return 0; - } - - return 1; -} - -static bool -_test_framework_has_crypto (void) -{ -#ifdef MONGOC_ENABLE_CRYPTO - return true; -#else - return false; -#endif -} - -int -test_framework_skip_if_no_sessions (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - - if (!_test_framework_has_crypto ()) { - return 0; - } - - return -1 != test_framework_session_timeout_minutes (); -} - - -int -test_framework_skip_if_no_cluster_time (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - - return test_framework_clustertime_supported () ? 1 : 0; -} - - -int -test_framework_skip_if_crypto (void) -{ - return _test_framework_has_crypto () ? 0 : 1; -} - - -int -test_framework_skip_if_no_crypto (void) -{ - return test_framework_skip_if_crypto () ? 0 : 1; -} - - -int -test_framework_skip_if_offline (void) -{ - return test_framework_getenv_bool ("MONGOC_TEST_OFFLINE") ? 0 : 1; -} - - -int -test_framework_skip_if_slow (void) -{ - return test_framework_getenv_bool ("MONGOC_TEST_SKIP_SLOW") ? 0 : 1; -} - - -int -test_framework_skip_if_slow_or_live (void) -{ - return test_framework_skip_if_slow () && TestSuite_CheckLive (); -} - - -int -test_framework_skip_if_valgrind (void) -{ - return test_suite_valgrind () ? 0 : 1; -} - - -int -test_framework_skip_if_windows (void) -{ -#ifdef _WIN32 - return false; -#else - return true; -#endif -} - - -/* skip if no Unix domain socket */ -int -test_framework_skip_if_no_uds (void) -{ -#ifdef _WIN32 - return 0; -#else - char *path; - int ret; - - if (!TestSuite_CheckLive ()) { - return 0; - } - - path = test_framework_get_unix_domain_socket_path (); - ret = access (path, R_OK | W_OK) == 0 ? 1 : 0; - - bson_free (path); - - return ret; -#endif -} - - -int -test_framework_skip_if_no_txns (void) -{ - if (test_framework_skip_if_no_crypto () && - test_framework_skip_if_no_sessions () && - test_framework_skip_if_not_replset () && - test_framework_skip_if_max_wire_version_less_than_7 ()) { - return 1; - } - - if (test_framework_skip_if_no_crypto () && - test_framework_skip_if_no_sessions () && - test_framework_skip_if_not_mongos () && - test_framework_skip_if_max_wire_version_less_than_8 ()) { - return 1; - } - - /* transactions not supported, skip the test */ - return 0; -} - - -bool -test_framework_max_wire_version_at_least (int version) -{ - int64_t max_version; - - BSON_ASSERT (version > 0); - test_framework_get_max_wire_version (&max_version); - return max_version >= version; -} - - -int64_t -test_framework_max_write_batch_size (void) -{ - bson_t reply; - bson_iter_t iter; - int64_t size; - - call_ismaster (&reply); - - if (bson_iter_init_find (&iter, &reply, "maxWriteBatchSize")) { - size = bson_iter_as_int64 (&iter); - } else { - size = 1000; - } - - bson_destroy (&reply); - - return size; -} - -#define N_SERVER_VERSION_PARTS 4 - -static server_version_t -_parse_server_version (const bson_t *buildinfo) -{ - bson_iter_t iter; - bson_iter_t array_iter; - int i; - server_version_t ret = 0; - - ASSERT (bson_iter_init_find (&iter, buildinfo, "versionArray")); - ASSERT (bson_iter_recurse (&iter, &array_iter)); - - /* Server returns a 4-part version like [3, 2, 0, 0], or like [3, 2, 0, -49] - * for an RC. Bail if number of parts is ever not 4. */ - i = 0; - while (bson_iter_next (&array_iter)) { - ret *= 1000; - ret += 100 + bson_iter_as_int64 (&array_iter); - i++; - ASSERT_CMPINT (i, <=, N_SERVER_VERSION_PARTS); - } - - ASSERT_CMPINT (i, ==, N_SERVER_VERSION_PARTS); - - return ret; -} - -server_version_t -test_framework_get_server_version (void) -{ - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - server_version_t ret = 0; - - client = test_framework_client_new (); - ASSERT_OR_PRINT ( - mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'buildinfo': 1}"), NULL, &reply, &error), - error); - - ret = _parse_server_version (&reply); - - bson_destroy (&reply); - mongoc_client_destroy (client); - - return ret; -} - -server_version_t -test_framework_str_to_version (const char *version_str) -{ - char *str_copy; - char *part; - char *end; - int i; - server_version_t ret = 0; - - str_copy = bson_strdup (version_str); - i = 0; - part = strtok (str_copy, "."); - while (part) { - ret *= 1000; - - /* add 100 since release candidates have versions like "3.2.0.-49" */ - ret += 100 + bson_ascii_strtoll (part, &end, 10); - i++; - ASSERT_CMPINT (i, <=, N_SERVER_VERSION_PARTS); - part = strtok (NULL, "."); - } - - /* pad out a short version like "3.0" */ - for (; i < N_SERVER_VERSION_PARTS; i++) { - ret *= 1000; - ret += 100; - } - - bson_free (str_copy); - - return ret; -} - -/* self-tests for a test framework feature */ -static void -test_version_cmp (void) -{ - server_version_t v2_6_12 = 102106112100; - server_version_t v3_0_0 = 103100100100; - server_version_t v3_0_1 = 103100101100; - server_version_t v3_0_10 = 103100110100; - server_version_t v3_2_0_rc1_pre = 103102100051; - - ASSERT (v2_6_12 == test_framework_str_to_version ("2.6.12")); - ASSERT (v2_6_12 == _parse_server_version ( - tmp_bson ("{'versionArray': [2, 6, 12, 0]}"))); - - ASSERT (v3_0_0 == test_framework_str_to_version ("3")); - ASSERT (v3_0_0 == - _parse_server_version (tmp_bson ("{'versionArray': [3, 0, 0, 0]}"))); - - ASSERT (v3_0_1 == test_framework_str_to_version ("3.0.1")); - ASSERT (v3_0_1 == - _parse_server_version (tmp_bson ("{'versionArray': [3, 0, 1, 0]}"))); - - ASSERT (v3_0_10 == test_framework_str_to_version ("3.0.10")); - ASSERT (v3_0_10 == _parse_server_version ( - tmp_bson ("{'versionArray': [3, 0, 10, 0]}"))); - - ASSERT (v3_2_0_rc1_pre == test_framework_str_to_version ("3.2.0.-49")); - ASSERT (v3_2_0_rc1_pre == _parse_server_version ( - tmp_bson ("{'versionArray': [3, 2, 0, -49]}"))); - - ASSERT (v3_2_0_rc1_pre > test_framework_str_to_version ("3.1.9")); - ASSERT (v3_2_0_rc1_pre < test_framework_str_to_version ("3.2")); -} - -int -test_framework_skip_if_single (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return (test_framework_is_mongos () || test_framework_is_replset ()); -} - -int -test_framework_skip_if_mongos (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return test_framework_is_mongos () ? 0 : 1; -} - -int -test_framework_skip_if_replset (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return test_framework_is_replset () ? 0 : 1; -} - -int -test_framework_skip_if_not_single (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return !test_framework_skip_if_single (); -} - -int -test_framework_skip_if_not_mongos (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return !test_framework_skip_if_mongos (); -} - -int -test_framework_skip_if_not_replset (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return !test_framework_skip_if_replset (); -} - -/* convenience skip functions based on the wire version. */ -#define WIRE_VERSION_CHECKS(wv) \ - int test_framework_skip_if_max_wire_version_more_than_##wv () \ - { \ - if (!TestSuite_CheckLive ()) { \ - return 0; \ - } \ - return test_framework_max_wire_version_at_least (wv + 1) ? 0 : 1; \ - } \ - int test_framework_skip_if_max_wire_version_less_than_##wv () \ - { \ - if (!TestSuite_CheckLive ()) { \ - return 0; \ - } \ - return test_framework_max_wire_version_at_least (wv); \ - } \ - int test_framework_skip_if_not_rs_version_##wv (void) \ - { \ - if (!TestSuite_CheckLive ()) { \ - return 0; \ - } \ - return (test_framework_max_wire_version_at_least (wv) && \ - test_framework_is_replset ()) \ - ? 1 \ - : 0; \ - } \ - int test_framework_skip_if_rs_version_##wv (void) \ - { \ - if (!TestSuite_CheckLive ()) { \ - return 0; \ - } \ - return (test_framework_max_wire_version_at_least (wv) && \ - test_framework_is_replset ()) \ - ? 0 \ - : 1; \ - } - -WIRE_VERSION_CHECKS (3) -WIRE_VERSION_CHECKS (4) -WIRE_VERSION_CHECKS (5) -WIRE_VERSION_CHECKS (6) -WIRE_VERSION_CHECKS (7) -WIRE_VERSION_CHECKS (8) - -int -test_framework_skip_if_no_dual_ip_hostname (void) -{ - struct addrinfo hints = {0}, *res = NULL, *iter; - int res_count = 0; - char *host = test_framework_getenv ("MONGOC_TEST_IPV4_AND_IPV6_HOST"); - bool needs_free = false; - if (host) { - needs_free = true; - } else { - host = "localhost"; - } - - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = 0; - hints.ai_protocol = 0; - - BSON_ASSERT (getaddrinfo (host, "27017", &hints, &res) != -1); - - iter = res; - - while (iter) { - res_count++; - iter = iter->ai_next; - } - - freeaddrinfo (res); - if (needs_free) { - bson_free (host); - } - - ASSERT_CMPINT (res_count, >, 0); - return res_count > 1; -} - -int -test_framework_skip_if_no_compressors (void) -{ - char *compressors = test_framework_get_compressors (); - bool ret = compressors != NULL; - bson_free (compressors); - return ret; -} - -int -test_framework_skip_if_compressors (void) -{ - return !test_framework_skip_if_no_compressors (); -} - -int -test_framework_skip_if_no_failpoint (void) -{ - mongoc_client_t *client; - bool ret; - bson_error_t error; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - ret = mongoc_client_command_simple ( - client, - "admin", - tmp_bson ("{'configureFailPoint': 'failCommand', 'mode': 'off', 'data': " - "{'errorCode': 10107, 'failCommands': ['count']}}"), - NULL, - NULL, - &error); - mongoc_client_destroy (client); - - if (!ret) { - return 0; /* do not proceed */ - } - - /* proceed. */ - return 1; -} - -int -test_framework_skip_if_no_client_side_encryption (void) -{ - char *aws_secret_access_key; - char *aws_access_key_id; - bool has_creds; - - aws_secret_access_key = - test_framework_getenv ("MONGOC_TEST_AWS_SECRET_ACCESS_KEY"); - aws_access_key_id = test_framework_getenv ("MONGOC_TEST_AWS_ACCESS_KEY_ID"); - - has_creds = (NULL != aws_secret_access_key) && (NULL != aws_access_key_id); - - bson_free (aws_secret_access_key); - bson_free (aws_access_key_id); - - if (has_creds) { -#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION - return 1; /* 1 == proceed. */ -#else - return 0; /* 0 == do not proceed. */ -#endif - } - return 0; /* 0 == do not proceed. */ - } - -void -test_framework_resolve_path (const char *path, char *resolved) -{ - if (!realpath (path, resolved)) { - MONGOC_ERROR ("Cannot resolve path %s\n", path); - MONGOC_ERROR ("Run test-libmongoc in repository root directory.\n"); - ASSERT (false); - } -} - -static char MONGOC_TEST_UNIQUE[32]; - -int -main (int argc, char *argv[]) -{ - TestSuite suite; - int ret; - - mongoc_init (); - - bson_snprintf (MONGOC_TEST_UNIQUE, - sizeof MONGOC_TEST_UNIQUE, - "test_%u_%u", - (unsigned) time (NULL), - (unsigned) gettestpid ()); - - bson_mutex_init (&captured_logs_mutex); - _mongoc_array_init (&captured_logs, sizeof (log_entry_t *)); - mongoc_log_set_handler (log_handler, (void *) &suite); - -#ifdef MONGOC_ENABLE_SSL - test_framework_global_ssl_opts_init (); - atexit (test_framework_global_ssl_opts_cleanup); -#endif - - TestSuite_Init (&suite, "", argc, argv); - TestSuite_Add (&suite, "/TestSuite/version_cmp", test_version_cmp); - - /* libbson */ - - test_atomic_install (&suite); - test_bcon_basic_install (&suite); - test_bcon_extract_install (&suite); - test_bson_corpus_install (&suite); - test_bson_error_install (&suite); - test_bson_install (&suite); - test_bson_version_install (&suite); - test_clock_install (&suite); - test_decimal128_install (&suite); - test_endian_install (&suite); - test_iso8601_install (&suite); - test_iter_install (&suite); - test_json_install (&suite); - test_oid_install (&suite); - test_reader_install (&suite); - test_string_install (&suite); - test_utf8_install (&suite); - test_value_install (&suite); - test_writer_install (&suite); - - /* libmongoc */ - - test_aggregate_install (&suite); - test_array_install (&suite); - test_async_install (&suite); - test_buffer_install (&suite); - test_change_stream_install (&suite); - test_client_install (&suite); - test_client_max_staleness_install (&suite); - test_client_pool_install (&suite); - test_write_command_install (&suite); - test_bulk_install (&suite); - test_cluster_install (&suite); - test_collection_install (&suite); - test_collection_find_install (&suite); - test_collection_find_with_opts_install (&suite); - test_connection_uri_install (&suite); - test_command_monitoring_install (&suite); - test_cursor_install (&suite); - test_database_install (&suite); - test_error_install (&suite); - test_exhaust_install (&suite); - test_find_and_modify_install (&suite); - test_gridfs_install (&suite); - test_gridfs_bucket_install (&suite); - test_gridfs_file_page_install (&suite); - test_handshake_install (&suite); - test_linux_distro_scanner_install (&suite); - test_list_install (&suite); - test_log_install (&suite); - test_matcher_install (&suite); - test_mongos_pinning_install (&suite); - test_queue_install (&suite); - test_primary_stepdown_install (&suite); - test_read_concern_install (&suite); - test_read_write_concern_install (&suite); - test_read_prefs_install (&suite); - test_retryable_writes_install (&suite); - test_retryable_reads_install (&suite); - test_rpc_install (&suite); - test_socket_install (&suite); - test_opts_install (&suite); - test_topology_scanner_install (&suite); - test_topology_reconcile_install (&suite); - test_transactions_install (&suite); - test_samples_install (&suite); - test_scram_install (&suite); - test_sdam_install (&suite); - test_sdam_monitoring_install (&suite); - test_server_selection_install (&suite); - test_dns_install (&suite); - test_server_selection_errors_install (&suite); - test_session_install (&suite); - test_set_install (&suite); - test_stream_install (&suite); - test_thread_install (&suite); - test_topology_install (&suite); - test_topology_description_install (&suite); - test_uri_install (&suite); - test_usleep_install (&suite); - test_util_install (&suite); - test_version_install (&suite); - test_with_transaction_install (&suite); - test_write_concern_install (&suite); -#ifdef MONGOC_ENABLE_SSL - test_stream_tls_install (&suite); - test_x509_install (&suite); - test_stream_tls_error_install (&suite); -#endif -#ifdef MONGOC_ENABLE_SASL_CYRUS - test_cyrus_install (&suite); -#endif - test_happy_eyeballs_install (&suite); - test_counters_install (&suite); - test_crud_install (&suite); - test_apm_install (&suite); - test_client_side_encryption_install (&suite); - - ret = TestSuite_Run (&suite); - - TestSuite_Destroy (&suite); - - capture_logs (false); /* clear entries */ - _mongoc_array_destroy (&captured_logs); - mongoc_cleanup (); - - return ret; -} diff --git a/lib/mongoc/libmongoc/tests/test-libmongoc.h b/lib/mongoc/libmongoc/tests/test-libmongoc.h deleted file mode 100644 index a1acbeb8233ff748375528ccde3f1efdf72421a3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-libmongoc.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2013 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 TEST_LIBMONGOC_H -#define TEST_LIBMONGOC_H - - -mongoc_database_t * -get_test_database (mongoc_client_t *client); -char * -gen_collection_name (const char *prefix); -mongoc_collection_t * -get_test_collection (mongoc_client_t *client, const char *prefix); -void -capture_logs (bool capture); -void -clear_captured_logs (void); -bool -has_captured_log (mongoc_log_level_t level, const char *msg); -void -assert_all_captured_logs_have_prefix (const char *prefix); -bool -has_captured_logs (void); -void -print_captured_logs (const char *prefix); -int64_t -get_future_timeout_ms (void); -char * -test_framework_getenv (const char *name); -bool -test_framework_getenv_bool (const char *name); -int64_t -test_framework_getenv_int64 (const char *name, int64_t default_value); -char * -test_framework_get_host (void); -uint16_t -test_framework_get_port (void); -char * -test_framework_get_host_and_port (void); -char * -test_framework_get_admin_user (void); -char * -test_framework_get_admin_password (void); -bool -test_framework_get_ssl (void); -char * -test_framework_add_user_password (const char *uri_str, - const char *user, - const char *password); -char * -test_framework_add_user_password_from_env (const char *uri_str); -char * -test_framework_get_uri_str_no_auth (const char *database_name); -char * -test_framework_get_uri_str (void); -char * -test_framework_get_unix_domain_socket_uri_str (void); -char * -test_framework_get_unix_domain_socket_path_escaped (void); -mongoc_uri_t * -test_framework_get_uri (void); -size_t -test_framework_mongos_count (void); -char * -test_framework_replset_name (void); -size_t -test_framework_replset_member_count (void); -size_t -test_framework_data_nodes_count (void); -size_t -test_framework_server_count (void); - -#ifdef MONGOC_ENABLE_SSL -const mongoc_ssl_opt_t * -test_framework_get_ssl_opts (void); -#endif -void -test_framework_set_ssl_opts (mongoc_client_t *client); -void -test_framework_set_pool_ssl_opts (mongoc_client_pool_t *pool); -mongoc_client_t * -test_framework_client_new (void); -mongoc_client_pool_t * -test_framework_client_pool_new (void); - -bool -test_framework_is_mongos (void); -bool -test_framework_is_replset (void); -bool -test_framework_server_is_secondary (mongoc_client_t *client, - uint32_t server_id); -int64_t -test_framework_session_timeout_minutes (void); -void -test_framework_get_max_wire_version (int64_t *max_version); -bool -test_framework_clustertime_supported (void); -bool -test_framework_max_wire_version_at_least (int version); -int64_t -test_framework_max_write_batch_size (void); - -int -test_framework_skip_if_auth (void); -int -test_framework_skip_if_no_auth (void); -int -test_framework_skip_if_no_sessions (void); -int -test_framework_skip_if_no_cluster_time (void); -int -test_framework_skip_if_crypto (void); -int -test_framework_skip_if_no_crypto (void); -int -test_framework_skip_if_mongos (void); -int -test_framework_skip_if_replset (void); -int -test_framework_skip_if_single (void); -int -test_framework_skip_if_windows (void); -int -test_framework_skip_if_no_uds (void); /* skip if no Unix domain socket */ -int -test_framework_skip_if_no_txns (void); -int -test_framework_skip_if_not_mongos (void); -int -test_framework_skip_if_not_replset (void); -int -test_framework_skip_if_not_single (void); -int -test_framework_skip_if_offline (void); -int -test_framework_skip_if_slow (void); -int -test_framework_skip_if_slow_or_live (void); -int -test_framework_skip_if_valgrind (void); - -#define WIRE_VERSION_CHECK_DECLS(wv) \ - int test_framework_skip_if_max_wire_version_less_than_##wv (void); \ - int test_framework_skip_if_max_wire_version_more_than_##wv (void); \ - int test_framework_skip_if_rs_version_##wv (void); \ - int test_framework_skip_if_not_rs_version_##wv (void); - -WIRE_VERSION_CHECK_DECLS (3) -WIRE_VERSION_CHECK_DECLS (4) -WIRE_VERSION_CHECK_DECLS (5) -WIRE_VERSION_CHECK_DECLS (6) -WIRE_VERSION_CHECK_DECLS (7) -WIRE_VERSION_CHECK_DECLS (8) - -#undef WIRE_VERSION_CHECK_DECLS - -typedef struct _debug_stream_stats_t { - mongoc_client_t *client; - int n_destroyed; - int n_failed; -} debug_stream_stats_t; - -void -test_framework_set_debug_stream (mongoc_client_t *client, - debug_stream_stats_t *stats); - -typedef int64_t server_version_t; - -server_version_t -test_framework_get_server_version (void); -server_version_t -test_framework_str_to_version (const char *version_str); - -int -test_framework_skip_if_no_dual_ip_hostname (void); - -char * -test_framework_get_compressors (void); - -int -test_framework_skip_if_no_compressors (void); - -int -test_framework_skip_if_compressors (void); - -int -test_framework_skip_if_no_failpoint (void); - -int -test_framework_skip_if_no_client_side_encryption (void); - -void -test_framework_resolve_path (const char *path, char *resolved); - -#endif diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-aggregate.c b/lib/mongoc/libmongoc/tests/test-mongoc-aggregate.c deleted file mode 100644 index 59387e4dd600da74c347cf949fa178e9a99d7848..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-aggregate.c +++ /dev/null @@ -1,103 +0,0 @@ -#include <mongoc/mongoc.h> -#include "mongoc/mongoc-client-private.h" - -#include "TestSuite.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "test-conveniences.h" - -static void -_test_query_flag (mongoc_query_flags_t flag, bson_t *opt) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - future_t *future; - request_t *request; - const bson_t *doc; - - server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_aggregate ( - collection, flag, tmp_bson ("{'pipeline': []}"), opt, NULL); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - /* "aggregate" command */ - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_msg (server, - MONGOC_QUERY_NONE, - tmp_bson ("{'aggregate': 'collection'," - " 'pipeline': [ ]," - " 'tailable': {'$exists': false}}")); - ASSERT (request); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '123'}," - " 'ns': 'db.collection'," - " 'nextBatch': [{}]}}"); - ASSERT (future_get_bool (future)); - request_destroy (request); - future_destroy (future); - - /* "getMore" command */ - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_msg (server, - MONGOC_QUERY_NONE, - tmp_bson ("{'getMore': {'$numberLong': '123'}," - " 'collection': 'collection'," - " 'tailable': {'$exists': false}}")); - ASSERT (request); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '0'}," - " 'ns': 'db.collection'," - " 'nextBatch': [{}]}}"); - - ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_query_flags (void) -{ - int i; - - typedef struct { - mongoc_query_flags_t flag; - bson_t *opt; - } flag_and_opt_t; - - flag_and_opt_t flags_and_opts[] = { - {MONGOC_QUERY_TAILABLE_CURSOR, tmp_bson ("{'tailable': true}")}, - {MONGOC_QUERY_TAILABLE_CURSOR | MONGOC_QUERY_AWAIT_DATA, - tmp_bson ("{'tailable': true, 'awaitData': true}")}}; - - /* test with both flag and opt */ - for (i = 0; i < (sizeof flags_and_opts) / (sizeof (flag_and_opt_t)); i++) { - _test_query_flag (flags_and_opts[i].flag, NULL); - _test_query_flag (MONGOC_QUERY_NONE, flags_and_opts[i].opt); - } -} - -void -test_aggregate_install (TestSuite *suite) -{ - TestSuite_AddMockServerTest ( - suite, "/Aggregate/query_flags", test_query_flags); -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-array.c b/lib/mongoc/libmongoc/tests/test-mongoc-array.c deleted file mode 100644 index cd4ff71eb68b7c60059ffcba63e9be89965f618e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-array.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "mongoc/mongoc-array-private.h" -#include "TestSuite.h" - - -static void -test_array (void) -{ - mongoc_array_t ar; - int i; - int v; - - _mongoc_array_init (&ar, sizeof i); - BSON_ASSERT (ar.element_size == sizeof i); - BSON_ASSERT (ar.len == 0); - BSON_ASSERT (ar.allocated); - BSON_ASSERT (ar.data); - - for (i = 0; i < 100; i++) { - _mongoc_array_append_val (&ar, i); - } - - for (i = 0; i < 100; i++) { - v = _mongoc_array_index (&ar, int, i); - BSON_ASSERT (v == i); - } - - BSON_ASSERT (ar.len == 100); - BSON_ASSERT (ar.allocated >= (100 * sizeof i)); - - _mongoc_array_clear (&ar); - BSON_ASSERT (ar.len == 0); - BSON_ASSERT (ar.allocated); - BSON_ASSERT (ar.data); - BSON_ASSERT (ar.element_size); - - _mongoc_array_destroy (&ar); -} - - -void -test_array_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Array/Basic", test_array); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-async.c b/lib/mongoc/libmongoc/tests/test-mongoc-async.c deleted file mode 100644 index f186ae39a08bbae4919df2c57d097c09e59dc3ea..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-async.c +++ /dev/null @@ -1,382 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-client-private.h> - -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-async-private.h" -#include "mongoc/mongoc-async-cmd-private.h" -#include "TestSuite.h" -#include "mock_server/mock-server.h" -#include "mock_server/future-functions.h" -#include "mongoc/mongoc-errno-private.h" -#include "test-libmongoc.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "async-test" - -#define TIMEOUT 10000 /* milliseconds */ -#define NSERVERS 10 - -struct result { - int32_t server_id; - bool finished; -}; - -static mongoc_stream_t * -get_localhost_stream (uint16_t port) -{ - int errcode; - int r; - struct sockaddr_in server_addr = {0}; - mongoc_socket_t *conn_sock; - conn_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (conn_sock); - - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons (port); - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - r = mongoc_socket_connect ( - conn_sock, (struct sockaddr *) &server_addr, sizeof (server_addr), 0); - - errcode = mongoc_socket_errno (conn_sock); - if (!(r == 0 || MONGOC_ERRNO_IS_AGAIN (errcode))) { - fprintf (stderr, - "mongoc_socket_connect unexpected return: " - "%d (errno: %d)\n", - r, - errcode); - fflush (stderr); - abort (); - } - - return mongoc_stream_socket_new (conn_sock); -} - - -static void -test_ismaster_helper (mongoc_async_cmd_t *acmd, - mongoc_async_cmd_result_t result, - const bson_t *bson, - int64_t duration_usec) -{ - struct result *r = (struct result *) acmd->data; - bson_iter_t iter; - bson_error_t *error = &acmd->error; - - /* ignore the connected event. */ - if (result == MONGOC_ASYNC_CMD_CONNECTED) { - return; - } - - if (result != MONGOC_ASYNC_CMD_SUCCESS) { - fprintf (stderr, "error: %s\n", error->message); - } - ASSERT_CMPINT (result, ==, MONGOC_ASYNC_CMD_SUCCESS); - - BSON_ASSERT (bson_iter_init_find (&iter, bson, "serverId")); - BSON_ASSERT (BSON_ITER_HOLDS_INT32 (&iter)); - r->server_id = bson_iter_int32 (&iter); - r->finished = true; -} - - -static void -test_ismaster_impl (bool with_ssl) -{ - mock_server_t *servers[NSERVERS]; - mongoc_async_t *async; - mongoc_stream_t *sock_streams[NSERVERS]; - mongoc_async_cmd_setup_t setup = NULL; - void *setup_ctx = NULL; - uint16_t ports[NSERVERS]; - struct result results[NSERVERS]; - int i; - int offset; - int server_id; - bson_t q = BSON_INITIALIZER; - future_t *future; - request_t *request; - char *reply; - -#ifdef MONGOC_ENABLE_SSL - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; -#endif - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - BSON_ASSERT (bson_append_int32 (&q, "isMaster", 8, 1)); - - for (i = 0; i < NSERVERS; i++) { - servers[i] = mock_server_new (); - -#ifdef MONGOC_ENABLE_SSL - if (with_ssl) { - sopt.weak_cert_validation = true; - sopt.pem_file = CERT_SERVER; - sopt.ca_file = CERT_CA; - - mock_server_set_ssl_opts (servers[i], &sopt); - } -#endif - - ports[i] = mock_server_run (servers[i]); - } - - async = mongoc_async_new (); - - for (i = 0; i < NSERVERS; i++) { - sock_streams[i] = get_localhost_stream (ports[i]); - -#ifdef MONGOC_ENABLE_SSL - if (with_ssl) { - copt.ca_file = CERT_CA; - copt.weak_cert_validation = 1; - - sock_streams[i] = mongoc_stream_tls_new_with_hostname ( - sock_streams[i], NULL, &copt, 1); - setup = mongoc_async_cmd_tls_setup; - setup_ctx = (void *) "127.0.0.1"; - } -#endif - - results[i].finished = false; - - mongoc_async_cmd_new (async, - sock_streams[i], - false, - NULL /* dns result, n/a. */, - NULL, /* initiator. */ - 0, /* initiate delay. */ - setup, - setup_ctx, - "admin", - &q, - &test_ismaster_helper, - (void *) &results[i], - TIMEOUT); - } - - future = future_async_run (async); - - /* start in the middle - prove scanner handles replies in any order */ - offset = NSERVERS / 2; - for (i = 0; i < NSERVERS; i++) { - server_id = (i + offset) % NSERVERS; - request = mock_server_receives_command ( - servers[server_id], "admin", MONGOC_QUERY_SLAVE_OK, NULL); - - /* use "serverId" field to distinguish among responses */ - reply = bson_strdup_printf ("{'ok': 1," - " 'ismaster': true," - " 'minWireVersion': 0," - " 'maxWireVersion': 1000," - " 'serverId': %d}", - server_id); - - mock_server_replies_simple (request, reply); - bson_free (reply); - request_destroy (request); - } - - BSON_ASSERT (future_wait (future)); - - for (i = 0; i < NSERVERS; i++) { - if (!results[i].finished) { - fprintf (stderr, "command %d not finished\n", i); - abort (); - } - - ASSERT_CMPINT (i, ==, results[i].server_id); - } - - mongoc_async_destroy (async); - future_destroy (future); - bson_destroy (&q); - - for (i = 0; i < NSERVERS; i++) { - mock_server_destroy (servers[i]); - mongoc_stream_destroy (sock_streams[i]); - } -} - -static void -test_ismaster (void) -{ - test_ismaster_impl (false); -} - - -#if defined(MONGOC_ENABLE_SSL_OPENSSL) -static void -test_ismaster_ssl (void) -{ - test_ismaster_impl (true); -} -#else - -static void -test_large_ismaster_helper (mongoc_async_cmd_t *acmd, - mongoc_async_cmd_result_t result, - const bson_t *bson, - int64_t duration_usec) -{ - bson_iter_t iter; - bson_error_t *error = &acmd->error; - - /* ignore the connected event. */ - if (result == MONGOC_ASYNC_CMD_CONNECTED) { - return; - } - - if (result != MONGOC_ASYNC_CMD_SUCCESS) { - fprintf (stderr, "error: %s\n", error->message); - } - ASSERT_CMPINT (result, ==, MONGOC_ASYNC_CMD_SUCCESS); - - BSON_ASSERT (bson_iter_init_find (&iter, bson, "ismaster")); - BSON_ASSERT (BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)); -} - -static void -test_large_ismaster (void *ctx) -{ - mongoc_async_t *async; - mongoc_stream_t *sock_stream; - int i = 0; - bson_t q = BSON_INITIALIZER; - -#ifdef MONGOC_ENABLE_SSL - mongoc_ssl_opt_t ssl_opts; -#endif - - /* Inflate the size of the isMaster message with other fields to ~1MB. - * mongod should ignore them, but this tests that CDRIVER-2483 is fixed. - */ - BSON_ASSERT (bson_append_int32 (&q, "isMaster", 8, 1)); - while (q.len < 1024 * 1024) { - char buf[11]; - bson_snprintf (buf, sizeof (buf), "key_%06d", i++); - BSON_APPEND_INT32 (&q, buf, 0); - } - - sock_stream = get_localhost_stream (test_framework_get_port ()); - -#ifdef MONGOC_ENABLE_SSL - if (test_framework_get_ssl ()) { - ssl_opts = *test_framework_get_ssl_opts (); - sock_stream = - mongoc_stream_tls_new_with_hostname (sock_stream, NULL, &ssl_opts, 1); - } -#endif - - async = mongoc_async_new (); - mongoc_async_cmd_new (async, - sock_stream, - false, /* is setup done. */ - NULL /* dns result, n/a. */, - NULL, /* initiator. */ - 0, /* initiate delay. */ -#ifdef MONGOC_ENABLE_SSL - test_framework_get_ssl () ? mongoc_async_cmd_tls_setup - : NULL, -#else - NULL, -#endif - NULL, - "admin", - &q, - &test_large_ismaster_helper, - NULL, - TIMEOUT); - - mongoc_async_run (async); - mongoc_async_destroy (async); - mongoc_stream_destroy (sock_stream); - bson_destroy (&q); -} -#endif - -typedef struct _stream_with_result_t { - mongoc_stream_t *stream; - bool finished; -} stream_with_result_t; - -static void -test_ismaster_delay_callback (mongoc_async_cmd_t *acmd, - mongoc_async_cmd_result_t result, - const bson_t *bson, - int64_t duration_usec) -{ - ((stream_with_result_t *) acmd->data)->finished = true; -} - -static mongoc_stream_t * -test_ismaster_delay_initializer (mongoc_async_cmd_t *acmd) -{ - return ((stream_with_result_t *) acmd->data)->stream; -} - -static void -test_ismaster_delay () -{ - /* test that a delayed cmd works. */ - mock_server_t *server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mongoc_async_t *async = mongoc_async_new (); - bson_t ismaster_cmd = BSON_INITIALIZER; - stream_with_result_t stream_with_result = {0}; - int64_t start = bson_get_monotonic_time (); - - mock_server_run (server); - - stream_with_result.stream = - get_localhost_stream (mock_server_get_port (server)); - stream_with_result.finished = false; - - BSON_ASSERT (bson_append_int32 (&ismaster_cmd, "isMaster", 8, 1)); - mongoc_async_cmd_new (async, - NULL, /* stream, initialized after delay. */ - false, /* is setup done. */ - NULL, /* dns result. */ - test_ismaster_delay_initializer, - 100, /* delay 100ms. */ - NULL, /* setup function. */ - NULL, /* setup ctx. */ - "admin", - &ismaster_cmd, - &test_ismaster_delay_callback, - &stream_with_result, - TIMEOUT); - - mongoc_async_run (async); - - /* it should have taken at least 100ms to finish. */ - ASSERT_CMPINT64 ( - bson_get_monotonic_time () - start, >, (int64_t) (100 * 1000)); - BSON_ASSERT (stream_with_result.finished); - - bson_destroy (&ismaster_cmd); - mongoc_stream_destroy (stream_with_result.stream); - mongoc_async_destroy (async); - mock_server_destroy (server); -} - -void -test_async_install (TestSuite *suite) -{ - TestSuite_AddMockServerTest (suite, "/Async/ismaster", test_ismaster); -#if defined(MONGOC_ENABLE_SSL_OPENSSL) - TestSuite_AddMockServerTest ( - suite, "/Async/ismaster_ssl", test_ismaster_ssl); -#else - /* Skip this test on OpenSSL since was having issues connecting. */ - TestSuite_AddFull (suite, - "/Async/large_ismaster", - test_large_ismaster, - NULL /* dtor */, - NULL /* ctx */, - test_framework_skip_if_not_single); -#endif - TestSuite_AddMockServerTest (suite, "/Async/delay", test_ismaster_delay); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-buffer.c b/lib/mongoc/libmongoc/tests/test-mongoc-buffer.c deleted file mode 100644 index 3874b76997a6749a9aaa6729c9ed156cf704ff9b..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-buffer.c +++ /dev/null @@ -1,42 +0,0 @@ -#include <fcntl.h> -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-buffer-private.h> - -#include "TestSuite.h" - - -static void -test_mongoc_buffer_basic (void) -{ - mongoc_stream_t *stream; - mongoc_buffer_t buf; - bson_error_t error = {0}; - uint8_t *data = (uint8_t *) bson_malloc0 (1024); - ssize_t r; - - stream = - mongoc_stream_file_new_for_path (BINARY_DIR "/reply1.dat", O_RDONLY, 0); - ASSERT (stream); - - _mongoc_buffer_init (&buf, data, 1024, NULL, NULL); - - r = _mongoc_buffer_fill (&buf, stream, 537, 0, &error); - ASSERT_CMPINT ((int) r, ==, -1); - r = _mongoc_buffer_fill (&buf, stream, 536, 0, &error); - ASSERT_CMPINT ((int) r, ==, 536); - ASSERT (buf.len == 536); - - _mongoc_buffer_destroy (&buf); - _mongoc_buffer_destroy (&buf); - _mongoc_buffer_destroy (&buf); - _mongoc_buffer_destroy (&buf); - - mongoc_stream_destroy (stream); -} - - -void -test_buffer_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Buffer/Basic", test_mongoc_buffer_basic); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-bulk.c b/lib/mongoc/libmongoc/tests/test-mongoc-bulk.c deleted file mode 100644 index 6c375e50a47e18257563841fc56d471bb899d324..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-bulk.c +++ /dev/null @@ -1,4910 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-bulk-operation-private.h> -#include <mongoc/mongoc-client-private.h> -#include <mongoc/mongoc-cursor-private.h> -#include <mongoc/mongoc-collection-private.h> -#include <mongoc/mongoc-util-private.h> - -#include "TestSuite.h" - -#include "test-libmongoc.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" -#include "test-conveniences.h" -#include "mock_server/mock-rs.h" - - -typedef void (*update_fn) (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - bool upsert); - -typedef bool (*update_with_opts_fn) (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *document, - const bson_t *opts, - bson_error_t *error); - -/*-------------------------------------------------------------------------- - * - * assert_error_count -- - * - * Check the length of a bulk operation reply's writeErrors. - * - * Returns: - * None. - * - * Side effects: - * Aborts if the array is the wrong length. - * - *-------------------------------------------------------------------------- - */ - -static void -assert_error_count (int len, const bson_t *reply) -{ - bson_iter_t iter; - bson_iter_t error_iter; - int n = 0; - - BSON_ASSERT (bson_iter_init_find (&iter, reply, "writeErrors")); - BSON_ASSERT (bson_iter_recurse (&iter, &error_iter)); - while (bson_iter_next (&error_iter)) { - n++; - } - ASSERT_CMPINT (len, ==, n); -} - - -/*-------------------------------------------------------------------------- - * - * assert_n_inserted -- - * - * Check a bulk operation reply's nInserted field. - * - * Returns: - * None. - * - * Side effects: - * Aborts if the field is incorrect. - * - *-------------------------------------------------------------------------- - */ - -static void -assert_n_inserted (int n, const bson_t *reply) -{ - bson_iter_t iter; - - BSON_ASSERT (bson_iter_init_find (&iter, reply, "nInserted")); - BSON_ASSERT (BSON_ITER_HOLDS_INT32 (&iter)); - ASSERT_CMPINT (n, ==, bson_iter_int32 (&iter)); -} - - -/*-------------------------------------------------------------------------- - * - * oid_created_on_client -- - * - * Check that a document's _id contains this process's pid. - * - * Returns: - * True or false. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -static bool -oid_created_on_client (const bson_t *doc) -{ - bson_oid_t new_oid; - const uint8_t *new_pid; - bson_iter_t iter; - const bson_oid_t *oid; - const uint8_t *pid; - - bson_oid_init (&new_oid, NULL); - new_pid = &new_oid.bytes[7]; - - bson_iter_init_find (&iter, doc, "_id"); - - if (!BSON_ITER_HOLDS_OID (&iter)) { - return false; - } - - oid = bson_iter_oid (&iter); - pid = &oid->bytes[7]; - - return 0 == memcmp (pid, new_pid, 2); -} - - -static void -create_unique_index (mongoc_collection_t *collection) -{ - mongoc_index_opt_t opt; - bson_error_t error; - - mongoc_index_opt_init (&opt); - opt.unique = true; - - BEGIN_IGNORE_DEPRECATIONS - ASSERT_OR_PRINT (mongoc_collection_create_index ( - collection, tmp_bson ("{'a': 1}"), &opt, &error), - error); - END_IGNORE_DEPRECATIONS -} - - -static void -test_bulk (void) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - bson_t reply; - bson_t child; - bson_t del; - bson_t up; - bson_t doc = BSON_INITIALIZER; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_bulk"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - mongoc_bulk_operation_insert (bulk, &doc); - mongoc_bulk_operation_insert (bulk, &doc); - mongoc_bulk_operation_insert (bulk, &doc); - mongoc_bulk_operation_insert (bulk, &doc); - - bson_init (&up); - bson_append_document_begin (&up, "$set", -1, &child); - bson_append_int32 (&child, "hello", -1, 123); - bson_append_document_end (&up, &child); - mongoc_bulk_operation_update (bulk, &doc, &up, false); - bson_destroy (&up); - - bson_init (&del); - BSON_APPEND_INT32 (&del, "hello", 123); - mongoc_bulk_operation_remove (bulk, &del); - bson_destroy (&del); - - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 4," - " 'nMatched': 4," - " 'nModified': 4," - " 'nRemoved': 4," - " 'nUpserted': 0," - " 'writeErrors': []}"); - - ASSERT_COUNT (0, collection); - - bson_destroy (&reply); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&doc); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -_test_opt (const char *opts_json, const char *msg) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_bulk"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts ( - collection, tmp_bson (opts_json)); - BSON_ASSERT (bulk); - - BSON_ASSERT (!mongoc_bulk_operation_insert_with_opts ( - bulk, tmp_bson ("{}"), NULL, &error)); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, msg); - - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_opts (void) -{ - _test_opt ("{'foo': 1}", "Invalid option 'foo'"); - _test_opt ("{'writeConcern': 1}", "Invalid writeConcern"); - _test_opt ("{'writeConcern': {'w': 0, 'j': 1}}", "Invalid writeConcern"); - _test_opt ("{'sessionId': 'hi'}", "Invalid sessionId"); - _test_opt ("{'sessionId': 101}", "Invalid sessionId"); - _test_opt ("{'ordered': 'yes'}", - "Invalid field \"ordered\" in opts, should contain bool"); -} - - -static void -test_bulk_error (void) -{ - bson_t reply = {0}; - bson_error_t error; - mongoc_bulk_operation_t *bulk; - mock_server_t *mock_server; - mongoc_client_t *client; - - mock_server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (mock_server); - client = mongoc_client_new_from_uri (mock_server_get_uri (mock_server)); - - bulk = mongoc_bulk_operation_new (true); - mongoc_bulk_operation_set_client (bulk, client); - BSON_ASSERT (!mongoc_bulk_operation_execute (bulk, &reply, &error)); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_COMMAND_INVALID_ARG); - - /* reply was initialized */ - ASSERT_CMPUINT32 (reply.len, ==, (uint32_t) 5); - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_client_destroy (client); - mock_server_destroy (mock_server); -} - - -static void -test_bulk_error_unordered (void) -{ - mock_server_t *mock_server; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - request_t *request; - future_t *future; - int i; - mongoc_uri_t *uri; - - if (test_suite_valgrind ()) { - bson_destroy (&opts); - return; - } - mock_server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (mock_server); - - uri = mongoc_uri_copy (mock_server_get_uri (mock_server)); - mongoc_uri_set_option_as_int32 (uri, "sockettimeoutms", 500); - client = mongoc_client_new_from_uri (uri); - mongoc_uri_destroy (uri); - collection = mongoc_client_get_collection (client, "test", "test"); - - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - for (i = 0; i <= 2048; i++) { - mongoc_bulk_operation_update_many_with_opts ( - bulk, - tmp_bson ("{'hello': 'earth'}"), - tmp_bson ("{'$set': {'hello': 'world'}}"), - NULL, - &error); - } - - future = future_bulk_operation_execute (bulk, &reply, &error); - - request = - mock_server_receives_command (mock_server, - "test", - MONGOC_QUERY_NONE, - "{'update': 'test'," - " 'writeConcern': {'$exists': false}," - " 'ordered': false}", - NULL); - mock_server_replies_simple (request, "{ 'ok' : 1, 'n' : 5 }"); - - request_destroy (request); - request = - mock_server_receives_command (mock_server, - "test", - MONGOC_QUERY_NONE, - "{'update': 'test'," - " 'writeConcern': {'$exists': false}," - " 'ordered': false}", - NULL); - - request_destroy (request); - mock_server_destroy (mock_server); - - future_wait_max (future, 100); - ASSERT (!future_value_get_uint32_t (&future->return_value)); - future_destroy (future); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "socket error or timeout"); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 5," - " 'nRemoved': 0," - " 'nUpserted': 0}"); - - bson_destroy (&reply); - bson_destroy (&opts); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_insert (bool ordered) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - bson_t reply; - bson_t opts = BSON_INITIALIZER; - bson_t doc = BSON_INITIALIZER; - bson_t query = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - const bson_t *inserted_doc; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_insert"); - BSON_ASSERT (collection); - - bson_append_bool (&opts, "ordered", 7, ordered); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - BSON_ASSERT (bulk->flags.ordered == ordered); - - mongoc_bulk_operation_insert (bulk, &doc); - mongoc_bulk_operation_insert (bulk, &doc); - - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 2," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 0}"); - - bson_destroy (&reply); - ASSERT_COUNT (2, collection); - - cursor = mongoc_collection_find_with_opts (collection, &query, NULL, NULL); - BSON_ASSERT (cursor); - - while (mongoc_cursor_next (cursor, &inserted_doc)) { - BSON_ASSERT (oid_created_on_client (inserted_doc)); - } - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_cursor_destroy (cursor); - bson_destroy (&query); - bson_destroy (&opts); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&doc); -} - - -static void -test_insert_ordered (void) -{ - test_insert (true); -} - - -static void -test_insert_unordered (void) -{ - test_insert (false); -} - - -static void -test_insert_check_keys (void) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - bool r; - - capture_logs (true); - - client = test_framework_client_new (); - BSON_ASSERT (client); - collection = get_test_collection (client, "test_insert_check_keys"); - BSON_ASSERT (collection); - - /* keys can't start with "$" */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'$dollar': 1}")); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "keys cannot begin with \"$\": \"$dollar\""); - - BSON_ASSERT (bson_empty (&reply)); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - - /* valid, then invalid */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - mongoc_bulk_operation_insert (bulk, tmp_bson (NULL)); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'$dollar': 1}")); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "keys cannot begin with \"$\": \"$dollar\""); - - BSON_ASSERT (bson_empty (&reply)); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - - /* keys can't contain "." */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'a.b': 1}")); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "keys cannot contain \".\": \"a.b\""); - - BSON_ASSERT (bson_empty (&reply)); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_upsert (bool ordered) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - - bson_error_t error; - bson_t reply; - bson_t *sel; - bson_t *doc; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_upsert"); - BSON_ASSERT (collection); - - bson_append_bool (&opts, "ordered", 7, ordered); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - sel = tmp_bson ("{'_id': 1234}"); - doc = tmp_bson ("{'$set': {'hello': 'there'}}"); - - mongoc_bulk_operation_update (bulk, sel, doc, true); - - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 1," - " 'upserted': [{'index': 0, '_id': 1234}]," - " 'writeErrors': []}"); - - ASSERT_COUNT (1, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - /* non-upsert, no matches */ - sel = tmp_bson ("{'_id': 2}"); - doc = tmp_bson ("{'$set': {'hello': 'there'}}"); - - mongoc_bulk_operation_update (bulk, sel, doc, false); - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'upserted': {'$exists': false}," - " 'writeErrors': []}"); - - ASSERT_COUNT (1, collection); /* doc remains from previous operation */ - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_upsert_ordered (void) -{ - test_upsert (true); -} - - -static void -test_upsert_unordered (void) -{ - test_upsert (false); -} - - -static void -test_upsert_unordered_oversized (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t *u; - bool r; - bson_error_t error; - bson_t reply; - - client = test_framework_client_new (); - collection = get_test_collection (client, "upsert_oversized"); - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - - /* much too large */ - u = tmp_bson ("{'$set': {'x': '%s', 'y': '%s'}}", - huge_string (client), - huge_string (client)); - - r = mongoc_bulk_operation_update_one_with_opts ( - bulk, tmp_bson (NULL), u, tmp_bson ("{'upsert': true}"), &error); - - ASSERT_OR_PRINT (r, error); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Document 0 is too large"); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': []}"); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_upserted_index (bool ordered) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - - bson_error_t error; - bson_t reply; - bson_t *emp = tmp_bson ("{}"); - bson_t *inc = tmp_bson ("{'$inc': {'b': 1}}"); - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_upserted_index"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - mongoc_bulk_operation_insert (bulk, emp); - mongoc_bulk_operation_insert (bulk, emp); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'i': 2}")); - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 3}"), inc, false); - /* upsert */ - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 4}"), inc, true); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'i': 5}")); - mongoc_bulk_operation_remove_one (bulk, tmp_bson ("{'i': 6}")); - mongoc_bulk_operation_replace_one (bulk, tmp_bson ("{'i': 7}"), emp, false); - /* upsert */ - mongoc_bulk_operation_replace_one (bulk, tmp_bson ("{'i': 8}"), emp, true); - /* upsert */ - mongoc_bulk_operation_replace_one (bulk, tmp_bson ("{'i': 9}"), emp, true); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'i': 10}")); - mongoc_bulk_operation_insert (bulk, emp); - mongoc_bulk_operation_insert (bulk, emp); - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 13}"), inc, false); - /* upsert */ - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 14}"), inc, true); - mongoc_bulk_operation_insert (bulk, emp); - /* upserts */ - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 16}"), inc, true); - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 17}"), inc, true); - /* non-upsert */ - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 18}"), inc, false); - /* upserts */ - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 19}"), inc, true); - mongoc_bulk_operation_replace_one (bulk, tmp_bson ("{'i': 20}"), emp, true); - mongoc_bulk_operation_replace_one (bulk, tmp_bson ("{'i': 21}"), emp, true); - mongoc_bulk_operation_replace_one (bulk, tmp_bson ("{'i': 22}"), emp, true); - mongoc_bulk_operation_update (bulk, tmp_bson ("{'i': 23}"), inc, true); - /* non-upsert */ - mongoc_bulk_operation_update_one (bulk, tmp_bson ("{'i': 24}"), inc, false); - /* upsert */ - mongoc_bulk_operation_update_one (bulk, tmp_bson ("{'i': 25}"), inc, true); - /* non-upserts */ - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'i': 26}")); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'i': 27}")); - mongoc_bulk_operation_update_one (bulk, tmp_bson ("{'i': 28}"), inc, false); - mongoc_bulk_operation_update_one (bulk, tmp_bson ("{'i': 29}"), inc, false); - /* each update modifies existing 16 docs, but only increments index by one */ - mongoc_bulk_operation_update (bulk, emp, inc, false); - mongoc_bulk_operation_update (bulk, emp, inc, false); - /* upsert */ - mongoc_bulk_operation_update_one (bulk, tmp_bson ("{'i': 32}"), inc, true); - - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - fprintf (stderr, "bulk failed: %s\n", error.message); - abort (); - } - - ASSERT_MATCH (&reply, - "{'nInserted': 5," - " 'nMatched': 34," - " 'nModified': 34," - " 'nRemoved': 0," - " 'nUpserted': 13," - " 'upserted': [" - " {'index': 4}," - " {'index': 8}," - " {'index': 9}," - " {'index': 14}," - " {'index': 16}," - " {'index': 17}," - " {'index': 19}," - " {'index': 20}," - " {'index': 21}," - " {'index': 22}," - " {'index': 23}," - " {'index': 25}," - " {'index': 32}" - " ]," - " 'writeErrors': []}"); - - ASSERT_COUNT (18, collection); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_upserted_index_ordered (void) -{ - test_upserted_index (true); -} - - -static void -test_upserted_index_unordered (void) -{ - test_upserted_index (false); -} - - -static void -test_update_one (bool ordered) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - - bson_error_t error; - bson_t reply; - bson_t *sel; - bson_t *doc; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_update_one"); - BSON_ASSERT (collection); - - doc = bson_new (); - r = mongoc_collection_insert_one (collection, doc, NULL, NULL, NULL); - BSON_ASSERT (r); - r = mongoc_collection_insert_one (collection, doc, NULL, NULL, NULL); - BSON_ASSERT (r); - bson_destroy (doc); - - bson_append_bool (&opts, "ordered", 7, ordered); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - sel = tmp_bson ("{}"); - doc = tmp_bson ("{'$set': {'hello': 'there'}}"); - mongoc_bulk_operation_update_one (bulk, sel, doc, true); - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 1," - " 'nModified': 1," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'upserted': {'$exists': false}," - " 'writeErrors': []}"); - - ASSERT_COUNT (2, collection); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_update_one_ordered (void) -{ - test_update_one (true); -} - - -static void -test_update_one_unordered (void) -{ - test_update_one (false); -} - - -static void -test_update_with_opts_validate (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - update_with_opts_fn fns[] = { - mongoc_bulk_operation_update_one_with_opts, - mongoc_bulk_operation_update_many_with_opts, - }; - int i; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_update_with_opts_validate"); - - for (i = 0; i < 2; i++) { - update_with_opts_fn update_function; - - update_function = fns[i]; - bulk = - mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (!update_function ( - bulk, tmp_bson ("{}"), tmp_bson ("{'a.a': 1}"), NULL, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "update only works with $ operators"); - - BSON_ASSERT ( - update_function (bulk, - tmp_bson ("{}"), - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_NONE), - &error)); - BSON_ASSERT (!update_function ( - bulk, - tmp_bson ("{}"), - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_DOT_KEYS), - &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid argument for update: keys cannot contain \".\": \"a.a\""); - mongoc_bulk_operation_destroy (bulk); - - /* Test a valid update_one with explicit validation on the server. */ - bulk = - mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT ( - update_function (bulk, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'a': 1}}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_DOT_KEYS), - &error)); - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, NULL, &error), - error); - mongoc_bulk_operation_destroy (bulk); - } - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -/* Tests that documents in `coll` found with `selector` all match `match` */ -static void -_test_docs_in_coll_matches (mongoc_collection_t *coll, - bson_t *selector, - const char *match, - uint32_t expected_count) -{ - const bson_t *next_doc; - mongoc_cursor_t *cursor = - mongoc_collection_find_with_opts (coll, selector, NULL, NULL); - while (expected_count > 0) { - ASSERT (mongoc_cursor_next (cursor, &next_doc)); - if (match) { - ASSERT_MATCH (next_doc, match); - } - --expected_count; - } - ASSERT_CMPINT (expected_count, ==, 0); - mongoc_cursor_destroy (cursor); -} - - -static void -test_update_arrayfilters (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - - bson_error_t err; - bson_t reply; - bool ret = false; - int i; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_update_arrayfilters"); - BSON_ASSERT (collection); - - mongoc_collection_drop (collection, NULL); - - bson_append_bool (&opts, "ordered", 7, true); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - for (i = 1; i < 4; i++) { - ret = mongoc_bulk_operation_insert_with_opts ( - bulk, - tmp_bson ("{'_id': %d, 'a': [{'x':1}, {'x':2}]}", i), - NULL, - &err); - ASSERT_OR_PRINT (ret, err); - } - - ret = mongoc_bulk_operation_update_one_with_opts ( - bulk, - tmp_bson ("{'_id': 1}"), - tmp_bson ("{'$set': {'a.$[i].x': 3}}"), - tmp_bson ("{'arrayFilters': [{'i.x': {'$gt': 1}}]}"), - &err); - ASSERT_OR_PRINT (ret, err); - - ret = mongoc_bulk_operation_update_many_with_opts ( - bulk, - tmp_bson ("{'_id': {'$gt': 1}}"), - tmp_bson ("{'$set': {'a.$[i].x': 4}}"), - tmp_bson ("{'arrayFilters': [{'i.x': {'$gt': 1}}]}"), - &err); - ASSERT_OR_PRINT (ret, err); - - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &err), - err); - - ASSERT_MATCH (&reply, - "{'nInserted': 3," - " 'nMatched': 3," - " 'nModified': 3," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'upserted': {'$exists': false}," - " 'writeErrors': []}"); - bson_destroy (&reply); - - ASSERT_COUNT (3, collection); - - _test_docs_in_coll_matches ( - collection, tmp_bson ("{'_id':1}"), "{'a': [{'x':1}, {'x':3}]}", 1); - - _test_docs_in_coll_matches ( - collection, tmp_bson ("{'_id':2}"), "{'a': [{'x':1}, {'x':4}]}", 1); - - _test_docs_in_coll_matches ( - collection, tmp_bson ("{'_id':3}"), "{'a': [{'x':1}, {'x':4}]}", 1); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &err), err); - - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_update_arrayfilters_unsupported (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_error_t err; - bool ret; - int i; - - update_with_opts_fn fns[] = { - mongoc_bulk_operation_update_one_with_opts, - mongoc_bulk_operation_update_many_with_opts, - }; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_update_arrayfilters_err"); - - for (i = 0; i < 2; i++) { - bulk = - mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - ret = fns[i](bulk, - tmp_bson ("{'_id': 1}"), - tmp_bson ("{'$set': {'a.$[i].x': 3}}"), - tmp_bson ("{'arrayFilters': [{'i.x': {'$gt': 1}}]}"), - &err); - - /* adding the updateOne/updateMany operation to the bulk succeeds */ - ASSERT_OR_PRINT (ret, err); - - ret = mongoc_bulk_operation_execute (bulk, NULL, &err) > 0; - BSON_ASSERT (!ret); - ASSERT_ERROR_CONTAINS ( - err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support array filters"); - - mongoc_bulk_operation_destroy (bulk); - } - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_replace_one (bool ordered) -{ - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - - bson_error_t error; - bson_t reply; - bson_t *sel; - bson_t *doc; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_replace_one"); - BSON_ASSERT (collection); - - doc = bson_new (); - r = mongoc_collection_insert_one (collection, doc, NULL, NULL, NULL); - BSON_ASSERT (r); - r = mongoc_collection_insert_one (collection, doc, NULL, NULL, NULL); - BSON_ASSERT (r); - bson_destroy (doc); - - bson_append_bool (&opts, "ordered", 7, ordered); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - sel = tmp_bson ("{}"); - doc = tmp_bson ("{'hello': 'there'}"); - mongoc_bulk_operation_replace_one (bulk, sel, doc, true); - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 1," - " 'nModified': 1," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'upserted': {'$exists': false}," - " 'writeErrors': []}"); - - ASSERT_COUNT (2, collection); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -_test_replace_one_check_keys (bool with_opts) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - - bson_error_t error; - bson_t reply; - bool r; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_replace_one_check_keys"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - if (with_opts) { - /* rejected immediately */ - r = mongoc_bulk_operation_replace_one_with_opts ( - bulk, tmp_bson ("{}"), tmp_bson ("{'$a': 1}"), NULL, &error); - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "keys cannot begin with \"$\": \"$a\""); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "empty bulk write"); - } else { - /* rejected during execute() */ - capture_logs (true); - mongoc_bulk_operation_replace_one ( - bulk, tmp_bson ("{}"), tmp_bson ("{'$a': 1}"), true); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "keys cannot begin with \"$\": \"$a\""); - } - - ASSERT (bson_empty (&reply)); - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_replace_one_check_keys (void) -{ - _test_replace_one_check_keys (false); -} - - -static void -test_replace_one_with_opts_check_keys (void) -{ - _test_replace_one_check_keys (true); -} - - -static void -test_replace_one_with_opts_validate (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_replace_with_opts_validate"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - BSON_ASSERT (!mongoc_bulk_operation_replace_one_with_opts ( - bulk, tmp_bson ("{}"), tmp_bson ("{'a.a': 1}"), NULL, &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid argument for replace: keys cannot contain \".\": \"a.a\""); - - BSON_ASSERT (mongoc_bulk_operation_replace_one_with_opts ( - bulk, - tmp_bson ("{}"), - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_NONE), - &error)); - BSON_ASSERT (mongoc_bulk_operation_replace_one_with_opts ( - bulk, - tmp_bson ("{}"), - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_UTF8), - &error)); - BSON_ASSERT (!mongoc_bulk_operation_replace_one_with_opts ( - bulk, - tmp_bson ("{}"), - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_DOT_KEYS), - &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid argument for replace: keys cannot contain \".\": \"a.a\""); - - mongoc_bulk_operation_destroy (bulk); - - /* Test a valid replace_one with explicit validation on the server. */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (mongoc_bulk_operation_replace_one_with_opts ( - bulk, - tmp_bson ("{}"), - tmp_bson ("{'a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_DOT_KEYS), - &error)); - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, NULL, &error), error); - mongoc_bulk_operation_destroy (bulk); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -/* - * check that we include command overhead in msg size when deciding to split, - * CDRIVER-1082 - */ -static void -test_upsert_large (void *ctx) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_t *selector = tmp_bson ("{'_id': 'aaaaaaaaaa'}"); - size_t sz = 8396692; /* a little over 8 MB */ - char *large_str = bson_malloc (sz); - bson_t update = BSON_INITIALIZER; - bson_t child; - bson_error_t error; - int i; - bson_t reply; - - memset (large_str, 'a', sz); - large_str[sz - 1] = '\0'; - client = test_framework_client_new (); - collection = get_test_collection (client, "test_upsert_large"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - bson_append_document_begin (&update, "$set", 4, &child); - bson_append_utf8 (&child, "big", 3, large_str, (int) sz - 1); - bson_append_document_end (&update, &child); - - /* two 8MB+ docs could fit in 16MB + 16K, if not for command overhead, - * check the driver splits into two msgs */ - for (i = 0; i < 2; i++) { - mongoc_bulk_operation_update (bulk, selector, &update, true); - } - - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 1," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 1," - " 'upserted': [{'index': 0, '_id': 'aaaaaaaaaa'}]," - " 'writeErrors': []}"); - - ASSERT_COUNT (1, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&update); - bson_free (large_str); -} - - -static void -test_upsert_huge (void *ctx) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_t *sel = tmp_bson ("{'_id': 1}"); - bson_t doc = BSON_INITIALIZER; - bson_t child; - bson_t query = BSON_INITIALIZER; - const bson_t *retdoc; - bson_error_t error; - bson_t reply; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - BSON_ASSERT (client); - mongoc_client_set_error_api (client, 2); - - collection = get_test_collection (client, "test_upsert_huge"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - bson_append_document_begin (&doc, "$set", -1, &child); - BSON_ASSERT (bson_append_utf8 (&child, - "x", - -1, - huge_string (client), - (int) huge_string_length (client))); - bson_append_document_end (&doc, &child); - - mongoc_bulk_operation_update (bulk, sel, &doc, true); - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 1," - " 'upserted': [{'index': 0, '_id': 1}]," - " 'writeErrors': []}"); - - ASSERT_COUNT (1, collection); - - cursor = mongoc_collection_find_with_opts (collection, &query, NULL, NULL); - ASSERT_CURSOR_NEXT (cursor, &retdoc); - ASSERT_CURSOR_DONE (cursor); - - bson_destroy (&child); - bson_destroy (&query); - bson_destroy (&reply); - bson_destroy (&doc); - mongoc_cursor_destroy (cursor); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_replace_one_ordered (void) -{ - test_replace_one (true); -} - - -static void -test_replace_one_unordered (void) -{ - test_replace_one (false); -} - - -static void -test_update (bool ordered) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *docs_inserted[] = { - tmp_bson ("{'a': 1}"), - tmp_bson ("{'a': 2}"), - tmp_bson ("{'a': 3, 'foo': 'bar'}"), - }; - unsigned int i; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t reply; - bson_t *sel; - bson_t *bad_update_doc = tmp_bson ("{'foo': 'bar'}"); - bson_t *update_doc; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_update"); - BSON_ASSERT (collection); - - for (i = 0; i < sizeof docs_inserted / sizeof (bson_t *); i++) { - BSON_ASSERT (mongoc_collection_insert_one ( - collection, docs_inserted[i], NULL, NULL, NULL)); - } - - bson_append_bool (&opts, "ordered", 7, ordered); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - /* an update doc without $-operators is rejected */ - sel = tmp_bson ("{'a': {'$gte': 2}}"); - capture_logs (true); - mongoc_bulk_operation_update (bulk, sel, bad_update_doc, false); - - BSON_ASSERT (!mongoc_bulk_operation_execute (bulk, &reply, &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid key 'foo': update only works with $ operators"); - - BSON_ASSERT (bson_empty (&reply)); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&reply); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - update_doc = tmp_bson ("{'$set': {'foo': 'bar'}}"); - mongoc_bulk_operation_update (bulk, sel, update_doc, false); - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 2," - " 'nModified': 1," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'upserted': {'$exists': false}," - " 'writeErrors': []}"); - - /* one doc already had "foo": "bar" */ - ASSERT_COUNT (3, collection); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - bson_destroy (&reply); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_update_ordered (void) -{ - test_update (true); -} - - -static void -test_update_unordered (void) -{ - test_update (false); -} - - -/* update document has key that doesn't start with "$" */ -static void -_test_update_check_keys (bool many, bool with_opts) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_t *q = tmp_bson ("{}"); - bson_t *u = tmp_bson ("{'a': 1}"); - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - collection = get_test_collection (client, "test_update_check_keys"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - capture_logs (true); - - if (with_opts) { - /* document is rejected immediately */ - if (many) { - r = mongoc_bulk_operation_update_many_with_opts ( - bulk, q, u, NULL, &error); - } else { - r = mongoc_bulk_operation_update_one_with_opts ( - bulk, q, u, NULL, &error); - } - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid key 'a': update only works with $ operators"); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "empty bulk"); - } else { - /* document rejected when bulk op is executed */ - if (many) { - mongoc_bulk_operation_update (bulk, q, u, false); - } else { - mongoc_bulk_operation_update_one (bulk, q, u, false); - } - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid key 'a': update only works with $ operators"); - } - - BSON_ASSERT (bson_empty (&reply)); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_update_one_check_keys (void) -{ - _test_update_check_keys (false, false); -} - - -static void -test_update_check_keys (void) -{ - _test_update_check_keys (true, false); -} - - -static void -test_update_one_with_opts_check_keys (void) -{ - _test_update_check_keys (false, true); -} - - -static void -test_update_many_with_opts_check_keys (void) -{ - _test_update_check_keys (true, true); -} - - -typedef struct { - const char *bad_update_json; - const char *good_update_json; - update_fn update; - update_with_opts_fn update_with_opts; - bool invalid_first; - const char *error_message; -} update_validate_test_t; - - -static void -_test_update_validate (update_validate_test_t *test) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_t *q = tmp_bson ("{}"); - bson_t *bad_update = tmp_bson (test->bad_update_json); - bson_t *good_update = tmp_bson (test->good_update_json); - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - collection = get_test_collection (client, "test_update_invalid_first"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - capture_logs (true); - - if (test->update_with_opts) { - if (test->invalid_first) { - /* document is rejected immediately */ - r = test->update_with_opts (bulk, q, bad_update, NULL, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - test->error_message); - - /* now a valid document */ - r = test->update_with_opts (bulk, q, good_update, NULL, &error); - ASSERT_OR_PRINT (r, error); - ASSERT_CMPSIZE_T ((size_t) 1, ==, bulk->commands.len); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!bson_empty (&reply)); - } else { - /* first a valid document */ - r = test->update_with_opts (bulk, q, good_update, NULL, &error); - ASSERT_OR_PRINT (r, error); - - /* invalid document is rejected without invalidating batch */ - r = test->update_with_opts (bulk, q, bad_update, NULL, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - test->error_message); - - ASSERT_CMPSIZE_T ((size_t) 1, ==, bulk->commands.len); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!bson_empty (&reply)); - } - } else { - if (test->invalid_first) { - /* invalid, then valid */ - test->update (bulk, q, bad_update, false); - test->update (bulk, q, good_update, false); - - /* not added */ - ASSERT_CMPSIZE_T ((size_t) 0, ==, bulk->commands.len); - - /* invalid document invalidated the whole bulk */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - BSON_ASSERT (bson_empty (&reply)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - test->error_message); - } else { - /* valid, then invalid */ - test->update (bulk, q, good_update, false); - test->update (bulk, q, bad_update, false); - - ASSERT_CMPSIZE_T ((size_t) 1, ==, bulk->commands.len); - - /* invalid document invalidated the whole bulk */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - BSON_ASSERT (bson_empty (&reply)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - test->error_message); - } - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -_test_update_one_invalid (bool first) -{ - update_validate_test_t test = {0}; - test.bad_update_json = "{'a': 1}"; - test.good_update_json = "{'$set': {'x': 1}}"; - test.update = mongoc_bulk_operation_update_one; - test.update_with_opts = NULL; - test.invalid_first = first; - test.error_message = "Invalid key 'a': update only works with $ operators"; - - _test_update_validate (&test); -} - - -static void -_test_update_invalid (bool first) -{ - update_validate_test_t test = {0}; - test.bad_update_json = "{'a': 1}"; - test.good_update_json = "{'$set': {'x': 1}}"; - test.update = mongoc_bulk_operation_update; - test.update_with_opts = NULL; - test.invalid_first = first; - test.error_message = "Invalid key 'a': update only works with $ operators"; - - _test_update_validate (&test); -} - - -static void -_test_update_one_with_opts_invalid (bool first) -{ - update_validate_test_t test = {0}; - test.bad_update_json = "{'a': 1}"; - test.good_update_json = "{'$set': {'x': 1}}"; - test.update = NULL; - test.update_with_opts = mongoc_bulk_operation_update_one_with_opts; - test.invalid_first = first; - test.error_message = "Invalid key 'a': update only works with $ operators"; - - _test_update_validate (&test); -} - - -static void -_test_update_many_with_opts_invalid (bool first) -{ - update_validate_test_t test = {0}; - test.bad_update_json = "{'a': 1}"; - test.good_update_json = "{'$set': {'x': 1}}"; - test.update = NULL; - test.update_with_opts = mongoc_bulk_operation_update_many_with_opts; - test.invalid_first = first; - test.error_message = "Invalid key 'a': update only works with $ operators"; - - _test_update_validate (&test); -} - - -static void -_test_replace_one_invalid (bool first) -{ - update_validate_test_t test = {0}; - test.bad_update_json = "{'$set': {'x': 1}}"; - test.good_update_json = "{'a': 1}"; - test.update = mongoc_bulk_operation_replace_one; - test.update_with_opts = NULL; - test.invalid_first = first; - test.error_message = "keys cannot begin with \"$\": \"$set\""; - - _test_update_validate (&test); -} - - -static void -_test_replace_one_with_opts_invalid (bool first) -{ - update_validate_test_t test = {0}; - test.bad_update_json = "{'$set': {'x': 1}}"; - test.good_update_json = "{'a': 1}"; - test.update = NULL; - test.update_with_opts = mongoc_bulk_operation_replace_one_with_opts; - test.invalid_first = first; - test.error_message = "keys cannot begin with \"$\": \"$set\""; - - _test_update_validate (&test); -} - - -static void -test_update_one_invalid_first (void) -{ - _test_update_one_invalid (true /* invalid first */); -} - - -static void -test_update_invalid_first (void) -{ - _test_update_invalid (true /* invalid first */); -} - - -static void -test_update_one_with_opts_invalid_first (void) -{ - _test_update_one_with_opts_invalid (true /* invalid first */); -} - - -static void -test_update_many_with_opts_invalid_first (void) -{ - _test_update_many_with_opts_invalid (true /* invalid first */); -} - - -static void -test_replace_one_invalid_first (void) -{ - _test_replace_one_invalid (true /* invalid first */); -} - - -static void -test_replace_one_with_opts_invalid_first (void) -{ - _test_replace_one_with_opts_invalid (true /* invalid first */); -} - - -static void -test_update_one_invalid_second (void) -{ - _test_update_one_invalid (false /* invalid first */); -} - - -static void -test_update_invalid_second (void) -{ - _test_update_invalid (false /* invalid first */); -} - - -static void -test_update_one_with_opts_invalid_second (void) -{ - _test_update_one_with_opts_invalid (false /* invalid first */); -} - - -static void -test_update_many_with_opts_invalid_second (void) -{ - _test_update_many_with_opts_invalid (false /* invalid first */); -} - - -static void -test_replace_one_invalid_second (void) -{ - _test_replace_one_invalid (false /* invalid first */); -} - - -static void -test_replace_one_with_opts_invalid_second (void) -{ - _test_replace_one_with_opts_invalid (false /* invalid first */); -} - - -static void -_test_insert_invalid (bool with_opts, bool invalid_first) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_t *bad_insert = tmp_bson ("{'a.b': 1}"); - bson_t *good_insert = tmp_bson ("{'x': 1}"); - bson_t reply; - bson_error_t error; - bool r; - const char *err = "keys cannot contain \".\": \"a.b\""; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_insert_validate"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (mongoc_collection_delete_many ( - collection, tmp_bson (NULL), NULL, NULL, NULL)); - - capture_logs (true); - - if (with_opts) { - if (invalid_first) { - /* document is rejected immediately */ - r = mongoc_bulk_operation_insert_with_opts ( - bulk, bad_insert, NULL, &error); - - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, err); - - /* now a valid document */ - r = mongoc_bulk_operation_insert_with_opts ( - bulk, good_insert, NULL, &error); - ASSERT_OR_PRINT (r, error); - ASSERT_CMPSIZE_T ((size_t) 1, ==, bulk->commands.len); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!bson_empty (&reply)); - } else { - /* first a valid document */ - r = mongoc_bulk_operation_insert_with_opts ( - bulk, good_insert, NULL, &error); - ASSERT_OR_PRINT (r, error); - - /* invalid document is rejected without invalidating batch */ - r = mongoc_bulk_operation_insert_with_opts ( - bulk, bad_insert, NULL, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, err); - - ASSERT_CMPSIZE_T ((size_t) 1, ==, bulk->commands.len); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!bson_empty (&reply)); - } - } else { /* not "with_opts" */ - if (invalid_first) { - /* invalid, then valid */ - mongoc_bulk_operation_insert (bulk, bad_insert); - mongoc_bulk_operation_insert (bulk, good_insert); - - /* not added */ - ASSERT_CMPSIZE_T ((size_t) 0, ==, bulk->commands.len); - - /* invalid document invalidated the whole bulk */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - BSON_ASSERT (bson_empty (&reply)); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, err); - } else { - /* valid, then invalid */ - mongoc_bulk_operation_insert (bulk, good_insert); - mongoc_bulk_operation_insert (bulk, bad_insert); - - ASSERT_CMPSIZE_T ((size_t) 1, ==, bulk->commands.len); - - /* invalid document invalidated the whole bulk */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - BSON_ASSERT (bson_empty (&reply)); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, err); - } - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_insert_invalid_first (void) -{ - _test_insert_invalid (true, false); -} - - -static void -test_insert_invalid_second (void) -{ - _test_insert_invalid (false, false); -} - - -static void -test_insert_with_opts_invalid_first (void) -{ - _test_insert_invalid (true, true); -} - - -static void -test_insert_with_opts_invalid_second (void) -{ - _test_insert_invalid (false, true); -} - - -static void -test_insert_with_opts_validate (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_insert_with_opts_validate"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - BSON_ASSERT (!mongoc_bulk_operation_insert_with_opts ( - bulk, tmp_bson ("{'a.a': 1}"), NULL, &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document for insert: keys cannot contain \".\": \"a.a\""); - - ASSERT_OR_PRINT (mongoc_bulk_operation_insert_with_opts ( - bulk, - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_NONE), - &error), - error); - ASSERT_OR_PRINT (mongoc_bulk_operation_insert_with_opts ( - bulk, - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_UTF8), - &error), - error); - ASSERT_OR_PRINT (!mongoc_bulk_operation_insert_with_opts ( - bulk, - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_DOT_KEYS), - &error), - error); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document for insert: keys cannot contain \".\": \"a.a\""); - - mongoc_bulk_operation_destroy (bulk); - - /* Test a valid insert with explicit validation on the server. */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (mongoc_bulk_operation_insert_with_opts ( - bulk, - tmp_bson ("{'a': 1}"), - tmp_bson ("{'validate': %d}", BSON_VALIDATE_DOT_KEYS), - &error)); - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, NULL, &error), error); - mongoc_bulk_operation_destroy (bulk); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -typedef void (*remove_fn) (mongoc_bulk_operation_t *bulk, - const bson_t *selector); - -typedef bool (*remove_with_opts_fn) (mongoc_bulk_operation_t *bulk, - const bson_t *selector, - const bson_t *opts, - bson_error_t *error); - -typedef struct { - remove_fn remove; - remove_with_opts_fn remove_with_opts; -} remove_validate_test_t; - - -static void -_test_remove_validate (remove_validate_test_t *test) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - collection = get_test_collection (client, "test_update_invalid_first"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - capture_logs (true); - - /* invalid */ - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'$a': 1}")); - - if (test->remove_with_opts) { - r = test->remove_with_opts (bulk, tmp_bson (NULL), NULL, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Bulk operation is invalid from prior error: " - "invalid document for insert: keys " - "cannot begin with \"$\": \"$a\""); - } else { - test->remove (bulk, tmp_bson (NULL)); - } - - /* remove operation was not recorded */ - ASSERT_CMPSIZE_T ((size_t) 0, ==, bulk->commands.len); - - /* invalid document invalidated the whole bulk */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - BSON_ASSERT (bson_empty (&reply)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document for insert: keys " - "cannot begin with \"$\": \"$a\""); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_remove_one_after_invalid (void) -{ - remove_validate_test_t test = {0}; - test.remove = mongoc_bulk_operation_remove_one; - - _test_remove_validate (&test); -} -static void -test_remove_after_invalid (void) -{ - remove_validate_test_t test = {0}; - test.remove = mongoc_bulk_operation_remove; - - _test_remove_validate (&test); -} -static void -test_remove_one_with_opts_after_invalid (void) -{ - remove_validate_test_t test = {0}; - test.remove_with_opts = mongoc_bulk_operation_remove_one_with_opts; - - _test_remove_validate (&test); -} -static void -test_remove_many_with_opts_after_invalid (void) -{ - remove_validate_test_t test = {0}; - test.remove_with_opts = mongoc_bulk_operation_remove_many_with_opts; - - _test_remove_validate (&test); -} - -static void -test_index_offset (void) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - bson_t reply; - bson_t *sel; - bson_t *doc; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_index_offset"); - BSON_ASSERT (collection); - - doc = tmp_bson ("{}"); - BSON_APPEND_INT32 (doc, "_id", 1234); - r = mongoc_collection_insert_one (collection, doc, NULL, NULL, &error); - BSON_ASSERT (r); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - sel = tmp_bson ("{'_id': 1234}"); - doc = tmp_bson ("{'$set': {'hello': 'there'}}"); - - mongoc_bulk_operation_remove_one (bulk, sel); - mongoc_bulk_operation_update (bulk, sel, doc, true); - - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 1," - " 'nUpserted': 1," - " 'upserted': [{'index': 1, '_id': 1234}]," - " 'writeErrors': []}"); - - ASSERT_COUNT (1, collection); - - bson_destroy (&reply); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_single_ordered_bulk (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_single_ordered_bulk"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'a': 1}")); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'a': 1}"), tmp_bson ("{'$set': {'b': 1}}"), false); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'a': 2}"), tmp_bson ("{'$set': {'b': 2}}"), true); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'a': 3}")); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'a': 3}")); - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 2," - " 'nMatched': 1," - " 'nModified': 1," - " 'nRemoved': 1," - " 'nUpserted': 1," - " 'upserted': [{'index': 2, '_id': {'$exists': true}}]" - "}"); - - ASSERT_COUNT (2, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_insert_continue_on_error (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t *doc0 = tmp_bson ("{'a': 1}"); - bson_t *doc1 = tmp_bson ("{'a': 2}"); - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_insert_continue_on_error"); - BSON_ASSERT (collection); - - create_unique_index (collection); - - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - mongoc_bulk_operation_insert (bulk, doc0); - mongoc_bulk_operation_insert (bulk, doc0); - mongoc_bulk_operation_insert (bulk, doc1); - mongoc_bulk_operation_insert (bulk, doc1); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - - ASSERT_MATCH (&reply, - "{'nInserted': 2," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': [{'index': 1}, {'index': 3}]}"); - - assert_error_count (2, &reply); - ASSERT_COUNT (2, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_update_continue_on_error (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t *doc0 = tmp_bson ("{'a': 1}"); - bson_t *doc1 = tmp_bson ("{'a': 2}"); - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_update_continue_on_error"); - BSON_ASSERT (collection); - - create_unique_index (collection); - mongoc_collection_insert_one (collection, doc0, NULL, NULL, NULL); - mongoc_collection_insert_one (collection, doc1, NULL, NULL, NULL); - - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - /* succeeds */ - mongoc_bulk_operation_update ( - bulk, doc0, tmp_bson ("{'$inc': {'b': 1}}"), false); - /* fails */ - mongoc_bulk_operation_update ( - bulk, doc0, tmp_bson ("{'$set': {'a': 2}}"), false); - /* succeeds */ - mongoc_bulk_operation_update ( - bulk, doc1, tmp_bson ("{'$set': {'b': 2}}"), false); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 2," - " 'nModified': 2," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': [{'index': 1}]}"); - - assert_error_count (1, &reply); - ASSERT_COUNT (2, collection); - ASSERT_CMPINT ( - 1, - ==, - (int) mongoc_collection_count_documents ( - collection, tmp_bson ("{'b': 2}"), NULL, NULL, NULL, NULL)); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_remove_continue_on_error (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t *doc0 = tmp_bson ("{'a': 1}"); - bson_t *doc1 = tmp_bson ("{'a': 2}"); - bson_t *doc2 = tmp_bson ("{'a': 3}"); - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_remove_continue_on_error"); - BSON_ASSERT (collection); - - mongoc_collection_insert_one (collection, doc0, NULL, NULL, NULL); - mongoc_collection_insert_one (collection, doc1, NULL, NULL, NULL); - mongoc_collection_insert_one (collection, doc2, NULL, NULL, NULL); - - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - /* succeeds */ - mongoc_bulk_operation_remove_one (bulk, doc0); - /* fails */ - mongoc_bulk_operation_remove_one (bulk, tmp_bson ("{'a': {'$bad': 1}}")); - /* succeeds */ - mongoc_bulk_operation_remove_one (bulk, doc1); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 2," - " 'nUpserted': 0," - " 'writeErrors': [{'index': 1}]}"); - - assert_error_count (1, &reply); - ASSERT_COUNT (1, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_single_error_ordered_bulk (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_single_error_ordered_bulk"); - BSON_ASSERT (collection); - - create_unique_index (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 1, 'a': 1}")); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'b': 2}"), tmp_bson ("{'$set': {'a': 1}}"), true); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 3, 'a': 2}")); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - - /* TODO: CDRIVER-651, BSON_ASSERT contents of the 'op' field */ - ASSERT_MATCH (&reply, - "{'nInserted': 1," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': [" - " {'index': 1," - " 'code': {'$exists': true}," - " 'errmsg': {'$exists': true}}]" - /* - * " 'writeErrors.0.op': ...," - */ - "}"); - assert_error_count (1, &reply); - ASSERT_COUNT (1, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_multiple_error_ordered_bulk (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = - get_test_collection (client, "test_multiple_error_ordered_bulk"); - BSON_ASSERT (collection); - - create_unique_index (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - /* 0 succeeds */ - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 1, 'a': 1}")); - /* 1 succeeds */ - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'b': 3}"), tmp_bson ("{'$set': {'a': 2}}"), true); - /* 2 fails, duplicate value for 'a' */ - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'b': 2}"), tmp_bson ("{'$set': {'a': 1}}"), true); - /* 3 not attempted, bulk is already aborted */ - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 4, 'a': 3}")); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - BSON_ASSERT (error.code); - - /* TODO: CDRIVER-651, BSON_ASSERT contents of the 'op' field */ - ASSERT_MATCH (&reply, - "{'nInserted': 1," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 1," - " 'writeErrors': [" - " {'index': 2, 'errmsg': {'$exists': true}}" - "]" - /* - * " 'writeErrors.0.op': {'q': {'b': 2}, - * 'u': {'$set': {'a': 1}}, 'multi': false}" - */ - "}"); - assert_error_count (1, &reply); - ASSERT_COUNT (2, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_single_unordered_bulk (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_single_unordered_bulk"); - BSON_ASSERT (collection); - - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'a': 1}")); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'a': 1}"), tmp_bson ("{'$set': {'b': 1}}"), false); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'a': 2}"), tmp_bson ("{'$set': {'b': 2}}"), true); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'a': 3}")); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'a': 3}")); - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 2," - " 'nMatched': 1," - " 'nModified': 1," - " 'nRemoved': 1," - " 'nUpserted': 1," - " 'upserted': [" - " {'index': 2, '_id': {'$exists': true}}]," - " 'writeErrors': []}"); - ASSERT_COUNT (2, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_single_error_unordered_bulk (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = - get_test_collection (client, "test_single_error_unordered_bulk"); - BSON_ASSERT (collection); - - create_unique_index (collection); - - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - - /* 0 succeeds */ - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 1, 'a': 1}")); - /* 1 fails */ - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'b': 2}"), tmp_bson ("{'$set': {'a': 1}}"), true); - /* 2 succeeds */ - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 3, 'a': 2}")); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - BSON_ASSERT (error.code); - - /* TODO: CDRIVER-651, BSON_ASSERT contents of the 'op' field */ - ASSERT_MATCH (&reply, - "{'nInserted': 2," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': [{'index': 1," - " 'code': {'$exists': true}," - " 'errmsg': {'$exists': true}}]}"); - assert_error_count (1, &reply); - ASSERT_COUNT (2, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -_test_oversized_bulk_op (bool ordered) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *opts = NULL; - mongoc_bulk_operation_t *bulk; - bson_t *huge_doc; - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_oversized_bulk"); - mongoc_collection_drop_with_opts (collection, NULL, NULL); - - if (!ordered) { - opts = tmp_bson ("{'ordered': false}"); - } - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, opts); - - /* this fails, aborting bulk, even if it's unordered */ - huge_doc = BCON_NEW ("a", BCON_INT32 (1)); - bson_append_utf8 (huge_doc, - "b", - -1, - huge_string (client), - (int) huge_string_length (client)); - bson_append_utf8 (huge_doc, - "c", - -1, - huge_string (client), - (int) huge_string_length (client)); - mongoc_bulk_operation_insert (bulk, huge_doc); - - /* would succeed if it ran */ - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'a': 1}")); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_BSON, - MONGOC_ERROR_BSON_INVALID, - "Document 0 is too large"); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': []}"); - - /* second document was *not* inserted */ - ASSERT_COUNT (0, collection); - - bson_destroy (&reply); - bson_destroy (huge_doc); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_oversized_bulk_op_ordered (void *ctx) -{ - _test_oversized_bulk_op (true); -} - - -static void -test_oversized_bulk_op_unordered (void *ctx) -{ - _test_oversized_bulk_op (false); -} - - -static void -_test_write_concern (bool ordered, bool multi_err) -{ - mock_server_t *mock_server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - int32_t first_err; - int32_t second_err; - - mock_server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (mock_server); - client = mongoc_client_new_from_uri (mock_server_get_uri (mock_server)); - collection = mongoc_client_get_collection (client, "test", "test"); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_write_concern_set_wtimeout_int64 (wc, 100); - mongoc_write_concern_append (wc, &opts); - bson_append_bool (&opts, "ordered", 7, ordered); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 1}")); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'_id': 2}")); - - future = future_bulk_operation_execute (bulk, &reply, &error); - - request = mock_server_receives_command ( - mock_server, - "test", - MONGOC_QUERY_NONE, - "{'insert': 'test'," - " 'writeConcern': {'w': 2, 'wtimeout': 100}," - " 'ordered': %s," - " 'documents': [{'_id': 1}]}", - ordered ? "true" : "false"); - - BSON_ASSERT (request); - mock_server_replies_simple ( - request, - "{'ok': 1.0, 'n': 1, " - " 'writeConcernError': {'code': 17, 'errmsg': 'foo'}}"); - - request_destroy (request); - request = mock_server_receives_command ( - mock_server, - "test", - MONGOC_QUERY_NONE, - "{'delete': 'test'," - " 'writeConcern': {'w': 2, 'wtimeout': 100}," - " 'ordered': %s," - " 'deletes': [{'q': {'_id': 2}, 'limit': 0}]}", - ordered ? "true" : "false"); - - if (multi_err) { - mock_server_replies_simple ( - request, - "{'ok': 1.0, 'n': 1, " - " 'writeConcernError': {'code': 42, 'errmsg': 'bar'}}"); - } else { - mock_server_replies_simple (request, "{'ok': 1.0, 'n': 1}"); - } - - request_destroy (request); - - /* server fictionally returns 17 and 42; expect driver to use first one */ - first_err = 17; - second_err = 42; - - /* join thread, BSON_ASSERT mongoc_bulk_operation_execute () returned 0 */ - BSON_ASSERT (!future_get_uint32_t (future)); - - if (multi_err) { - ASSERT_MATCH (&reply, - "{'nInserted': 1," - " 'nMatched': 0," - " 'nRemoved': 1," - " 'nUpserted': 0," - " 'writeErrors': []," - " 'writeConcernErrors': [" - " {'code': %d, 'errmsg': 'foo'}," - " {'code': %d, 'errmsg': 'bar'}]}", - first_err, - second_err); - - ASSERT_CMPSTR ("Multiple write concern errors: \"foo\", \"bar\"", - error.message); - } else { - ASSERT_MATCH (&reply, - "{'nInserted': 1," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 1," - " 'nUpserted': 0," - " 'writeErrors': []," - " 'writeConcernErrors': [" - " {'code': %d, 'errmsg': 'foo'}]}", - first_err); - ASSERT_CMPSTR ("foo", error.message); - } - - ASSERT_CMPINT (MONGOC_ERROR_WRITE_CONCERN, ==, error.domain); - ASSERT_CMPINT (first_err, ==, error.code); - - future_destroy (future); - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (mock_server); -} - -static void -test_write_concern_write_command_ordered (void) -{ - _test_write_concern (true, false); -} - - -static void -test_write_concern_write_command_ordered_multi_err (void) -{ - _test_write_concern (true, true); -} - - -static void -test_write_concern_write_command_unordered (void) -{ - _test_write_concern (false, false); -} - - -static void -test_write_concern_write_command_unordered_multi_err (void) -{ - _test_write_concern (false, true); -} - - -static void -_test_write_concern_err_api (int32_t error_api_version) -{ - mock_server_t *mock_server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - uint32_t expected_code; - - mock_server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (mock_server); - client = mongoc_client_new_from_uri (mock_server_get_uri (mock_server)); - ASSERT (mongoc_client_set_error_api (client, error_api_version)); - collection = mongoc_client_get_collection (client, "test", "test"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 1}")); - - future = future_bulk_operation_execute (bulk, &reply, &error); - - request = mock_server_receives_command ( - mock_server, "test", MONGOC_QUERY_NONE, NULL); - - mock_server_replies_simple ( - request, - "{'ok': 1.0, 'n': 1, " - " 'writeConcernError': {'code': 42, 'errmsg': 'foo'}}"); - - BSON_ASSERT (!future_get_uint32_t (future)); - /* legacy write concern errs have no code from server, driver uses 64 */ - expected_code = 42; - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, expected_code, "foo"); - - request_destroy (request); - future_destroy (future); - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (mock_server); -} - - -static void -test_write_concern_error_write_command_v1 (void) -{ - _test_write_concern_err_api (1); -} - - -static void -test_write_concern_error_write_command_v2 (void) -{ - _test_write_concern_err_api (2); -} - - -static void -test_multiple_error_unordered_bulk (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = - get_test_collection (client, "test_multiple_error_unordered_bulk"); - BSON_ASSERT (collection); - - create_unique_index (collection); - - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 1, 'a': 1}")); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'b': 2}"), tmp_bson ("{'$set': {'a': 3}}"), true); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'b': 3}"), tmp_bson ("{'$set': {'a': 4}}"), true); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{'b': 4}"), tmp_bson ("{'$set': {'a': 3}}"), true); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 5, 'a': 2}")); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 6, 'a': 1}")); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - BSON_ASSERT (error.code); - - /* Assume the update at index 1 runs before the update at index 3, - * although the spec does not require it. Same for inserts. - */ - /* TODO: CDRIVER-651, BSON_ASSERT contents of the 'op' field */ - ASSERT_MATCH (&reply, - "{'nInserted': 2," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 2," - /* " 'writeErrors.0.op': {'q': {'b': 4}, 'u': {'$set': {'a': - 3}}, 'multi': false, 'upsert': true}}," */ - " 'writeErrors.0.index': 3," - " 'writeErrors.0.code': {'$exists': true}," - " 'writeErrors.1.index': 5," - /* " 'writeErrors.1.op': {'_id': '...', 'b': 6, 'a': 1}," */ - " 'writeErrors.1.code': {'$exists': true}," - " 'writeErrors.1.errmsg': {'$exists': true}}"); - assert_error_count (2, &reply); - - /* - * assume the update at index 1 runs before the update at index 3, - * although the spec does not require it. Same for inserts. - */ - ASSERT_COUNT (4, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -_test_wtimeout_plus_duplicate_key_err (void) -{ - mock_server_t *mock_server; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - - mock_server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (mock_server); - client = mongoc_client_new_from_uri (mock_server_get_uri (mock_server)); - collection = mongoc_client_get_collection (client, "test", "test"); - - /* unordered bulk */ - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 1}")); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 2}")); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{'_id': 3}")); - future = future_bulk_operation_execute (bulk, &reply, &error); - - request = - mock_server_receives_command (mock_server, - "test", - MONGOC_QUERY_NONE, - "{'insert': 'test'," - " 'writeConcern': {'$exists': false}," - " 'ordered': false," - " 'documents': [{'_id': 1}, {'_id': 2}]}"); - - BSON_ASSERT (request); - mock_server_replies ( - request, - 0, - 0, - 0, - 1, - "{'ok': 1.0, 'n': 1," - " 'writeErrors': [{'index': 0, 'code': 11000, 'errmsg': 'dupe'}]," - " 'writeConcernError': {'code': 17, 'errmsg': 'foo'}}"); - - request_destroy (request); - request = mock_server_receives_command ( - mock_server, - "test", - MONGOC_QUERY_NONE, - "{'delete': 'test'," - " 'writeConcern': {'$exists': false}," - " 'ordered': false," - " 'deletes': [{'q': {'_id': 3}, 'limit': 0}]}"); - - BSON_ASSERT (request); - mock_server_replies (request, - 0, - 0, - 0, - 1, - "{'ok': 1.0, 'n': 1," - " 'writeConcernError': {'code': 42, 'errmsg': 'bar'}}"); - request_destroy (request); - - /* mongoc_bulk_operation_execute () returned 0 */ - BSON_ASSERT (!future_get_uint32_t (future)); - - /* get err code from server with write commands, otherwise use 64 */ - ASSERT_MATCH (&reply, - "{'nInserted': 1," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 1," - " 'nUpserted': 0," - " 'writeErrors': [" - " {'index': 0, 'code': 11000, 'errmsg': 'dupe'}]," - " 'writeConcernErrors': [" - " {'code': %d, 'errmsg': 'foo'}," - " {'code': %d, 'errmsg': 'bar'}]}", - 17, - 42); - - future_destroy (future); - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (mock_server); -} - - -static void -test_wtimeout_plus_duplicate_key_err_write_commands (void) -{ - _test_wtimeout_plus_duplicate_key_err (); -} - - -static void -test_large_inserts_ordered (void *ctx) -{ - mongoc_client_t *client; - bson_t *huge_doc; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - bool r; - bson_t *big_doc; - bson_iter_t iter; - int i; - const bson_t *retdoc; - bson_t query = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - huge_doc = BCON_NEW ("a", BCON_INT32 (1)); - bson_append_utf8 (huge_doc, - "long-key-to-make-this-fail", - -1, - huge_string (client), - (int) huge_string_length (client)); - - collection = get_test_collection (client, "test_large_inserts_ordered"); - BSON_ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 1, 'a': 1}")); - mongoc_bulk_operation_insert (bulk, huge_doc); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 2, 'a': 2}")); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - ASSERT_MATCH (&reply, - "{'nInserted': 1," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': [{'index': 1}]}"); - assert_error_count (1, &reply); - ASSERT_COUNT (1, collection); - - cursor = mongoc_collection_find_with_opts (collection, &query, NULL, NULL); - ASSERT_CURSOR_NEXT (cursor, &retdoc); - ASSERT_CURSOR_DONE (cursor); - - bson_destroy (&query); - mongoc_collection_delete_many ( - collection, tmp_bson ("{}"), NULL, NULL, NULL); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - BSON_ASSERT (bulk); - - big_doc = tmp_bson ("{'a': 1}"); - bson_append_utf8 (big_doc, "big", -1, four_mb_string (), FOUR_MB); - bson_iter_init_find (&iter, big_doc, "a"); - - for (i = 1; i <= 6; i++) { - bson_iter_overwrite_int32 (&iter, i); - mongoc_bulk_operation_insert (bulk, big_doc); - } - - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - assert_n_inserted (6, &reply); - ASSERT_COUNT (6, collection); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - bson_destroy (huge_doc); - mongoc_client_destroy (client); -} - - -static void -test_large_inserts_unordered (void *ctx) -{ - mongoc_client_t *client; - bson_t *huge_doc; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - bool r; - bson_t *big_doc; - bson_iter_t iter; - int i; - const bson_t *retdoc; - bson_t query = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - huge_doc = BCON_NEW ("a", BCON_INT32 (1)); - bson_append_utf8 (huge_doc, - "long-key-to-make-this-fail", - -1, - huge_string (client), - (int) huge_string_length (client)); - - collection = get_test_collection (client, "test_large_inserts_unordered"); - BSON_ASSERT (collection); - - bson_append_bool (&opts, "ordered", 7, false); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 1, 'a': 1}")); - - /* 1 fails */ - mongoc_bulk_operation_insert (bulk, huge_doc); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'b': 2, 'a': 2}")); - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - ASSERT_MATCH (&reply, - "{'nInserted': 2," - " 'nMatched': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': [{" - " 'index': 1," - " 'code': {'$exists': true}," - " 'errmsg': {'$exists': true}" - " }]}"); - - ASSERT_COUNT (2, collection); - - cursor = mongoc_collection_find_with_opts (collection, &query, NULL, NULL); - ASSERT_CURSOR_NEXT (cursor, &retdoc); - ASSERT_CURSOR_NEXT (cursor, &retdoc); - ASSERT_CURSOR_DONE (cursor); - - bson_destroy (&query); - mongoc_collection_delete_many ( - collection, tmp_bson ("{}"), NULL, NULL, NULL); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - big_doc = tmp_bson ("{'a': 1}"); - bson_append_utf8 (big_doc, "big", -1, four_mb_string (), (int) FOUR_MB); - bson_iter_init_find (&iter, big_doc, "a"); - - for (i = 1; i <= 6; i++) { - bson_iter_overwrite_int32 (&iter, i); - mongoc_bulk_operation_insert (bulk, big_doc); - } - - ASSERT_OR_PRINT ((bool) mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - assert_n_inserted (6, &reply); - ASSERT_COUNT (6, collection); - - bson_destroy (huge_doc); - bson_destroy (&reply); - mongoc_cursor_destroy (cursor); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -execute_numerous_bulk_op (mock_server_t *server, - mongoc_bulk_operation_t *bulk, - const char *doc_json) -{ - bson_error_t error; - future_t *future; - request_t *request; - const bson_t *docs[4]; - int i, j; - - future = future_bulk_operation_execute (bulk, NULL, &error); - - /* accept anything for the command body */ - docs[0] = tmp_bson ("{}"); - - /* test that driver sends 7 documents in batches of up to 3 */ - for (i = 0; i < 7;) { - for (j = 0; j < 3 && i < 7; i++, j++) { - docs[j + 1] = tmp_bson (doc_json); - } - - request = mock_server_receives_request (server); - BSON_ASSERT (request_matches_msg (request, 0, &docs[0], j + 1)); - mock_server_replies_ok_and_destroys (request); - } - - ASSERT_OR_PRINT (future_get_uint32_t (future), error); - future_destroy (future); -} - - -static void -_test_numerous (bool ordered) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - int i; - bson_t *opts = tmp_bson ("{'ordered': %s}", ordered ? "true" : "false"); - bson_t *doc = tmp_bson ("{'_id': 1}"); - - server = mock_server_new (); - /* the real OP_MSG max batch is 100k docs, choose 3 for faster test */ - mock_server_auto_ismaster (server, - "{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 0," - " 'maxWireVersion': %d," - " 'maxWriteBatchSize': 3}", - WIRE_VERSION_OP_MSG); - - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - -#define TEST_NUMEROUS(_one_write, _doc_format) \ - do { \ - bulk = \ - mongoc_collection_create_bulk_operation_with_opts (collection, opts); \ - for (i = 0; i < 7; i++) { \ - mongoc_bulk_operation_##_one_write; \ - } \ - execute_numerous_bulk_op (server, bulk, _doc_format); \ - mongoc_bulk_operation_destroy (bulk); \ - } while (0) - - TEST_NUMEROUS (insert (bulk, doc), "{'_id': 1}"); - TEST_NUMEROUS (remove_many_with_opts (bulk, doc, NULL, NULL), - "{'q': {'_id': 1}, 'limit': 0}"); - TEST_NUMEROUS (remove_one (bulk, doc), "{'q': {'_id': 1}, 'limit': 1}"); - TEST_NUMEROUS (replace_one (bulk, doc, tmp_bson ("{}"), false), - "{'q': {'_id': 1}, 'u': {}}"); - TEST_NUMEROUS (update_one (bulk, doc, tmp_bson ("{'$set': {'x': 1}}"), NULL), - "{'q': {'_id': 1}, 'u': {'$set': {'x': 1}}}"); - TEST_NUMEROUS (update_many_with_opts ( - bulk, doc, tmp_bson ("{'$set': {'x': 1}}"), NULL, NULL), - "{'q': {'_id': 1}, 'u': {'$set': {'x': 1}}}"); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_numerous_ordered (void *ctx) -{ - _test_numerous (true); -} - - -static void -test_numerous_unordered (void *ctx) -{ - _test_numerous (false); -} - - -static void -test_bulk_split (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk_op; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_iter_t iter, error_iter, indexnum; - bson_t doc, result; - bson_error_t error; - int n_docs; - int i; - uint32_t r; - - /* ensure we need two batches */ - n_docs = (int) test_framework_max_write_batch_size () + 10; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "split"); - BSON_ASSERT (collection); - - mongoc_write_concern_set_w (wc, 1); - - mongoc_write_concern_append (wc, &opts); - bson_append_bool (&opts, "ordered", 7, false); - bulk_op = - mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - - /* if n_docs is 100,010 insert 3337 docs with _ids 0, 3, 6, ..., 100,008 */ - for (i = 0; i < n_docs; i += 3) { - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, i); - - mongoc_bulk_operation_insert (bulk_op, &doc); - - bson_destroy (&doc); - } - - r = mongoc_bulk_operation_execute (bulk_op, NULL, &error); /* succeed */ - ASSERT_OR_PRINT (r, error); - - mongoc_bulk_operation_destroy (bulk_op); - - /* ordered false so we continue on error */ - bulk_op = - mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - /* insert n_docs documents with _ids 0, 1, 2, 3, ..., 100,008 */ - for (i = 0; i < n_docs; i++) { - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, i); - - mongoc_bulk_operation_insert (bulk_op, &doc); - - bson_destroy (&doc); - } - - /* two thirds of the docs succeed, but _ids 0, 3, 6, ... are duplicates */ - r = mongoc_bulk_operation_execute (bulk_op, &result, &error); - BSON_ASSERT (!r); - - /* all 100,010 docs were inserted, either by the first or second bulk op */ - ASSERT_COUNT (n_docs, collection); - - /* result like {writeErrors: [{index: i, code: n, errmsg: ''}, ... ]} */ - bson_iter_init_find (&iter, &result, "writeErrors"); - BSON_ASSERT (bson_iter_recurse (&iter, &error_iter)); - BSON_ASSERT (bson_iter_next (&error_iter)); - - /* we expect duplicate key errs about _ids 0, 3, 6, ..., 100,008 - * and the error index should equal the _id */ - for (i = 0; i < n_docs; i += 3) { - BSON_ASSERT (bson_iter_recurse (&error_iter, &indexnum)); - BSON_ASSERT (bson_iter_find (&indexnum, "index")); - if (bson_iter_int32 (&indexnum) != i) { - fprintf (stderr, - "index should be %d, but is %d\n", - i, - bson_iter_int32 (&indexnum)); - } - BSON_ASSERT (bson_iter_int32 (&indexnum) == i); - bson_iter_next (&error_iter); - } - - mongoc_bulk_operation_destroy (bulk_op); - bson_destroy (&opts); - bson_destroy (&result); - - mongoc_write_concern_destroy (wc); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_bulk_edge_case_372 (bool ordered) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_iter_t iter; - bson_iter_t citer; - bson_t *selector; - bson_t *update; - bson_t reply; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "CDRIVER_372"); - BSON_ASSERT (collection); - - bson_append_bool (&opts, "ordered", 7, ordered); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - BSON_ASSERT (bulk); - - selector = tmp_bson ("{'_id': 0}"); - update = tmp_bson ("{'$set': {'a': 0}}"); - mongoc_bulk_operation_update_one (bulk, selector, update, true); - - selector = tmp_bson ("{'a': 1}"); - update = tmp_bson ("{'_id': 1}"); - mongoc_bulk_operation_replace_one (bulk, selector, update, true); - - /* This is just here to make the counts right in all cases. */ - selector = tmp_bson ("{'_id': 2}"); - update = tmp_bson ("{'_id': 2}"); - mongoc_bulk_operation_replace_one (bulk, selector, update, true); - - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 3," - " 'upserted': [" - " {'index': 0, '_id': 0}," - " {'index': 1, '_id': 1}," - " {'index': 2, '_id': 2}" - " ]," - " 'writeErrors': []}"); - - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "upserted") && - BSON_ITER_HOLDS_ARRAY (&iter) && - bson_iter_recurse (&iter, &citer)); - - bson_destroy (&reply); - - mongoc_collection_drop (collection, NULL); - - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_bulk_edge_case_372_ordered (void) -{ - test_bulk_edge_case_372 (true); -} - - -static void -test_bulk_edge_case_372_unordered (void) -{ - test_bulk_edge_case_372 (false); -} - - -typedef struct { - int started; - int succeeded; - int failed; -} stats_t; - - -void -command_succeeded (const mongoc_apm_command_succeeded_t *event) -{ - const char *cmd_name = mongoc_apm_command_succeeded_get_command_name (event); - - if (!strcasecmp (cmd_name, "insert")) { - ((stats_t *) mongoc_apm_command_succeeded_get_context (event)) - ->succeeded++; - } -} - - -static void -test_bulk_max_msg_size (void) -{ - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - mongoc_write_concern_t *wc; - mongoc_client_t *client; - bson_error_t error; - bson_t reply; - bson_t doc; - bool retval; - mongoc_apm_callbacks_t *callbacks; - stats_t stats = {0}; - int str_size = 16 * 1024 * 1024 - 24; - char *msg = bson_malloc (str_size + 1); - int filler_string = 14445428; - mongoc_client_session_t *cs; - - memset (msg, 'a', str_size); - msg[str_size] = '\0'; - if (!test_framework_max_wire_version_at_least (WIRE_VERSION_OP_MSG)) { - bson_free (msg); - bson_destroy (&opts); - return; - } - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 1); - mongoc_write_concern_append (wc, &opts); - - client = test_framework_client_new (); - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_succeeded_cb (callbacks, command_succeeded); - mongoc_client_set_apm_callbacks (client, callbacks, (void *) &stats); - collection = mongoc_client_get_collection (client, "test", "max_msg_size"); - mongoc_collection_drop (collection, NULL); - - /* Cluster time document argument is injected sometimes */ - if (!bson_empty (&client->topology->description.cluster_time)) { - filler_string -= client->topology->description.cluster_time.len + - strlen ("$clusterTime") + 2; - } - - cs = mongoc_client_start_session (client, NULL, NULL); - if (cs) { - /* sessions are supported */ - filler_string -= - mongoc_client_session_get_lsid (cs)->len + strlen ("lsid") + 2; - - /* TODO: this check can be removed once CDRIVER-3070 is resolved */ - if (test_framework_is_mongos () || test_framework_is_replset ()) { - /* retryable writes includes a txnNumber (int64) */ - filler_string -= strlen ("txnNumber") + 10; - } - - ASSERT_OR_PRINT (mongoc_client_session_append (cs, &opts, &error), error); - } - - /* {{{ Exactly 48 000 000 bytes (not to be confused with 48mb!) */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - /* 16 mb doc */ - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, 1); - BSON_APPEND_UTF8 (&doc, "msg", msg); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - - /* 16 mb doc */ - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, 2); - BSON_APPEND_UTF8 (&doc, "msg", msg); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - - /* fill up to the 48 000 000 bytes message size */ - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, 3); - bson_append_utf8 (&doc, "msg", -1, msg, filler_string); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - - retval = mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (retval, error); - assert_n_inserted (3, &reply); - bson_destroy (&reply); - /* Make sure this was ONE bulk ! */ - ASSERT_CMPINT (stats.succeeded, ==, 1); - stats.succeeded = 0; - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_drop (collection, NULL); - /* }}} */ - - /* {{{ 48 000 001 byte */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - /* 16 mb doc */ - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, 1); - BSON_APPEND_UTF8 (&doc, "msg", msg); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - - /* 16 mb doc */ - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, 2); - BSON_APPEND_UTF8 (&doc, "msg", msg); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - - /* fill up to the 48 000 001 bytes message size */ - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, 3); - bson_append_utf8 (&doc, "msg", -1, msg, filler_string + 1); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - - retval = mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (retval, error); - assert_n_inserted (3, &reply); - bson_destroy (&reply); - /* Make sure this was TWO bulks, otherwise our one bulk math was wrong! */ - ASSERT_CMPINT (stats.succeeded, ==, 2); - stats.succeeded = 0; - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_drop (collection, NULL); - /* }}} */ - - if (cs) { - mongoc_client_session_destroy (cs); - } - - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_client_destroy (client); - bson_free (msg); - bson_destroy (&opts); -} - - -static void -test_bulk_max_batch_size (void) -{ - int64_t max_batch; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - mongoc_write_concern_t *wc; - mongoc_client_t *client; - bson_error_t error; - bson_t reply; - bson_t doc; - bool retval; - int i; - mongoc_apm_callbacks_t *callbacks; - stats_t stats = {0}; - - if (!test_framework_max_wire_version_at_least (WIRE_VERSION_OP_MSG)) { - bson_destroy (&opts); - return; - } - - max_batch = test_framework_max_write_batch_size (); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 1); - mongoc_write_concern_append (wc, &opts); - client = test_framework_client_new (); - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_succeeded_cb (callbacks, command_succeeded); - mongoc_client_set_apm_callbacks (client, callbacks, (void *) &stats); - collection = get_test_collection (client, "max_batch_size"); - - - /* {{{ Insert 100 000 documents, in one bulk */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - for (i = 1; i <= max_batch; i++) { - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, i); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - } - - retval = mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (retval, error); - assert_n_inserted (i - 1, &reply); - bson_destroy (&reply); - ASSERT_CMPINT (stats.succeeded, ==, 1); - stats.succeeded = 0; - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_drop (collection, NULL); - /* }}} */ - - /* {{{ Insert 100 001 documents, in two bulks */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - for (i = 1; i <= (max_batch + 1); i++) { - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, i); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - } - - retval = mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (retval, error); - assert_n_inserted (i - 1, &reply); - bson_destroy (&reply); - ASSERT_CMPINT (stats.succeeded, ==, 2); - stats.succeeded = 0; - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_drop (collection, NULL); - /* }}} */ - - /* {{{ Insert 200 000 documents, in two bulks */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - for (i = 1; i <= 2 * max_batch; i++) { - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, i); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - } - - retval = mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (retval, error); - assert_n_inserted (i - 1, &reply); - bson_destroy (&reply); - ASSERT_CMPINT (stats.succeeded, ==, 2); - stats.succeeded = 0; - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_drop (collection, NULL); - /* }}} */ - - /* {{{ Insert 200 001 documents, in 3 bulks */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - for (i = 1; i <= (2 * max_batch + 1); i++) { - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, i); - mongoc_bulk_operation_insert (bulk, &doc); - bson_destroy (&doc); - } - - retval = mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (retval, error); - assert_n_inserted (i - 1, &reply); - bson_destroy (&reply); - ASSERT_CMPINT (stats.succeeded, ==, 3); - stats.succeeded = 0; - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_drop (collection, NULL); - /* }}} */ - - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_client_destroy (client); -} - - -static void -test_bulk_new (void) -{ - mongoc_bulk_operation_t *bulk; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - bson_t empty = BSON_INITIALIZER; - uint32_t r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "bulk_new"); - BSON_ASSERT (collection); - - bulk = mongoc_bulk_operation_new (true); - mongoc_bulk_operation_destroy (bulk); - - bulk = mongoc_bulk_operation_new (true); - - r = mongoc_bulk_operation_execute (bulk, NULL, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_COMMAND_INVALID_ARG); - - mongoc_bulk_operation_set_database (bulk, "test"); - r = mongoc_bulk_operation_execute (bulk, NULL, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_COMMAND_INVALID_ARG); - - mongoc_bulk_operation_set_collection (bulk, "test"); - r = mongoc_bulk_operation_execute (bulk, NULL, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_COMMAND_INVALID_ARG); - - mongoc_bulk_operation_set_client (bulk, client); - r = mongoc_bulk_operation_execute (bulk, NULL, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_COMMAND_INVALID_ARG); - - mongoc_bulk_operation_insert (bulk, &empty); - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, NULL, &error), error); - - mongoc_bulk_operation_destroy (bulk); - - mongoc_collection_drop (collection, NULL); - - bson_destroy (&empty); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -typedef enum { HANGUP, SERVER_ERROR, ERR_TYPE_LAST } err_type_t; - - -static void -test_bulk_write_concern_split (void) -{ - mongoc_client_t *client; - mongoc_bulk_operation_t *bulk; - mongoc_write_concern_t *write_concern; - bson_t doc; - bson_error_t error; - uint32_t success; - int i; - char *str; - bson_t reply; - bson_iter_t iter; - bool r; - int num_docs; - - num_docs = (int) test_framework_max_write_batch_size () + 10; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_w (write_concern, 1); - mongoc_client_set_write_concern (client, write_concern); - - str = gen_collection_name ("bulk_write_concern_split"); - bulk = mongoc_bulk_operation_new (true); - mongoc_bulk_operation_set_database (bulk, "test"); - mongoc_bulk_operation_set_collection (bulk, str); - mongoc_write_concern_set_w (write_concern, 0); - mongoc_bulk_operation_set_write_concern (bulk, write_concern); - mongoc_bulk_operation_set_client (bulk, client); - - for (i = 0; i < num_docs; i += 3) { - bson_init (&doc); - bson_append_int32 (&doc, "_id", -1, i); - - mongoc_bulk_operation_insert (bulk, &doc); - - bson_destroy (&doc); - } - - success = mongoc_bulk_operation_execute (bulk, NULL, &error); - ASSERT_OR_PRINT (success, error); - - /* wait for bulk insert to complete on this connection */ - r = mongoc_client_command_simple ( - client, "test", tmp_bson ("{'getlasterror': 1}"), NULL, &reply, &error); - - ASSERT_OR_PRINT (r, error); - if (bson_iter_init_find (&iter, &reply, "err") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - test_error ("%s", bson_iter_utf8 (&iter, NULL)); - abort (); - } - - bson_destroy (&reply); - bson_free (str); - mongoc_bulk_operation_destroy (bulk); - mongoc_client_destroy (client); - mongoc_write_concern_destroy (write_concern); -} - - -static uint32_t -server_id_for_read_mode (mongoc_client_t *client, mongoc_read_mode_t read_mode) -{ - mongoc_read_prefs_t *prefs; - mongoc_server_description_t *sd; - bson_error_t error; - uint32_t server_id; - - prefs = mongoc_read_prefs_new (read_mode); - sd = - mongoc_topology_select (client->topology, MONGOC_SS_READ, prefs, &error); - - ASSERT_OR_PRINT (sd, error); - server_id = sd->id; - - mongoc_server_description_destroy (sd); - mongoc_read_prefs_destroy (prefs); - - return server_id; -} - - -static void -_test_bulk_hint (bool pooled, bool use_primary) -{ - mock_rs_t *rs; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bool ret; - uint32_t server_id; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - - /* primary, 2 secondaries */ - rs = mock_rs_with_autoismaster (WIRE_VERSION_MIN, true, 2, 0); - mock_rs_run (rs); - - if (pooled) { - pool = mongoc_client_pool_new (mock_rs_get_uri (rs)); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - } - - /* warm up the client so its server_id is valid */ - ret = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'isMaster': 1}"), NULL, NULL, &error); - ASSERT_OR_PRINT (ret, error); - - collection = mongoc_client_get_collection (client, "test", "test"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - ASSERT_CMPUINT32 ((uint32_t) 0, ==, mongoc_bulk_operation_get_hint (bulk)); - if (use_primary) { - server_id = server_id_for_read_mode (client, MONGOC_READ_PRIMARY); - } else { - server_id = server_id_for_read_mode (client, MONGOC_READ_SECONDARY); - } - - mongoc_bulk_operation_set_hint (bulk, server_id); - ASSERT_CMPUINT32 (server_id, ==, mongoc_bulk_operation_get_hint (bulk)); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 1}")); - future = future_bulk_operation_execute (bulk, &reply, &error); - - request = mock_rs_receives_command ( - rs, "test", MONGOC_QUERY_NONE, "{'insert': 'test'}"); - - BSON_ASSERT (request); - mock_server_replies_simple (request, "{'ok': 1.0, 'n': 1}"); - - if (use_primary) { - BSON_ASSERT (mock_rs_request_is_to_primary (rs, request)); - } else { - BSON_ASSERT (mock_rs_request_is_to_secondary (rs, request)); - } - - ASSERT_CMPUINT32 (server_id, ==, future_get_uint32_t (future)); - - request_destroy (request); - future_destroy (future); - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mock_rs_destroy (rs); -} - -static void -test_hint_single_command_secondary (void) -{ - _test_bulk_hint (false, false); -} - -static void -test_hint_single_command_primary (void) -{ - _test_bulk_hint (false, true); -} - -static void -test_hint_pooled_command_secondary (void) -{ - _test_bulk_hint (true, false); -} - -static void -test_hint_pooled_command_primary (void) -{ - _test_bulk_hint (true, true); -} - - -static void -test_bulk_reply_w0 (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t reply; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_insert_w0"); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_append (wc, &opts); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{}")); - mongoc_bulk_operation_update ( - bulk, tmp_bson ("{}"), tmp_bson ("{'$set': {'x': 1}}"), false); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{}")); - - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, &reply, &error), - error); - - ASSERT (bson_empty (&reply)); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_bulk_invalid_write_concern (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bson_t reply; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_bulk_invalid_write_concern"); - bulk = mongoc_collection_create_bulk_operation_with_opts ( - collection, tmp_bson ("{'writeConcern': {'w': 0, 'j': true}}")); - BSON_ASSERT (!mongoc_bulk_operation_insert_with_opts ( - bulk, tmp_bson ("{}"), NULL, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Bulk operation is invalid from prior error"); - - memset (&error, 0, sizeof (bson_error_t)); - BSON_ASSERT (!mongoc_bulk_operation_execute (bulk, &reply, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - - ASSERT (bson_empty (&reply)); - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -typedef enum { - BULK_REMOVE, - BULK_REMOVE_ONE, - BULK_REPLACE_ONE, - BULK_UPDATE, - BULK_UPDATE_ONE -} bulkop; - -static void -_test_bulk_collation (int w, int wire_version, bulkop op) -{ - mock_server_t *mock_server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - request_t *request; - future_t *future; - bson_t *opts; - const char *expect; - bool r; - - mock_server = mock_server_with_autoismaster (wire_version); - mock_server_run (mock_server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (mock_server)); - collection = mongoc_client_get_collection (client, "test", "test"); - - bulk = mongoc_collection_create_bulk_operation_with_opts ( - collection, tmp_bson ("{'writeConcern': {'w': %d, 'wtimeout': 100}}", w)); - - opts = BCON_NEW ("collation", - "{", - "locale", - BCON_UTF8 ("en_US"), - "caseFirst", - BCON_UTF8 ("lower"), - "}"); - - switch (op) { - case BULK_REMOVE: - r = mongoc_bulk_operation_remove_many_with_opts ( - bulk, tmp_bson ("{'_id': 1}"), opts, &error); - expect = "{'delete': 'test'," - " 'writeConcern': {'w': %d, 'wtimeout': 100}," - " 'ordered': true," - " 'deletes': [" - " {'q': {'_id': 1}, 'limit': 0, 'collation': { 'locale': " - "'en_US', 'caseFirst': 'lower'}}" - " ]" - "}"; - break; - case BULK_REMOVE_ONE: - r = mongoc_bulk_operation_remove_one_with_opts ( - bulk, tmp_bson ("{'_id': 2}"), opts, &error); - expect = "{'delete': 'test'," - " 'writeConcern': {'w': %d, 'wtimeout': 100}," - " 'ordered': true," - " 'deletes': [" - " {'q': {'_id': 2}, 'limit': 1, 'collation': { 'locale': " - "'en_US', 'caseFirst': 'lower'}}" - " ]" - "}"; - break; - case BULK_REPLACE_ONE: - r = mongoc_bulk_operation_replace_one_with_opts ( - bulk, tmp_bson ("{'_id': 3}"), tmp_bson ("{'_id': 4}"), opts, &error); - expect = "{'update': 'test'," - " 'writeConcern': {'w': %d, 'wtimeout': 100}," - " 'ordered': true," - " 'updates': [" - " {'q': {'_id': 3}, 'u': {'_id': 4}, 'collation': { " - "'locale': 'en_US', 'caseFirst': 'lower'}, 'multi': false}" - " ]" - "}"; - break; - case BULK_UPDATE: - r = mongoc_bulk_operation_update_many_with_opts ( - bulk, - tmp_bson ("{'_id': 5}"), - tmp_bson ("{'$set': {'_id': 6}}"), - opts, - &error); - expect = - "{'update': 'test'," - " 'writeConcern': {'w': %d, 'wtimeout': 100}," - " 'ordered': true," - " 'updates': [" - " {'q': {'_id': 5}, 'u': { '$set': {'_id': 6} }, 'collation': { " - "'locale': 'en_US', 'caseFirst': 'lower'}, 'multi': true }" - " ]" - "}"; - break; - case BULK_UPDATE_ONE: - r = mongoc_bulk_operation_update_one_with_opts ( - bulk, - tmp_bson ("{'_id': 7}"), - tmp_bson ("{'$set': {'_id': 8}}"), - opts, - &error); - expect = - "{'update': 'test'," - " 'writeConcern': {'w': %d, 'wtimeout': 100}," - " 'ordered': true," - " 'updates': [" - " {'q': {'_id': 7}, 'u': { '$set': {'_id': 8} }, 'collation': { " - "'locale': 'en_US', 'caseFirst': 'lower'}, 'multi': false}" - " ]" - "}"; - break; - default: - BSON_ASSERT (false); - } - - ASSERT_OR_PRINT (r, error); - future = future_bulk_operation_execute (bulk, &reply, &error); - - if (wire_version >= WIRE_VERSION_COLLATION && w) { - request = mock_server_receives_command ( - mock_server, "test", MONGOC_QUERY_NONE, expect, w); - - mock_server_replies_simple (request, "{'ok': 1.0, 'n': 1}"); - request_destroy (request); - ASSERT (future_get_uint32_t (future)); - future_destroy (future); - } else { - ASSERT (!future_get_uint32_t (future)); - future_destroy (future); - if (w) { - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } else { - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set collation for unacknowledged writes"); - } - } - - - bson_destroy (opts); - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (mock_server); -} - -static void -_test_bulk_collation_multi (int w, int wire_version) -{ - mock_server_t *mock_server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - request_t *request; - future_t *future; - - mock_server = mock_server_with_autoismaster (wire_version); - mock_server_run (mock_server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (mock_server)); - collection = mongoc_client_get_collection (client, "test", "test"); - bulk = mongoc_collection_create_bulk_operation_with_opts ( - collection, tmp_bson ("{'writeConcern': {'w': %d, 'wtimeout': 100}}", w)); - - mongoc_bulk_operation_remove_many_with_opts ( - bulk, tmp_bson ("{'_id': 1}"), NULL, &error); - - mongoc_bulk_operation_remove_many_with_opts ( - bulk, - tmp_bson ("{'_id': 2}"), - tmp_bson ("{'collation': {'locale': 'en_US', 'caseFirst': 'lower'}}"), - &error); - - future = future_bulk_operation_execute (bulk, &reply, &error); - - if (wire_version >= WIRE_VERSION_COLLATION && w) { - request = mock_server_receives_command (mock_server, - "test", - MONGOC_QUERY_NONE, - "{'delete': 'test'," - " 'ordered': true," - " 'deletes': [" - " {'q': {'_id': 1}}," - " {'q': {'_id': 2}, " - "'collation': { 'locale': " - "'en_US', 'caseFirst': 'lower'}}" - " ]" - "}"); - mock_server_replies_simple (request, "{'ok': 1.0, 'n': 1}"); - request_destroy (request); - ASSERT (future_get_uint32_t (future)); - future_destroy (future); - } else { - ASSERT (!future_get_uint32_t (future)); - future_destroy (future); - if (w) { - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } else { - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set collation for unacknowledged writes"); - } - } - - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (mock_server); -} - -void -test_bulk_collation_multi_w1_wire5 (void) -{ - _test_bulk_collation_multi (1, WIRE_VERSION_COLLATION); -} - -void -test_bulk_collation_multi_w0_wire5 (void) -{ - _test_bulk_collation_multi (0, WIRE_VERSION_COLLATION); -} - -void -test_bulk_collation_multi_w1_wire4 (void) -{ - _test_bulk_collation_multi (1, WIRE_VERSION_COLLATION - 1); -} - -void -test_bulk_collation_multi_w0_wire4 (void) -{ - _test_bulk_collation_multi (0, WIRE_VERSION_COLLATION - 1); -} - -void -test_bulk_collation_w1_wire5 (void) -{ - _test_bulk_collation (1, WIRE_VERSION_COLLATION, BULK_REMOVE); - _test_bulk_collation (1, WIRE_VERSION_COLLATION, BULK_REMOVE_ONE); - _test_bulk_collation (1, WIRE_VERSION_COLLATION, BULK_REPLACE_ONE); - _test_bulk_collation (1, WIRE_VERSION_COLLATION, BULK_UPDATE); - _test_bulk_collation (1, WIRE_VERSION_COLLATION, BULK_UPDATE_ONE); -} - -void -test_bulk_collation_w0_wire5 (void) -{ - _test_bulk_collation (0, WIRE_VERSION_COLLATION, BULK_REMOVE); - _test_bulk_collation (0, WIRE_VERSION_COLLATION, BULK_REMOVE_ONE); - _test_bulk_collation (0, WIRE_VERSION_COLLATION, BULK_REPLACE_ONE); - _test_bulk_collation (0, WIRE_VERSION_COLLATION, BULK_UPDATE); - _test_bulk_collation (0, WIRE_VERSION_COLLATION, BULK_UPDATE_ONE); -} - -void -test_bulk_collation_w1_wire4 (void) -{ - _test_bulk_collation (1, WIRE_VERSION_COLLATION - 1, BULK_REMOVE); - _test_bulk_collation (1, WIRE_VERSION_COLLATION - 1, BULK_REMOVE_ONE); - _test_bulk_collation (1, WIRE_VERSION_COLLATION - 1, BULK_REPLACE_ONE); - _test_bulk_collation (1, WIRE_VERSION_COLLATION - 1, BULK_UPDATE); - _test_bulk_collation (1, WIRE_VERSION_COLLATION - 1, BULK_UPDATE_ONE); -} - -void -test_bulk_collation_w0_wire4 (void) -{ - _test_bulk_collation (0, WIRE_VERSION_COLLATION - 1, BULK_REMOVE); - _test_bulk_collation (0, WIRE_VERSION_COLLATION - 1, BULK_REMOVE_ONE); - _test_bulk_collation (0, WIRE_VERSION_COLLATION - 1, BULK_REPLACE_ONE); - _test_bulk_collation (0, WIRE_VERSION_COLLATION - 1, BULK_UPDATE); - _test_bulk_collation (0, WIRE_VERSION_COLLATION - 1, BULK_UPDATE_ONE); -} - -static void -test_bulk_update_one_error_message (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - - client = mongoc_client_new ("mongodb://server"); - collection = mongoc_client_get_collection (client, "test", "test"); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - mongoc_bulk_operation_update_many_with_opts ( - bulk, - tmp_bson ("{'_id': 5}"), - tmp_bson ("{'set': {'_id': 6}}"), - NULL, - &error); - - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid key 'set': update only works with $ operators"); - - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_bulk_opts_parse (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *q = tmp_bson ("{'_id': 1}"); - bson_t *u = tmp_bson ("{'$set': {'x': 1}}"); - bson_t *repl = tmp_bson ("{'x': 1}"); - bson_error_t error; - bool r; - - client = mongoc_client_new ("mongodb://server"); - collection = mongoc_client_get_collection (client, "test", "test"); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - -#define RM_ERR(_msg, _fn, ...) \ - r = mongoc_bulk_operation_##_fn##_with_opts (bulk, q, __VA_ARGS__, &error); \ - BSON_ASSERT (!r); \ - ASSERT_ERROR_CONTAINS (error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - "Invalid " _msg) - -#define UPDATE_ERR(_msg, _fn, ...) \ - r = mongoc_bulk_operation_update_##_fn##_with_opts ( \ - bulk, q, u, __VA_ARGS__, &error); \ - BSON_ASSERT (!r); \ - ASSERT_ERROR_CONTAINS (error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - "Invalid " _msg) - -#define REPLACE_ERR(_msg, ...) \ - r = mongoc_bulk_operation_replace_one_with_opts ( \ - bulk, q, repl, __VA_ARGS__, &error); \ - BSON_ASSERT (!r); \ - ASSERT_ERROR_CONTAINS (error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - "Invalid " _msg) - - RM_ERR ("option 'foo'", remove_one, tmp_bson ("{'foo': 1}")); - RM_ERR ("option 'foo'", remove_many, tmp_bson ("{'foo': 1}")); - RM_ERR ("\"limit\" in opts: 2", remove_one, tmp_bson ("{'limit': 2}")); - RM_ERR ("\"limit\" in opts: 2", remove_many, tmp_bson ("{'limit': 2}")); - RM_ERR ("\"limit\" in opts: 0", remove_one, tmp_bson ("{'limit': 0}")); - RM_ERR ("\"limit\" in opts: 1", remove_many, tmp_bson ("{'limit': 1}")); - - UPDATE_ERR ("option 'foo'", one, tmp_bson ("{'foo': 1}")); - UPDATE_ERR ("option 'foo'", many, tmp_bson ("{'foo': 1}")); - UPDATE_ERR ("\"multi\" in opts: true", one, tmp_bson ("{'multi': true}")); - UPDATE_ERR ("\"multi\" in opts: false", many, tmp_bson ("{'multi': false}")); - - REPLACE_ERR ("option 'foo'", tmp_bson ("{'foo': 1}")); - REPLACE_ERR ("\"multi\": true in opts", tmp_bson ("{'multi': true}")); - -#define NO_ERR(_fn, ...) \ - ASSERT_OR_PRINT ( \ - mongoc_bulk_operation_##_fn##_with_opts (bulk, __VA_ARGS__, &error), \ - error) - - /* for some reason we allow "multi" and "limit", if they equal the default */ - NO_ERR (remove_one, q, tmp_bson ("{'limit': 1}")); - NO_ERR (remove_many, q, tmp_bson ("{'limit': 0}")); - NO_ERR (update_one, q, u, tmp_bson ("{'multi': false}")); - NO_ERR (update_many, q, u, tmp_bson ("{'multi': true}")); - NO_ERR (replace_one, q, repl, tmp_bson ("{'multi': false}")); - - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_bulk_no_client (void) -{ - mongoc_bulk_operation_t *bulk; - bson_t reply; - bson_error_t error; - - bulk = mongoc_bulk_operation_new (true /* ordered */); - BSON_ASSERT (!mongoc_bulk_operation_execute (bulk, &reply, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "requires a client"); - - /* reply was initialized */ - BSON_ASSERT (bson_empty (&reply)); - - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&reply); -} - - -static void -test_bulk_bypass_document_validation (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - uint32_t i; - bool r; - - client = test_framework_client_new (); - collection = get_test_collection (client, "bypass_validation"); - - /* bypassDocumentValidation can't be passed in opts */ - bulk = mongoc_collection_create_bulk_operation_with_opts ( - collection, tmp_bson ("{'bypassDocumentValidation': true}")); - - i = mongoc_bulk_operation_execute (bulk, NULL, &error); - ASSERT_CMPUINT32 (i, ==, (uint32_t) 0); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option 'bypassDocumentValidation'"); - - mongoc_bulk_operation_destroy (bulk); - - /* not allowed in insert opts either */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - r = mongoc_bulk_operation_insert_with_opts ( - bulk, - tmp_bson ("{}"), - tmp_bson ("{'bypassDocumentValidation': true}"), - &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option 'bypassDocumentValidation'"); - - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -void -test_bulk_install (TestSuite *suite) -{ - TestSuite_AddLive (suite, "/BulkOperation/basic", test_bulk); - TestSuite_AddLive (suite, "/BulkOperation/opts", test_opts); - TestSuite_AddMockServerTest (suite, "/BulkOperation/error", test_bulk_error); - TestSuite_AddMockServerTest ( - suite, "/BulkOperation/error/unordered", test_bulk_error_unordered); - TestSuite_AddLive ( - suite, "/BulkOperation/insert_ordered", test_insert_ordered); - TestSuite_AddLive ( - suite, "/BulkOperation/insert_unordered", test_insert_unordered); - TestSuite_AddLive ( - suite, "/BulkOperation/insert_check_keys", test_insert_check_keys); - TestSuite_AddLive ( - suite, "/BulkOperation/update_ordered", test_update_ordered); - TestSuite_AddLive ( - suite, "/BulkOperation/update_unordered", test_update_unordered); - TestSuite_AddLive (suite, - "/BulkOperation/update_one_check_keys", - test_update_one_check_keys); - TestSuite_AddLive ( - suite, "/BulkOperation/update_check_keys", test_update_check_keys); - TestSuite_AddLive (suite, - "/BulkOperation/update_one_with_opts_check_keys", - test_update_one_with_opts_check_keys); - TestSuite_AddLive (suite, - "/BulkOperation/update_many_with_opts_check_keys", - test_update_many_with_opts_check_keys); - TestSuite_AddLive (suite, - "/BulkOperation/update_one_invalid_first", - test_update_one_invalid_first); - TestSuite_AddLive ( - suite, "/BulkOperation/update_invalid_first", test_update_invalid_first); - TestSuite_AddLive (suite, - "/BulkOperation/update_one_with_opts_invalid_first", - test_update_one_with_opts_invalid_first); - TestSuite_AddLive (suite, - "/BulkOperation/update_many_with_opts_invalid_first", - test_update_many_with_opts_invalid_first); - TestSuite_AddLive (suite, - "/BulkOperation/replace_one_invalid_first", - test_replace_one_invalid_first); - TestSuite_AddLive (suite, - "/BulkOperation/replace_one_with_opts_invalid_first", - test_replace_one_with_opts_invalid_first); - TestSuite_AddLive (suite, - "/BulkOperation/update_one_invalid_second", - test_update_one_invalid_second); - TestSuite_AddLive (suite, - "/BulkOperation/update_invalid_second", - test_update_invalid_second); - TestSuite_AddLive (suite, - "/BulkOperation/update_one_with_opts_invalid_second", - test_update_one_with_opts_invalid_second); - TestSuite_AddLive (suite, - "/BulkOperation/update_many_with_opts_invalid_second", - test_update_many_with_opts_invalid_second); - TestSuite_AddLive (suite, - "/BulkOperation/replace_one_invalid_second", - test_replace_one_invalid_second); - TestSuite_AddLive (suite, - "/BulkOperation/replace_one_with_opts_invalid_second", - test_replace_one_with_opts_invalid_second); - TestSuite_AddLive ( - suite, "/BulkOperation/insert_invalid_first", test_insert_invalid_first); - TestSuite_AddLive (suite, - "/BulkOperation/insert_invalid_second", - test_insert_invalid_second); - TestSuite_AddLive (suite, - "/BulkOperation/insert_with_opts_invalid_first", - test_insert_with_opts_invalid_first); - TestSuite_AddLive (suite, - "/BulkOperation/insert_with_opts_invalid_second", - test_insert_with_opts_invalid_second); - TestSuite_AddLive (suite, - "/BulkOperation/insert_with_opts_validate", - test_insert_with_opts_validate); - TestSuite_AddLive (suite, - "/BulkOperation/remove_one_after_invalid", - test_remove_one_after_invalid); - TestSuite_AddLive ( - suite, "/BulkOperation/remove_after_invalid", test_remove_after_invalid); - TestSuite_AddLive (suite, - "/BulkOperation/remove_one_with_opts_after_invalid", - test_remove_one_with_opts_after_invalid); - TestSuite_AddLive (suite, - "/BulkOperation/remove_many_with_opts_after_invalid", - test_remove_many_with_opts_after_invalid); - 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", - 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_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, - test_framework_skip_if_max_wire_version_less_than_6); - TestSuite_AddFull (suite, - "/BulkOperation/update_arrayfilters/unsupported", - test_update_arrayfilters_unsupported, - NULL, - NULL, - test_framework_skip_if_max_wire_version_more_than_5); - TestSuite_AddLive ( - suite, "/BulkOperation/replace_one_ordered", test_replace_one_ordered); - TestSuite_AddLive (suite, - "/BulkOperation/replace_one_unordered", - test_replace_one_unordered); - TestSuite_AddLive ( - suite, "/BulkOperation/replace_one/keys", test_replace_one_check_keys); - TestSuite_AddLive (suite, - "/BulkOperation/replace_one_with_opts/keys", - test_replace_one_with_opts_check_keys); - TestSuite_AddLive (suite, - "/BulkOperation/replace_one_with_opts_validate", - test_replace_one_with_opts_validate); - TestSuite_AddLive (suite, "/BulkOperation/index_offset", test_index_offset); - TestSuite_AddLive ( - suite, "/BulkOperation/single_ordered_bulk", test_single_ordered_bulk); - TestSuite_AddLive (suite, - "/BulkOperation/insert_continue_on_error", - test_insert_continue_on_error); - TestSuite_AddLive (suite, - "/BulkOperation/update_continue_on_error", - test_update_continue_on_error); - TestSuite_AddLive (suite, - "/BulkOperation/remove_continue_on_error", - test_remove_continue_on_error); - TestSuite_AddLive (suite, - "/BulkOperation/single_error_ordered_bulk", - test_single_error_ordered_bulk); - TestSuite_AddLive (suite, - "/BulkOperation/multiple_error_ordered_bulk", - test_multiple_error_ordered_bulk); - 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", - test_oversized_bulk_op_ordered, - NULL, - NULL, - test_framework_skip_if_slow_or_live); - TestSuite_AddFull (suite, - "/BulkOperation/oversized/unordered", - test_oversized_bulk_op_unordered, - NULL, - NULL, - test_framework_skip_if_slow_or_live); - TestSuite_AddMockServerTest ( - suite, - "/BulkOperation/write_concern/write_command/ordered", - test_write_concern_write_command_ordered); - TestSuite_AddMockServerTest ( - suite, - "/BulkOperation/write_concern/write_command/ordered/multi_err", - test_write_concern_write_command_ordered_multi_err); - TestSuite_AddMockServerTest ( - suite, - "/BulkOperation/write_concern/write_command/unordered", - test_write_concern_write_command_unordered); - TestSuite_AddMockServerTest ( - suite, - "/BulkOperation/write_concern/write_command/unordered/multi_err", - test_write_concern_write_command_unordered_multi_err); - TestSuite_AddMockServerTest ( - suite, - "/BulkOperation/write_concern/error/write_command/v1", - test_write_concern_error_write_command_v1); - TestSuite_AddMockServerTest ( - suite, - "/BulkOperation/write_concern/error/write_command/v2", - test_write_concern_error_write_command_v2); - TestSuite_AddLive (suite, - "/BulkOperation/multiple_error_unordered_bulk", - test_multiple_error_unordered_bulk); - TestSuite_AddMockServerTest ( - suite, - "/BulkOperation/wtimeout_duplicate_key/write_commands", - test_wtimeout_plus_duplicate_key_err_write_commands); - TestSuite_AddFull (suite, - "/BulkOperation/large_inserts_ordered", - test_large_inserts_ordered, - NULL, - NULL, - test_framework_skip_if_slow_or_live); - TestSuite_AddFull (suite, - "/BulkOperation/large_inserts_unordered", - 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", - test_numerous_unordered, - NULL, - NULL, - test_framework_skip_if_slow_or_live); - TestSuite_AddLive (suite, - "/BulkOperation/CDRIVER-372_ordered", - test_bulk_edge_case_372_ordered); - TestSuite_AddLive (suite, - "/BulkOperation/CDRIVER-372_unordered", - test_bulk_edge_case_372_unordered); - TestSuite_AddLive (suite, "/BulkOperation/new", test_bulk_new); - 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_AddLive (suite, "/BulkOperation/split", test_bulk_split); - TestSuite_AddLive (suite, - "/BulkOperation/write_concern/split", - test_bulk_write_concern_split); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/hint/single/command/secondary", - test_hint_single_command_secondary); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/hint/single/command/primary", - test_hint_single_command_primary); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/hint/pooled/command/secondary", - test_hint_pooled_command_secondary); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/hint/pooled/command/primary", - test_hint_pooled_command_primary); - TestSuite_AddLive (suite, "/BulkOperation/reply_w0", test_bulk_reply_w0); - TestSuite_AddLive (suite, - "/BulkOperation/invalid_write_concern", - test_bulk_invalid_write_concern); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/opts/collation/w0/wire5", - test_bulk_collation_w0_wire5); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/opts/collation/w0/wire4", - test_bulk_collation_w0_wire4); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/opts/collation/w1/wire5", - test_bulk_collation_w1_wire5); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/opts/collation/w1/wire4", - test_bulk_collation_w1_wire4); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/opts/collation/multi/w0/wire5", - test_bulk_collation_multi_w0_wire5); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/opts/collation/multi/w0/wire4", - test_bulk_collation_multi_w0_wire4); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/opts/collation/multi/w1/wire5", - test_bulk_collation_multi_w1_wire5); - TestSuite_AddMockServerTest (suite, - "/BulkOperation/opts/collation/multi/w1/wire4", - test_bulk_collation_multi_w1_wire4); - TestSuite_Add (suite, - "/BulkOperation/update_one/error_message", - test_bulk_update_one_error_message); - TestSuite_Add (suite, "/BulkOperation/opts/parse", test_bulk_opts_parse); - TestSuite_Add (suite, "/BulkOperation/no_client", test_bulk_no_client); - TestSuite_AddLive ( - suite, "/BulkOperation/bypass", test_bulk_bypass_document_validation); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-change-stream.c b/lib/mongoc/libmongoc/tests/test-mongoc-change-stream.c deleted file mode 100644 index 0ad6e225c050882b8b70868e448e24d968d8bbf8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-change-stream.c +++ /dev/null @@ -1,2678 +0,0 @@ -/* - * Copyright 2017-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 <mongoc/mongoc.h> -#include "mongoc/mongoc-client-private.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mongoc/mongoc-change-stream-private.h" -#include "mongoc/mongoc-cursor-private.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "TestSuite.h" -#include "json-test.h" -#include "json-test-operations.h" - -#define DESTROY_CHANGE_STREAM(cursor_id) \ - do { \ - future_t *_future = future_change_stream_destroy (stream); \ - request_t *_request = mock_server_receives_command ( \ - server, \ - "db", \ - MONGOC_QUERY_SLAVE_OK, \ - "{ 'killCursors' : 'coll', 'cursors' : [ " #cursor_id " ] }"); \ - mock_server_replies_simple (_request, \ - "{ 'cursorsKilled': [ " #cursor_id " ] }"); \ - future_wait (_future); \ - future_destroy (_future); \ - request_destroy (_request); \ - } while (0); - - -typedef struct _data_change_stream_t { - mongoc_cursor_response_t response; - bson_t post_batch_resume_token; -} _data_change_stream_t; - - -static int -test_framework_skip_if_not_single_version_5 (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return (test_framework_max_wire_version_at_least (5) && - !test_framework_is_replset () && !test_framework_is_mongos ()) - ? 1 - : 0; -} - -static mongoc_collection_t * -drop_and_get_coll (mongoc_client_t *client, - const char *db_name, - const char *coll_name) -{ - mongoc_collection_t *coll = - mongoc_client_get_collection (client, db_name, coll_name); - mongoc_collection_drop (coll, NULL); - return coll; -} - -/* From Change Streams Spec tests: - * "$changeStream must be the first stage in a change stream pipeline sent - * to the server" */ -static void -test_change_stream_pipeline (void) -{ - mock_server_t *server; - request_t *request; - future_t *future; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *next_doc = NULL; - bson_t *nonempty_pipeline = - tmp_bson ("{ 'pipeline' : [ { '$project' : { 'ns': false } } ] }"); - - server = mock_server_with_autoismaster (5); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT (client); - - coll = mongoc_client_get_collection (client, "db", "coll"); - ASSERT (coll); - - future = future_collection_watch (coll, tmp_bson ("{}"), NULL); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{" - "'aggregate' : 'coll'," - "'pipeline' : " - " [" - " { '$changeStream':{ 'fullDocument' : 'default' } }" - " ]," - "'cursor' : {}" - "}"); - - mock_server_replies_simple ( - request, - "{'cursor' : {'id': 123, 'ns': 'db.coll', 'firstBatch': []}, 'ok': 1 }"); - - stream = future_get_mongoc_change_stream_ptr (future); - ASSERT (stream); - - future_destroy (future); - request_destroy (request); - - future = future_change_stream_next (stream, &next_doc); - - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'getMore': 123, 'collection': 'coll'}"); - mock_server_replies_simple (request, - "{'cursor' : { 'nextBatch' : [] }, 'ok': 1}"); - ASSERT (!future_get_bool (future)); - ASSERT (!mongoc_change_stream_error_document (stream, NULL, NULL)); - ASSERT (next_doc == NULL); - future_destroy (future); - request_destroy (request); - - /* Another call to next should produce another getMore */ - future = future_change_stream_next (stream, &next_doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 123, 'collection': 'coll' }"); - mock_server_replies_simple (request, - "{ 'cursor': { 'nextBatch': [] }, 'ok': 1 }"); - ASSERT (!future_get_bool (future)); - ASSERT (!mongoc_change_stream_error_document (stream, NULL, NULL)); - ASSERT (next_doc == NULL); - future_destroy (future); - request_destroy (request); - - DESTROY_CHANGE_STREAM (123); - - /* Test non-empty pipeline */ - future = future_collection_watch (coll, nonempty_pipeline, NULL); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{" - "'aggregate' : 'coll'," - "'pipeline' : " - " [" - " { '$changeStream':{ 'fullDocument' : 'default' } }," - " { '$project': { 'ns': false } }" - " ]," - "'cursor' : {}" - "}"); - mock_server_replies_simple ( - request, - "{'cursor': {'id': 123, 'ns': 'db.coll','firstBatch': []},'ok': 1}"); - - stream = future_get_mongoc_change_stream_ptr (future); - ASSERT (stream); - - future_destroy (future); - request_destroy (request); - - - future = future_change_stream_next (stream, &next_doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 123, 'collection': 'coll' }"); - mock_server_replies_simple (request, - "{ 'cursor': { 'nextBatch': [] }, 'ok': 1 }"); - ASSERT (!future_get_bool (future)); - ASSERT (!mongoc_change_stream_error_document (stream, NULL, NULL)); - ASSERT (next_doc == NULL); - future_destroy (future); - request_destroy (request); - - DESTROY_CHANGE_STREAM (123); - - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); - mock_server_destroy (server); -} - -/* From Change Streams Spec tests: - * "The watch helper must not throw a custom exception when executed against a - * single server topology, but instead depend on a server error" - */ -static void -test_change_stream_live_single_server (void *test_ctx) -{ - /* Temporarily skip on arm64 until mongod tested against is updated */ - mongoc_client_t *client = test_framework_client_new (); - mongoc_collection_t *coll; - bson_error_t error; - mongoc_change_stream_t *stream; - const bson_t *next_doc = NULL; - const bson_t *reported_err_doc = NULL; - const char *not_replset_doc = "{'errmsg': 'The $changeStream stage is " - "only supported on replica sets', 'code': " - "40573, 'ok': 0}"; - - /* Don't use the errmsg field since it contains quotes. */ - const char *not_supported_doc = "{'code' : 40324, 'ok' : 0 }"; - - ASSERT (client); - - coll = mongoc_client_get_collection (client, "db", "coll"); - ASSERT (coll); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), NULL, NULL, &error), - error); - - stream = mongoc_collection_watch (coll, tmp_bson ("{}"), NULL); - ASSERT (stream); - - ASSERT ( - mongoc_change_stream_error_document (stream, NULL, &reported_err_doc)); - ASSERT (next_doc == NULL); - - if (test_framework_max_wire_version_at_least (6)) { - ASSERT_MATCH (reported_err_doc, not_replset_doc); - } else { - ASSERT_MATCH (reported_err_doc, not_supported_doc); - ASSERT_CONTAINS (bson_lookup_utf8 (reported_err_doc, "errmsg"), - "Unrecognized pipeline stage"); - } - - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); -} - - -typedef struct _test_resume_token_ctx_t { - bool expecting_resume_token; - const bson_t *expected_resume_token_bson; -} test_resume_token_ctx_t; - -static void -test_resume_token_command_start (const mongoc_apm_command_started_t *event) -{ - const bson_t *cmd = mongoc_apm_command_started_get_command (event); - const char *cmd_name = mongoc_apm_command_started_get_command_name (event); - - test_resume_token_ctx_t *ctx = - (test_resume_token_ctx_t *) mongoc_apm_command_started_get_context ( - event); - - if (strcmp (cmd_name, "aggregate") == 0) { - if (ctx->expecting_resume_token) { - char *rt_pattern = bson_as_canonical_extended_json ( - ctx->expected_resume_token_bson, NULL); - char *pattern = - bson_strdup_printf ("{'aggregate': 'coll_resume', 'pipeline': " - "[{'$changeStream': { 'resumeAfter': %s }}]}", - rt_pattern); - ASSERT_MATCH (cmd, pattern); - bson_free (pattern); - bson_free (rt_pattern); - } else { - ASSERT_MATCH (cmd, - "{'aggregate': 'coll_resume', 'pipeline': [{ " - "'$changeStream': { 'resumeAfter': { '$exists': " - "false } }}]}"); - } - } -} - -/* From Change Streams Spec tests: - * "ChangeStream must continuously track the last seen resumeToken" - * Note: we should not inspect the resume token, since the format may change. - */ -static void -test_change_stream_live_track_resume_token (void *test_ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - bson_error_t error; - test_resume_token_ctx_t ctx = {0}; - const bson_t *next_doc = NULL; - mongoc_apm_callbacks_t *callbacks; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t opts = BSON_INITIALIZER; - bson_t doc0_rt, doc1_rt, doc2_rt; - const bson_t *resume_token; - - client = test_framework_client_new (); - ASSERT (client); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, - test_resume_token_command_start); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - - coll = drop_and_get_coll (client, "db", "coll_resume"); - ASSERT (coll); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), NULL, NULL, &error), - error); - - /* Set the batch size to 1 so we only get one document per call to next. */ - stream = mongoc_collection_watch ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 1}")); - ASSERT (stream); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - - /* Insert a few docs to listen for. Use write concern majority, so subsequent - * call to watch will be guaranteed to retrieve them. */ - mongoc_write_concern_set_wmajority (wc, 30000); - mongoc_write_concern_append (wc, &opts); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 0}"), &opts, NULL, &error), - error); - - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 1}"), &opts, NULL, &error), - error); - - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 2}"), &opts, NULL, &error), - error); - - /* The resume token should be updated to the most recently iterated doc */ - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - ASSERT (next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - bson_copy_to (resume_token, &doc0_rt); - - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - ASSERT (next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - ASSERT (bson_compare (resume_token, &doc0_rt) != 0); - bson_copy_to (resume_token, &doc1_rt); - - _mongoc_client_kill_cursor (client, - stream->cursor->server_id, - mongoc_cursor_get_id (stream->cursor), - 1 /* operation id */, - "db", - "coll_resume", - NULL /* session */); - - /* Now that the cursor has been killed, the next call to next will have to - * resume, forcing it to send the resumeAfter token in the aggregate cmd. */ - ctx.expecting_resume_token = true; - ctx.expected_resume_token_bson = &doc1_rt; - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - - ASSERT (next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - ASSERT (bson_compare (resume_token, &doc0_rt) != 0); - ASSERT (bson_compare (resume_token, &doc1_rt) != 0); - bson_copy_to (resume_token, &doc2_rt); - - /* There are no docs left. But the next call should still keep the same - * resume token */ - ASSERT (!mongoc_change_stream_next (stream, &next_doc)); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - ASSERT (!next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - ASSERT (bson_compare (resume_token, &doc2_rt) == 0); - - bson_destroy (&doc0_rt); - bson_destroy (&doc1_rt); - bson_destroy (&doc2_rt); - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); -} - -typedef struct _test_batch_size_ctx { - uint32_t num_get_mores; - uint32_t expected_getmore_batch_size; - uint32_t expected_agg_batch_size; -} test_batch_size_ctx_t; - -static void -test_batch_size_command_succeeded (const mongoc_apm_command_succeeded_t *event) -{ - const bson_t *reply = mongoc_apm_command_succeeded_get_reply (event); - const char *cmd_name = mongoc_apm_command_succeeded_get_command_name (event); - - test_batch_size_ctx_t *ctx = - (test_batch_size_ctx_t *) mongoc_apm_command_succeeded_get_context ( - event); - - if (strcmp (cmd_name, "getMore") == 0) { - bson_t next_batch; - ++ctx->num_get_mores; - bson_lookup_doc (reply, "cursor.nextBatch", &next_batch); - ASSERT (bson_count_keys (&next_batch) == - ctx->expected_getmore_batch_size); - } else if (strcmp (cmd_name, "aggregate") == 0) { - bson_t first_batch; - bson_lookup_doc (reply, "cursor.firstBatch", &first_batch); - ASSERT (bson_count_keys (&first_batch) == ctx->expected_agg_batch_size); - } -} -/* Test that the batch size option applies to both the initial aggregate and - * subsequent getMore commands. - */ -static void -test_change_stream_live_batch_size (void *test_ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - test_batch_size_ctx_t ctx = {0}; - const bson_t *next_doc = NULL; - mongoc_apm_callbacks_t *callbacks; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t opts = BSON_INITIALIZER; - bson_error_t err; - uint32_t i; - - client = test_framework_client_new (); - ASSERT (client); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_succeeded_cb (callbacks, - test_batch_size_command_succeeded); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - - coll = drop_and_get_coll (client, "db", "coll_batch"); - ASSERT (coll); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), NULL, NULL, &err), - err); - - stream = mongoc_collection_watch ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 1}")); - ASSERT (stream); - - ctx.expected_agg_batch_size = 0; - ctx.expected_getmore_batch_size = 0; - - ASSERT (!mongoc_change_stream_next (stream, &next_doc)); - ASSERT (!mongoc_change_stream_error_document (stream, NULL, NULL)); - ASSERT (next_doc == NULL); - - ctx.expected_getmore_batch_size = 1; - - mongoc_write_concern_set_wmajority (wc, 30000); - mongoc_write_concern_append (wc, &opts); - for (i = 0; i < 10; i++) { - bson_t *doc = BCON_NEW ("_id", BCON_INT32 (i)); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, doc, &opts, NULL, &err), err); - bson_destroy (doc); - } - - ctx.expected_getmore_batch_size = 1; - for (i = 0; i < 10; i++) { - mongoc_change_stream_next (stream, &next_doc); - } - - ctx.expected_getmore_batch_size = 0; - ASSERT (!mongoc_change_stream_next (stream, &next_doc)); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, NULL), - err); - ASSERT (next_doc == NULL); - - /* 10 getMores for results, 1 for initial next, 1 for last empty next */ - ASSERT (ctx.num_get_mores == 12); - - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); -} - - -/* From Change Streams Spec tests: - * "ChangeStream will throw an exception if the server response is missing the - * resume token." In the C driver case, return an error. - */ -static void -_test_resume_token_error (const char *id_projection) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - const bson_t *next_doc = NULL; - mongoc_change_stream_t *stream; - bson_error_t err; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t opts = BSON_INITIALIZER; - - client = test_framework_client_new (); - ASSERT (client); - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - - coll = drop_and_get_coll (client, "db", "coll_missing_resume"); - ASSERT (coll); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), NULL, NULL, &err), - err); - - stream = mongoc_collection_watch ( - coll, - tmp_bson ("{'pipeline': [{'$project': {'_id': %s }}]}", id_projection), - NULL); - - ASSERT (stream); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, NULL), - err); - - mongoc_write_concern_set_wmajority (wc, 30000); - mongoc_write_concern_append (wc, &opts); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 2}"), &opts, NULL, &err), - err); - - ASSERT (!mongoc_change_stream_next (stream, &next_doc)); - ASSERT (mongoc_change_stream_error_document (stream, &err, NULL)); - - /* Newer server versions emit different errors. */ - if (!test_framework_max_wire_version_at_least (8)) { - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CHANGE_STREAM_NO_RESUME_TOKEN, - "Cannot provide resume functionality"); - } else { - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_SERVER, - 280, - "Only transformations that retain the unmodified " - "_id field are allowed."); - } - - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); -} - -static void -test_change_stream_live_missing_resume_token (void *test_ctx) -{ - _test_resume_token_error ("0"); -} - -static void -test_change_stream_live_invalid_resume_token (void *test_ctx) -{ - /* test a few non-document BSON types */ - _test_resume_token_error ("{'$literal': 1}"); - _test_resume_token_error ("{'$literal': true}"); - _test_resume_token_error ("{'$literal': 'foo'}"); - _test_resume_token_error ("{'$literal': []}"); -} - -static void -_test_getmore_error (const char *server_reply, - bool should_resume, - bool resume_kills_cursor) -{ - mock_server_t *server; - request_t *request; - future_t *future; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *next_doc = NULL; - - server = mock_server_with_autoismaster (5); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - coll = mongoc_client_get_collection (client, "db", "coll"); - future = future_collection_watch (coll, tmp_bson ("{}"), NULL); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{ 'aggregate': 'coll' }"); - mock_server_replies_simple ( - request, - "{'cursor': {'id': 123, 'ns': 'db.coll','firstBatch': []},'ok': 1 }"); - stream = future_get_mongoc_change_stream_ptr (future); - BSON_ASSERT (stream); - future_destroy (future); - request_destroy (request); - - /* the first getMore receives an error. */ - future = future_change_stream_next (stream, &next_doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 123, 'collection': 'coll' }"); - mock_server_replies_simple (request, server_reply); - request_destroy (request); - if (should_resume) { - /* client should retry the aggregate. */ - if (resume_kills_cursor) { - /* errors that are considered "not master" or "node is recovering" - * errors by SDAM will mark the connected server as UNKNOWN, and no - * killCursors will be executed. */ - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'killCursors': 'coll'}"); - mock_server_replies_simple (request, "{'cursorsKilled': [123]}"); - request_destroy (request); - } - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{ 'aggregate': 'coll' }"); - mock_server_replies_simple (request, - "{'cursor':" - " {'id': 124," - " 'ns': 'db.coll'," - " 'firstBatch':" - " [{'_id': {'resume': 'doc'}}]}," - "'ok': 1}"); - request_destroy (request); - BSON_ASSERT (future_get_bool (future)); - BSON_ASSERT (!mongoc_change_stream_error_document (stream, NULL, NULL)); - DESTROY_CHANGE_STREAM (124); - } else { - BSON_ASSERT (!future_get_bool (future)); - BSON_ASSERT (mongoc_change_stream_error_document (stream, NULL, NULL)); - DESTROY_CHANGE_STREAM (123); - } - future_destroy (future); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -/* Test a variety of resumable and non-resumable errors that may be returned - * from a getMore. */ -static void -test_getmore_errors (void) -{ - _test_getmore_error ("{'ok': 0, 'code': 1, 'errmsg': 'internal error'}", - true /* should_resume */, - true /* resume_kills_cursor */); - _test_getmore_error ("{'ok': 0, 'code': 6, 'errmsg': 'host unreachable'}", - true /* should_resume */, - true /* resume_kills_cursor */); - _test_getmore_error ("{'ok': 0, 'code': 12345, 'errmsg': 'random error'}", - true /* should_resume */, - true /* resume_kills_cursor */); - /* most error codes are resumable, excluding a few blacklisted ones. */ - _test_getmore_error ("{'ok': 0, 'code': 11601, 'errmsg': 'interrupted'}", - false /* should_resume */, - false /* ignored */); - _test_getmore_error ( - "{'ok': 0, 'code': 136, 'errmsg': 'capped position lost'}", - false /* should_resume */, - true /* resume_kills_cursor */); - _test_getmore_error ("{'ok': 0, 'code': 237, 'errmsg': 'cursor killed'}", - false /* should_resume */, - false /* ignored */); - /* if the error code is missing, a message containing 'not master' or 'node - * is recovering' is still considered resumable. */ - _test_getmore_error ("{'ok': 0, 'errmsg': 'not master'}", - true /* should_resume */, - false /* resume_kills_cursor */); - _test_getmore_error ("{'ok': 0, 'errmsg': 'node is recovering'}", - true /* should_resume */, - false /* resume_kills_cursor */); - _test_getmore_error ("{'ok': 0, 'errmsg': 'random error'}", - false /* should_resume */, - false /* resume_kills_cursor */); - /* An error with a 'NonResumableChangeStreamError' label should not attempt - * to resume. */ - _test_getmore_error ( - "{'ok': 0, 'code': 280, 'errorLabels': " - "['NonResumableChangeStreamError'], 'errmsg': 'random error'}", - false /* should_resume */, - false /* resume_kills_cursor */); - /* But other error labels should resume. */ - _test_getmore_error ( - "{'ok': 0, 'code': 280, 'errorLabels': " - "['NonRetryableChangeStreamError'], 'errmsg': 'random error'}", - true /* should_resume */, - true /* resume_kills_cursor */); -} -/* From Change Streams Spec tests: - * "ChangeStream will automatically resume one time on a resumable error - * (including not master) with the initial pipeline and options, except for the - * addition/update of a resumeToken" - * "The killCursors command sent during the “Resume Process†must not be - * allowed to throw an exception." - */ -static void -test_change_stream_resumable_error (void) -{ - mock_server_t *server; - request_t *request; - future_t *future; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - mongoc_uri_t *uri; - bson_error_t err; - const bson_t *err_doc = NULL; - const bson_t *next_doc = NULL; - const char *not_master_err = - "{ 'code': 10107, 'errmsg': 'not master', 'ok': 0 }"; - const char *interrupted_err = - "{ 'code': 11601, 'errmsg': 'interrupted', 'ok': 0 }"; - const char *watch_cmd = - "{ 'aggregate': 'coll', 'pipeline' " - ": [ { '$changeStream': { 'fullDocument': 'default' } } ], " - "'cursor': { } }"; - - server = mock_server_with_autoismaster (5); - mock_server_run (server); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "socketTimeoutMS", 100); - client = mongoc_client_new_from_uri (uri); - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - coll = mongoc_client_get_collection (client, "db", "coll"); - - future = future_collection_watch (coll, tmp_bson ("{}"), NULL); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, watch_cmd); - - mock_server_replies_simple (request, - "{'cursor': {'id': 123, 'ns': " - "'db.coll','firstBatch': []},'ok': 1 " - "}"); - - stream = future_get_mongoc_change_stream_ptr (future); - ASSERT (stream); - - future_destroy (future); - request_destroy (request); - - /* Test that a network hangup results in a resumable error */ - future = future_change_stream_next (stream, &next_doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 123, 'collection': 'coll' }"); - mock_server_hangs_up (request); - request_destroy (request); - - /* Retry command */ - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, watch_cmd); - mock_server_replies_simple ( - request, - "{'cursor': {'id': 124,'ns': 'db.coll','firstBatch': []},'ok': 1 }"); - request_destroy (request); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 124, 'collection': 'coll' }"); - mock_server_replies_simple (request, - "{ 'cursor': { 'nextBatch': [] }, 'ok': 1 }"); - request_destroy (request); - ASSERT (!future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, NULL), - err); - ASSERT (next_doc == NULL); - future_destroy (future); - - /* Test the "notmaster" resumable error occurring twice in a row */ - future = future_change_stream_next (stream, &next_doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 124, 'collection': 'coll' }"); - mock_server_replies_simple (request, not_master_err); - request_destroy (request); - - /* Retry command */ - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, watch_cmd); - mock_server_replies_simple (request, - "{'cursor': {'id': 125, 'ns': " - "'db.coll','firstBatch': []},'ok': 1 " - "}"); - request_destroy (request); - - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 125, 'collection': 'coll' }"); - mock_server_replies_simple (request, not_master_err); - request_destroy (request); - - /* Retry command */ - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, watch_cmd); - mock_server_replies_simple (request, - "{'cursor': {'id': 126, 'ns': " - "'db.coll','firstBatch': []},'ok': 1 " - "}"); - request_destroy (request); - - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 126, 'collection': 'coll' }"); - mock_server_replies_simple (request, interrupted_err); - request_destroy (request); - - /* Check that error is returned */ - ASSERT (!future_get_bool (future)); - ASSERT (mongoc_change_stream_error_document (stream, &err, &err_doc)); - ASSERT (next_doc == NULL); - ASSERT_ERROR_CONTAINS (err, MONGOC_ERROR_SERVER, 11601, "interrupted"); - ASSERT_MATCH (err_doc, interrupted_err); - future_destroy (future); - DESTROY_CHANGE_STREAM (126); - - /* Test an error on the initial aggregate when resuming. */ - future = future_collection_watch (coll, tmp_bson ("{}"), NULL); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, watch_cmd); - mock_server_replies_simple (request, - "{'cursor': {'id': 123, 'ns': " - "'db.coll','firstBatch': []},'ok': 1 " - "}"); - stream = future_get_mongoc_change_stream_ptr (future); - ASSERT (stream); - request_destroy (request); - future_destroy (future); - - future = future_change_stream_next (stream, &next_doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 123, 'collection': 'coll' }"); - mock_server_replies_simple ( - request, "{ 'code': 10107, 'errmsg': 'not master', 'ok': 0 }"); - request_destroy (request); - - /* Retry command */ - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, watch_cmd); - mock_server_replies_simple (request, - "{'code': 123, 'errmsg': 'bad cmd', 'ok': 0}"); - request_destroy (request); - - /* Check that error is returned */ - ASSERT (!future_get_bool (future)); - ASSERT (mongoc_change_stream_error_document (stream, &err, &err_doc)); - ASSERT (next_doc == NULL); - ASSERT_ERROR_CONTAINS (err, MONGOC_ERROR_SERVER, 123, "bad cmd"); - ASSERT_MATCH (err_doc, "{'code': 123, 'errmsg': 'bad cmd', 'ok': 0}"); - future_destroy (future); - - mongoc_change_stream_destroy (stream); - mongoc_uri_destroy (uri); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -/* Test that options are sent correctly. - */ -static void -test_change_stream_options (void) -{ - mock_server_t *server; - request_t *request; - future_t *future; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *next_doc = NULL; - bson_error_t err; - - server = mock_server_with_autoismaster (5); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT (client); - - coll = mongoc_client_get_collection (client, "db", "coll"); - ASSERT (coll); - - - /* - * fullDocument: 'default'|'updateLookup', passed to $changeStream stage - * resumeAfter: optional<Doc>, passed to $changeStream stage - * startAfter: optional<Doc>, passed to $changeStream stage - * startAtOperationTime: optional<Timestamp>, passed to $changeStream stage - * maxAwaitTimeMS: Optional<Int64>, passed to cursor - * batchSize: Optional<Int32>, passed as agg option, {cursor: { batchSize: }} - * collation: Optional<Document>, passed as agg option - */ - - /* fullDocument */ - future = future_collection_watch ( - coll, - tmp_bson ("{}"), - tmp_bson ("{ 'fullDocument': 'updateLookup', " - "'resumeAfter': {'resume': 'after'}, " - "'startAfter': {'start': 'after'}, " - "'startAtOperationTime': { '$timestamp': { 't': 1, 'i': 1 }}, " - "'maxAwaitTimeMS': 5000, 'batchSize': " - "5, 'collation': { 'locale': 'en' }}")); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{" - "'aggregate': 'coll'," - "'pipeline': " - " [" - " { '$changeStream': {" - "'fullDocument': 'updateLookup', " - "'resumeAfter': {'resume': 'after'}, " - "'startAfter': {'start': 'after'}, " - "'startAtOperationTime': { '$timestamp': { 't': 1, 'i': 1 }}" - " } }" - " ]," - "'cursor': { 'batchSize': 5 }," - "'collation': { 'locale': 'en' }" - "}"); - - mock_server_replies_simple ( - request, - "{'cursor': {'id': 123,'ns': 'db.coll','firstBatch': []},'ok': 1 }"); - - stream = future_get_mongoc_change_stream_ptr (future); - ASSERT (stream); - future_destroy (future); - request_destroy (request); - - future = future_change_stream_next (stream, &next_doc); - request = mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{ 'getMore': 123, 'collection': " - "'coll', 'maxTimeMS': 5000, " - "'batchSize': 5 }"); - mock_server_replies_simple (request, - "{ 'cursor': { 'nextBatch': [] }, 'ok': 1 }"); - request_destroy (request); - ASSERT (!future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, NULL), - err); - ASSERT (next_doc == NULL); - future_destroy (future); - - DESTROY_CHANGE_STREAM (123); - - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -/* Test basic watch functionality and validate the server documents */ -static void -test_change_stream_live_watch (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - bson_t *inserted_doc = tmp_bson ("{ 'x': 'y'}"); - const bson_t *next_doc = NULL; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t opts = BSON_INITIALIZER; - bson_error_t err; - - mongoc_write_concern_set_wmajority (wc, 30000); - - coll = drop_and_get_coll (client, "db", "coll_watch"); - ASSERT (coll); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), NULL, NULL, &err), - err); - - stream = mongoc_collection_watch (coll, tmp_bson ("{}"), NULL); - ASSERT (stream); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, NULL), - err); - - /* Test that inserting a doc produces the expected change stream doc */ - mongoc_write_concern_append (wc, &opts); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, inserted_doc, &opts, NULL, &err), - err); - - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - - /* Validation rules as follows: - * { _id: <present>, operationType: "insert", ns: <doc>, documentKey: - * <present>, - * updateDescription: <missing>, fullDocument: <inserted doc> } - */ - ASSERT_HAS_FIELD (next_doc, "_id"); - ASSERT (!strcmp (bson_lookup_utf8 (next_doc, "operationType"), "insert")); - - ASSERT_MATCH ( - next_doc, - "{ '_id': { '$exists': true },'operationType': 'insert', 'ns': " - "{ 'db': 'db', 'coll': 'coll_watch' },'documentKey': { " - "'$exists': true }, 'updateDescription': { '$exists': false }, " - "'fullDocument': { '_id': { '$exists': true }, 'x': 'y' }}"); - - /* Test updating a doc */ - ASSERT_OR_PRINT ( - mongoc_collection_update (coll, - MONGOC_UPDATE_NONE, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'x': 'z'} }"), - wc, - &err), - err); - - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - - ASSERT_MATCH ( - next_doc, - "{ '_id': { '$exists': true },'operationType': 'update', 'ns': { 'db': " - "'db', 'coll': 'coll_watch' },'documentKey': { '$exists': " - "true }, 'updateDescription': { 'updatedFields': { 'x': 'z' } " - "}, 'fullDocument': { '$exists': false }}"); - - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -/* From Change Streams Spec tests: - * "ChangeStream will resume after a killCursors command is issued for its child - * cursor." - * "ChangeStream will perform server selection before attempting to resume, - * using initial readPreference" - */ -static void -test_change_stream_live_read_prefs (void *test_ctx) -{ - /* - - connect with secondary read preference - - verify we are connected to a secondary - - issue a killCursors to trigger a resume - - after resume, check that the cursor connected to a secondary - */ - - mongoc_read_prefs_t *prefs; - mongoc_client_t *client = test_framework_client_new (); - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - mongoc_cursor_t *raw_cursor; - const bson_t *next_doc = NULL; - bson_error_t err; - uint64_t first_cursor_id; - - coll = drop_and_get_coll (client, "db", "coll_read_prefs"); - ASSERT (coll); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, - tmp_bson (NULL), - tmp_bson ("{'writeConcern': {'w': %d}}", - test_framework_data_nodes_count ()), - NULL, - &err), - err); - - prefs = mongoc_read_prefs_copy (mongoc_collection_get_read_prefs (coll)); - mongoc_read_prefs_set_mode (prefs, MONGOC_READ_SECONDARY); - mongoc_collection_set_read_prefs (coll, prefs); - - stream = mongoc_collection_watch (coll, tmp_bson ("{}"), NULL); - ASSERT (stream); - mongoc_change_stream_next (stream, &next_doc); - - raw_cursor = stream->cursor; - ASSERT (raw_cursor); - - ASSERT (test_framework_server_is_secondary (client, raw_cursor->server_id)); - first_cursor_id = mongoc_cursor_get_id (raw_cursor); - - /* Call next to create the cursor, should return no documents. */ - ASSERT (!mongoc_change_stream_next (stream, &next_doc)); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, NULL), - err); - - _mongoc_client_kill_cursor (client, - raw_cursor->server_id, - mongoc_cursor_get_id (raw_cursor), - 1 /* operation_id */, - "db", - "coll_read_prefs", - NULL /* session */); - - /* Change stream client will resume with another cursor. */ - /* depending on the server version, this may or may not receive another - * document on resume */ - (void) mongoc_change_stream_next (stream, &next_doc); - ASSERT_OR_PRINT ( - !mongoc_change_stream_error_document (stream, &err, &next_doc), err); - - raw_cursor = stream->cursor; - ASSERT (first_cursor_id != mongoc_cursor_get_id (raw_cursor)); - ASSERT (test_framework_server_is_secondary (client, raw_cursor->server_id)); - - mongoc_read_prefs_destroy (prefs); - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -/* Test that a failed server selection returns an error. This verifies a bug - * is fixed, which would trigger an assert in this case. */ -static void -test_change_stream_server_selection_fails (void) -{ - const bson_t *bson; - bson_error_t err; - mongoc_client_t *client = mongoc_client_new ("mongodb://localhost:12345/"); - mongoc_collection_t *coll = - mongoc_client_get_collection (client, "test", "test"); - mongoc_change_stream_t *cs = - mongoc_collection_watch (coll, tmp_bson ("{}"), NULL); - - mongoc_change_stream_next (cs, &bson); - BSON_ASSERT (mongoc_change_stream_error_document (cs, &err, &bson)); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "No suitable servers found"); - mongoc_change_stream_destroy (cs); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -/* Test calling next on a change stream which errors after construction. This - * verifies a bug is fixed, which would try to access a NULL cursor. */ -static void -test_change_stream_next_after_error (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *bson; - bson_error_t err; - - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - coll = mongoc_client_get_collection (client, "db", "coll"); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), NULL, NULL, &err), - err); - stream = mongoc_collection_watch ( - coll, tmp_bson ("{'pipeline': ['invalid_stage']}"), NULL); - BSON_ASSERT (!mongoc_change_stream_next (stream, &bson)); - BSON_ASSERT (mongoc_change_stream_error_document (stream, &err, &bson)); - BSON_ASSERT (err.domain == MONGOC_ERROR_SERVER); - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -typedef struct { - char *pattern; - int agg_count; -} array_started_ctx_t; - -static void -_accepts_array_started (const mongoc_apm_command_started_t *event) -{ - const bson_t *cmd = mongoc_apm_command_started_get_command (event); - const char *cmd_name = mongoc_apm_command_started_get_command_name (event); - array_started_ctx_t *ctx = - (array_started_ctx_t *) mongoc_apm_command_started_get_context (event); - if (strcmp (cmd_name, "aggregate") != 0) { - return; - } - ctx->agg_count++; - ASSERT_MATCH (cmd, ctx->pattern); -} - -/* Test that watch accepts an array document {0: {}, 1: {}} as the pipeline, - * similar to mongoc_collection_aggregate */ -static void -test_change_stream_accepts_array (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - mongoc_apm_callbacks_t *callbacks = mongoc_apm_callbacks_new (); - array_started_ctx_t ctx = {0}; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *bson; - bson_error_t err; - bson_t *opts = - tmp_bson ("{'maxAwaitTimeMS': 1}"); /* to speed up the test. */ - - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - /* set up apm callbacks to listen for the agg commands. */ - ctx.pattern = - bson_strdup ("{'aggregate': 'coll', 'pipeline': [ {'$changeStream': {}}, " - "{'$match': {'x': 1}}, {'$project': {'x': 1}}]}"); - mongoc_apm_set_command_started_cb (callbacks, _accepts_array_started); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - coll = mongoc_client_get_collection (client, "db", "coll"); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), NULL, NULL, &err), - err); - /* try starting a change stream with a { "pipeline": [...] } argument */ - stream = mongoc_collection_watch ( - coll, - tmp_bson ("{'pipeline': [{'$match': {'x': 1}}, {'$project': {'x': 1}}]}"), - opts); - (void) mongoc_change_stream_next (stream, &bson); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, &bson), - err); - ASSERT_CMPINT32 (ctx.agg_count, ==, 1); - mongoc_change_stream_destroy (stream); - /* try with an array like document. */ - stream = mongoc_collection_watch ( - coll, - tmp_bson ("{'0': {'$match': {'x': 1}}, '1': {'$project': {'x': 1}}}"), - opts); - (void) mongoc_change_stream_next (stream, &bson); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, &bson), - err); - ASSERT_CMPINT32 (ctx.agg_count, ==, 2); - mongoc_change_stream_destroy (stream); - /* try with malformed { "pipeline": [...] } argument. */ - bson_free (ctx.pattern); - ctx.pattern = bson_strdup ( - "{'aggregate': 'coll', 'pipeline': [ {'$changeStream': {}}, 42 ]}"); - stream = - mongoc_collection_watch (coll, tmp_bson ("{'pipeline': [42] }"), NULL); - (void) mongoc_change_stream_next (stream, &bson); - BSON_ASSERT (mongoc_change_stream_error_document (stream, &err, &bson)); - ASSERT_ERROR_CONTAINS ( - err, - MONGOC_ERROR_SERVER, - 14, - "Each element of the 'pipeline' array must be an object"); - ASSERT_CMPINT32 (ctx.agg_count, ==, 3); - mongoc_change_stream_destroy (stream); - /* try with malformed array doc argument. */ - stream = mongoc_collection_watch (coll, tmp_bson ("{'0': 42 }"), NULL); - (void) mongoc_change_stream_next (stream, &bson); - BSON_ASSERT (mongoc_change_stream_error_document (stream, &err, &bson)); - ASSERT_ERROR_CONTAINS ( - err, - MONGOC_ERROR_SERVER, - 14, - "Each element of the 'pipeline' array must be an object"); - ASSERT_CMPINT32 (ctx.agg_count, ==, 4); - mongoc_change_stream_destroy (stream); - bson_free (ctx.pattern); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -/* A simple test that passing 'startAtOperationTime' does not error. */ -void -test_change_stream_start_at_operation_time (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *doc; - bson_t opts; - mongoc_client_session_t *session; - bson_error_t error; - - session = mongoc_client_start_session (client, NULL, &error); - coll = mongoc_client_get_collection (client, "db", "coll"); - bson_init (&opts); - ASSERT_OR_PRINT (mongoc_client_session_append (session, &opts, &error), - error); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), &opts, NULL, &error), - error); - BSON_APPEND_TIMESTAMP (&opts, - "startAtOperationTime", - session->operation_timestamp, - session->operation_increment); - stream = - mongoc_collection_watch (coll, tmp_bson ("{'pipeline': []}"), &opts); - - (void) mongoc_change_stream_next (stream, &doc); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - - bson_destroy (&opts); - mongoc_change_stream_destroy (stream); - mongoc_client_session_destroy (session); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -typedef struct { - bool has_initiated; - bool has_resumed; - bson_t agg_reply; -} resume_ctx_t; - -#define RESUME_INITIALIZER \ - { \ - false, false, BSON_INITIALIZER \ - } - -static void -_resume_at_optime_started (const mongoc_apm_command_started_t *event) -{ - resume_ctx_t *ctx; - - ctx = (resume_ctx_t *) mongoc_apm_command_started_get_context (event); - if (0 != strcmp (mongoc_apm_command_started_get_command_name (event), - "aggregate")) { - return; - } - - if (!ctx->has_initiated) { - ctx->has_initiated = true; - return; - } - - ctx->has_resumed = true; - - /* postBatchResumeToken (MongoDB 4.0.7+) supersedes operationTime. Since - * test_change_stream_resume_at_optime runs for wire version 7+, decide - * whether to skip operationTime assertion based on the command reply. */ - if (!bson_has_field (&ctx->agg_reply, "cursor.postBatchResumeToken")) { - bson_value_t replied_optime, sent_optime; - match_ctx_t match_ctx = {{0}}; - - /* it should re-use the same optime on resume. */ - bson_lookup_value (&ctx->agg_reply, "operationTime", &replied_optime); - bson_lookup_value (mongoc_apm_command_started_get_command (event), - "pipeline.0.$changeStream.startAtOperationTime", - &sent_optime); - BSON_ASSERT (replied_optime.value_type == BSON_TYPE_TIMESTAMP); - BSON_ASSERT ( - match_bson_value (&sent_optime, &replied_optime, &match_ctx)); - bson_value_destroy (&sent_optime); - bson_value_destroy (&replied_optime); - } -} - -static void -_resume_at_optime_succeeded (const mongoc_apm_command_succeeded_t *event) -{ - resume_ctx_t *ctx; - - ctx = (resume_ctx_t *) mongoc_apm_command_succeeded_get_context (event); - if (!strcmp (mongoc_apm_command_succeeded_get_command_name (event), - "aggregate")) { - bson_destroy (&ctx->agg_reply); - bson_copy_to (mongoc_apm_command_succeeded_get_reply (event), - &ctx->agg_reply); - } -} - -/* Test that "operationTime" in aggregate reply is used on resume */ -static void -test_change_stream_resume_at_optime (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *doc; - bson_error_t error; - mongoc_apm_callbacks_t *callbacks; - resume_ctx_t ctx = RESUME_INITIALIZER; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, _resume_at_optime_started); - mongoc_apm_set_command_succeeded_cb (callbacks, _resume_at_optime_succeeded); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - coll = mongoc_client_get_collection (client, "db", "coll"); - stream = mongoc_collection_watch (coll, tmp_bson ("{'pipeline': []}"), NULL); - - /* set the cursor id to a wrong cursor id so the next getMore fails and - * causes a resume. */ - stream->cursor->cursor_id = 12345; - - (void) mongoc_change_stream_next (stream, &doc); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - BSON_ASSERT (ctx.has_initiated); - BSON_ASSERT (ctx.has_resumed); - - bson_destroy (&ctx.agg_reply); - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_client_destroy (client); -} - -static void -_resume_with_post_batch_resume_token_started ( - const mongoc_apm_command_started_t *event) -{ - resume_ctx_t *ctx; - - ctx = (resume_ctx_t *) mongoc_apm_command_started_get_context (event); - if (0 != strcmp (mongoc_apm_command_started_get_command_name (event), - "aggregate")) { - return; - } - - if (!ctx->has_initiated) { - ctx->has_initiated = true; - return; - } - - ctx->has_resumed = true; - - /* postBatchResumeToken is available since MongoDB 4.0.7, but the test runs - * for wire version 7+. Decide whether to skip postBatchResumeToken assertion - * based on the command reply. */ - if (bson_has_field (&ctx->agg_reply, "cursor.postBatchResumeToken")) { - bson_value_t replied_pbrt, sent_pbrt; - match_ctx_t match_ctx = {{0}}; - - /* it should re-use the same postBatchResumeToken on resume. */ - bson_lookup_value ( - &ctx->agg_reply, "cursor.postBatchResumeToken", &replied_pbrt); - bson_lookup_value (mongoc_apm_command_started_get_command (event), - "pipeline.0.$changeStream.resumeAfter", - &sent_pbrt); - BSON_ASSERT (replied_pbrt.value_type == BSON_TYPE_DOCUMENT); - BSON_ASSERT (match_bson_value (&sent_pbrt, &replied_pbrt, &match_ctx)); - bson_value_destroy (&sent_pbrt); - bson_value_destroy (&replied_pbrt); - } -} - -static void -_resume_with_post_batch_resume_token_succeeded ( - const mongoc_apm_command_succeeded_t *event) -{ - resume_ctx_t *ctx; - - ctx = (resume_ctx_t *) mongoc_apm_command_succeeded_get_context (event); - if (!strcmp (mongoc_apm_command_succeeded_get_command_name (event), - "aggregate")) { - bson_destroy (&ctx->agg_reply); - bson_copy_to (mongoc_apm_command_succeeded_get_reply (event), - &ctx->agg_reply); - } -} - -/* Test that "postBatchResumeToken" in aggregate reply is used on resume */ -static void -test_change_stream_resume_with_post_batch_resume_token (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *doc; - bson_error_t error; - mongoc_apm_callbacks_t *callbacks; - resume_ctx_t ctx = RESUME_INITIALIZER; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb ( - callbacks, _resume_with_post_batch_resume_token_started); - mongoc_apm_set_command_succeeded_cb ( - callbacks, _resume_with_post_batch_resume_token_succeeded); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - coll = mongoc_client_get_collection (client, "db", "coll"); - stream = mongoc_collection_watch (coll, tmp_bson ("{'pipeline': []}"), NULL); - - /* set the cursor id to a wrong cursor id so the next getMore fails and - * causes a resume. */ - stream->cursor->cursor_id = 12345; - - (void) mongoc_change_stream_next (stream, &doc); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - BSON_ASSERT (ctx.has_initiated); - BSON_ASSERT (ctx.has_resumed); - - bson_destroy (&ctx.agg_reply); - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_client_destroy (client); -} - -/* A simple test of database watch. */ -void -test_change_stream_database_watch (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - mongoc_database_t *db; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *doc; - bson_t opts; - bson_error_t error; - - db = mongoc_client_get_database (client, "db"); - bson_init (&opts); - - stream = mongoc_database_watch (db, tmp_bson ("{}"), NULL); - - coll = mongoc_database_get_collection (db, "coll"); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), &opts, NULL, &error), - error); - - (void) mongoc_change_stream_next (stream, &doc); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - - bson_destroy (&opts); - mongoc_change_stream_destroy (stream); - mongoc_database_destroy (db); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -/* A simple test of client watch. */ -void -test_change_stream_client_watch (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *doc; - bson_t opts; - bson_error_t error; - - bson_init (&opts); - - stream = mongoc_client_watch (client, tmp_bson ("{}"), NULL); - - coll = mongoc_client_get_collection (client, "db", "coll"); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), &opts, NULL, &error), - error); - - (void) mongoc_change_stream_next (stream, &doc); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - - bson_destroy (&opts); - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - - -static int -_skip_if_rs_version_less_than (const char *version) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - if (!test_framework_skip_if_not_replset ()) { - return 0; - } - if (test_framework_get_server_version () >= - test_framework_str_to_version (version)) { - return 1; - } - return 0; -} - -static int -_skip_if_no_client_watch (void) -{ - return _skip_if_rs_version_less_than ("3.8.0"); -} - -static int -_skip_if_no_db_watch (void) -{ - return _skip_if_rs_version_less_than ("3.8.0"); -} - -static int -_skip_if_no_start_at_optime (void) -{ - return _skip_if_rs_version_less_than ("3.8.0"); -} - -typedef struct { - mongoc_change_stream_t *change_stream; -} change_stream_spec_ctx_t; - -static bool -change_stream_spec_operation_cb (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation) -{ - bson_t reply; - bool res; - - mongoc_collection_t *coll = - mongoc_client_get_collection (ctx->client, - bson_lookup_utf8 (operation, "database"), - bson_lookup_utf8 (operation, "collection")); - res = json_test_operation (ctx, test, operation, coll, NULL, &reply); - mongoc_collection_destroy (coll); - bson_destroy (&reply); - - return res; -} - -static void -change_stream_spec_before_test_cb (json_test_ctx_t *test_ctx, - const bson_t *test) -{ - change_stream_spec_ctx_t *ctx = - (change_stream_spec_ctx_t *) test_ctx->config->ctx; - bson_t opts; - bson_t pipeline; - const char *target = bson_lookup_utf8 (test, "target"); - - set_apm_callbacks (test_ctx, test_ctx->client); - - bson_lookup_doc (test, "changeStreamOptions", &opts); - bson_lookup_doc (test, "changeStreamPipeline", &pipeline); - if (!strcmp (target, "collection")) { - ctx->change_stream = - mongoc_collection_watch (test_ctx->collection, &pipeline, &opts); - } else if (!strcmp (target, "database")) { - ctx->change_stream = - mongoc_database_watch (test_ctx->db, &pipeline, &opts); - } else if (!strcmp (target, "client")) { - ctx->change_stream = - mongoc_client_watch (test_ctx->client, &pipeline, &opts); - } else { - ASSERT_WITH_MSG (false, - "target unknown: \"%s\" in test: %s", - target, - bson_as_json (test, NULL)); - } -} - -static void -change_stream_spec_after_test_cb (json_test_ctx_t *test_ctx, const bson_t *test) -{ - change_stream_spec_ctx_t *ctx = - (change_stream_spec_ctx_t *) test_ctx->config->ctx; - bson_error_t error; - if (mongoc_change_stream_error_document (ctx->change_stream, &error, NULL)) { - int32_t expected_err_code; - /* verify that the error code matches the result. */ - ASSERT_WITH_MSG ( - bson_has_field (test, "result.error.code"), - "Change stream got error: \"%s\" but test does not assert error: %s.", - error.message, - bson_as_json (test, NULL)); - expected_err_code = bson_lookup_int32 (test, "result.error.code"); - ASSERT_CMPINT64 (expected_err_code, ==, (int32_t) error.code); - } else { - if (bson_has_field (test, "result.success")) { - bson_t expected_docs; - bson_iter_t expected_iter; - bson_t all_changes = BSON_INITIALIZER; - int i = 0; - const bson_t *doc; - - bson_lookup_doc (test, "result.success", &expected_docs); - BSON_ASSERT (bson_iter_init (&expected_iter, &expected_docs)); - - /* iterate over the change stream, and verify that the document exists. - */ - while (mongoc_change_stream_next (ctx->change_stream, &doc)) { - char *key = bson_strdup_printf ("%d", i); - i++; - bson_append_document (&all_changes, key, -1, doc); - bson_free (key); - } - - /* check that everything in the "result.success" array is contained in - * our captured changes. */ - while (bson_iter_next (&expected_iter)) { - bson_t expected_doc; - match_ctx_t match_ctx = {{0}}; - - match_ctx.allow_placeholders = true; - match_ctx.retain_dots_in_keys = true; - match_ctx.strict_numeric_types = false; - bson_iter_bson (&expected_iter, &expected_doc); - match_in_array (&expected_doc, &all_changes, &match_ctx); - } - bson_destroy (&all_changes); - } - /* verify no failure. */ - ASSERT_OR_PRINT (!mongoc_change_stream_error_document ( - ctx->change_stream, &error, NULL), - error); - - /* go through the results. */ - } - /* based on results, do something. */ - /* call a "test ended" callback */ - /* or easier, just destroy the change stream here. */ - mongoc_change_stream_destroy (ctx->change_stream); -} - -static void -test_change_stream_spec_cb (bson_t *scenario) -{ - json_test_config_t config = JSON_TEST_CONFIG_INIT; - change_stream_spec_ctx_t ctx = {0}; - config.ctx = &ctx; - config.command_started_events_only = true; - config.command_monitoring_allow_subset = true; - config.before_test_cb = change_stream_spec_before_test_cb; - config.after_test_cb = change_stream_spec_after_test_cb; - config.run_operation_cb = change_stream_spec_operation_cb; - config.scenario = scenario; - run_json_general_test (&config); -} - - -static void -_test_resume (const char *opts, - const char *expected_change_stream_opts, - const char *first_doc, - const char *expected_resume_change_stream_opts, - const char *cursor_pbr) -{ - mock_server_t *server; - request_t *request; - future_t *future; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - bson_error_t err; - char *msg; - const bson_t *doc = NULL; - - server = mock_server_with_autoismaster (7); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - coll = mongoc_client_get_collection (client, "db", "coll"); - future = future_collection_watch (coll, tmp_bson ("{}"), tmp_bson (opts)); - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate': 'coll', 'pipeline' : [ { '$changeStream': { %s " - "'fullDocument': 'default' } } ], 'cursor': { } }", - expected_change_stream_opts)); - msg = bson_strdup_printf ("{'cursor': {'id': 123, 'ns': 'db.coll'," - "'firstBatch': [%s]%s }, 'operationTime': " - "{ '$timestamp': {'t': 1, 'i': 2} }, 'ok': 1 }", - first_doc, - cursor_pbr); - mock_server_replies_simple (request, msg); - bson_free (msg); - stream = future_get_mongoc_change_stream_ptr (future); - BSON_ASSERT (stream); - future_destroy (future); - request_destroy (request); - /* if a first document was returned, the first call to next returns it. */ - if (*first_doc) { - mongoc_change_stream_next (stream, &doc); - ASSERT_MATCH (doc, first_doc); - } - future = future_change_stream_next (stream, &doc); - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'getMore': {'$numberLong': '123'}, 'collection': 'coll' }")); - mock_server_hangs_up (request); - request_destroy (request); - /* since the server closed the connection, a resume is attempted. */ - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate': 'coll', 'pipeline' : [ { '$changeStream': { %s " - "'fullDocument': 'default' }} ], 'cursor': { } }", - expected_resume_change_stream_opts)); - mock_server_replies_simple ( - request, - "{'cursor': {'id': 0,'ns': 'db.coll','firstBatch': []},'ok': 1 }"); - request_destroy (request); - - BSON_ASSERT (!future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &err, NULL), - err); - BSON_ASSERT (doc == NULL); - future_destroy (future); - - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -/* test resume behavior before and after the first document is received. */ -static void -test_resume_cases (void) -{ -#define NO_OPT_RA "'resumeAfter': {'$exists': false}" -#define NO_OPT_SA "'startAfter': {'$exists': false}" -#define NO_OPT_OP "'startAtOperationTime': {'$exists': false}" -#define AGG_OP "'startAtOperationTime': {'$timestamp': {'t': 1, 'i': 2}}" -#define DOC "{'_id': {'resume': 'doc'}}" -#define OPT_OP "'startAtOperationTime': {'$timestamp': {'t': 111, 'i': 222}}" -#define DOC_RA "'resumeAfter': {'resume': 'doc'}" -#define OPT_RA "'resumeAfter': {'resume': 'opt'}" -#define OPT_SA "'startAfter': {'resume': 'opt'}" - - /* test features: - * - whether the change stream returns a document before resuming. - * - whether 'startAtOperationTime' is specified - * - whether 'resumeAfter' is specified - * - whether 'startAfterAfter' is specified */ - - /* no options specified. */ - /* - if no doc recv'ed, use the operationTime returned by aggregate. */ - _test_resume ("{}", - NO_OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - "", - AGG_OP "," NO_OPT_RA "," NO_OPT_SA ",", - ""); - /* - if doc recv'ed and iterated, use the doc's resume token. */ - _test_resume ("{}", - NO_OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - DOC, - DOC_RA "," NO_OPT_OP "," NO_OPT_SA ",", - ""); - - /* only 'startAtOperationTime' specified. */ - /* - if no doc recv'ed, use the startAtOperationTime option. */ - _test_resume ("{" OPT_OP "}", - OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - "", - OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - ""); - /* - if doc recv'ed and iterated, use the doc's resume token. */ - _test_resume ("{" OPT_OP "}", - OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - DOC, - DOC_RA "," NO_OPT_OP "," NO_OPT_SA ",", - ""); - - /* only 'resumeAfter' specified. */ - /* - if no doc recv'ed, use the resumeAfter option. */ - _test_resume ("{" OPT_RA "}", - OPT_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "", - OPT_RA "," NO_OPT_OP "," NO_OPT_SA ",", - ""); - /* - if doc recv'ed and iterated, use the doc's resume token. */ - _test_resume ("{" OPT_RA "}", - OPT_RA "," NO_OPT_OP "," NO_OPT_SA ",", - DOC, - DOC_RA "," NO_OPT_OP "," NO_OPT_SA ",", - ""); - - /* only 'startAfter' specified. */ - /* - if no doc recv'ed, use the startAfter option for the original aggregate - * whether or not we are resuming. */ - _test_resume ("{" OPT_SA "}", - OPT_SA "," NO_OPT_OP "," NO_OPT_RA ",", - "", - OPT_SA "," NO_OPT_OP "," NO_OPT_RA ",", - ""); - /* - if doc recv'ed and iterated, use the doc's resume token. */ - _test_resume ("{" OPT_SA "}", - OPT_SA "," NO_OPT_OP "," NO_OPT_RA ",", - DOC, - DOC_RA "," NO_OPT_OP "," NO_OPT_SA ",", - ""); - - /* 'resumeAfter', 'startAfter', and 'startAtOperationTime' are all specified. - * All should be passed (although the server currently returns an error). */ - /* - if no doc recv'ed, use startAfter. */ - _test_resume ("{" OPT_RA "," OPT_SA "," OPT_OP "}", - OPT_RA "," OPT_SA "," OPT_OP ",", - "", - OPT_SA "," NO_OPT_OP "," NO_OPT_RA ",", - ""); - /* - if one doc recv'ed and iterated, use resumeAfter with doc's resume - * token. */ - _test_resume ("{" OPT_RA "," OPT_SA "," OPT_OP "}", - OPT_RA "," OPT_SA "," OPT_OP ",", - DOC, - DOC_RA "," NO_OPT_OP "," NO_OPT_SA ",", - ""); -} - - -/* test resume behavior before and after the first document is received when a - postBatchResumeToken is available. */ -static void -test_resume_cases_with_post_batch_resume_token (void) -{ -#define CURSOR_PBR "'postBatchResumeToken': {'resume': 'pbr'}" -#define PBR_RA "'resumeAfter': {'resume': 'pbr'}" -#define PBR_SA "'startAfter': {'resume': 'pbr'}" - - /* test features: - * - whether the change stream returns a document before resuming. - * - whether 'postBatchResumeToken' is available - * - whether 'startAtOperationTime' is specified - * - whether 'resumeAfter' is specified - * - whether 'startAfterAfter' is specified */ - - /* postBatchResumeToken always takes priority over specified options or - * operation time. It will also take priority over the resume token of the - * last document in the batch (if _test_resume() iterates to that point). */ - - /* no options specified. */ - /* - if no doc recv'ed, use resumeAfter with postBatchResumeToken. */ - _test_resume ("{}", - NO_OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - "", - PBR_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "," CURSOR_PBR); - /* - if one doc recv'ed and iterated, use resumeAfter with - * postBatchResumeToken. */ - _test_resume ("{}", - NO_OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - DOC, - PBR_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "," CURSOR_PBR); - - /* only 'startAtOperationTime' specified. */ - /* - if no doc recv'ed, use resumeAfter with postBatchResumeToken. */ - _test_resume ("{" OPT_OP "}", - OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - "", - PBR_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "," CURSOR_PBR); - /* - if one doc recv'ed and iterated, use resumeAfter with - * postBatchResumeToken. */ - _test_resume ("{" OPT_OP "}", - OPT_OP "," NO_OPT_RA "," NO_OPT_SA ",", - DOC, - PBR_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "," CURSOR_PBR); - - /* only 'resumeAfter' specified. */ - /* - if no doc recv'ed, use resumeAfter with postBatchResumeToken. */ - _test_resume ("{" OPT_RA "}", - OPT_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "", - PBR_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "," CURSOR_PBR); - /* - if one doc recv'ed and iterated, use resumeAfter with - * postBatchResumeToken. */ - _test_resume ("{" OPT_RA "}", - OPT_RA "," NO_OPT_OP "," NO_OPT_SA ",", - DOC, - PBR_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "," CURSOR_PBR); - - /* only 'startAfter' specified. */ - /* - if no doc recv'ed, use startAfter with postBatchResumeToken. */ - _test_resume ("{" OPT_SA "}", - OPT_SA "," NO_OPT_OP "," NO_OPT_RA ",", - "", - PBR_SA "," NO_OPT_OP "," NO_OPT_RA ",", - "," CURSOR_PBR); - /* - if one doc recv'ed and iterated, use resumeAfter with - * postBatchResumeToken. */ - _test_resume ("{" OPT_SA "}", - OPT_SA "," NO_OPT_OP "," NO_OPT_RA ",", - DOC, - PBR_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "," CURSOR_PBR); - - /* 'resumeAfter', 'startAfter', and 'startAtOperationTime' are all specified. - * All should be passed (although the server currently returns an error). */ - /* - if no doc recv'ed, use startAfter with postBatchResumeToken. */ - _test_resume ("{" OPT_RA "," OPT_SA "," OPT_OP "}", - OPT_RA "," OPT_SA "," OPT_OP ",", - "", - PBR_SA "," NO_OPT_OP "," NO_OPT_RA ",", - "," CURSOR_PBR); - /* - if one doc recv'ed and iterated, use resumeAfter with - * postBatchResumeToken. */ - _test_resume ("{" OPT_RA "," OPT_SA "," OPT_OP "}", - OPT_RA "," OPT_SA "," OPT_OP ",", - DOC, - PBR_RA "," NO_OPT_OP "," NO_OPT_SA ",", - "," CURSOR_PBR); -} - - -void -test_error_null_doc (void *ctx) -{ - mongoc_client_t *client; - mongoc_change_stream_t *stream; - bson_error_t err; - const bson_t *error_doc = - tmp_bson ("{}"); /* assign to a non-zero address. */ - - client = test_framework_client_new (); - stream = mongoc_client_watch (client, tmp_bson ("{}"), NULL); - /* error_doc starts as non-NULL. */ - BSON_ASSERT (error_doc); - BSON_ASSERT ( - !mongoc_change_stream_error_document (stream, &err, &error_doc)); - /* error_doc is set to NULL no error occurred. */ - BSON_ASSERT (!error_doc); - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); -} - - -void -_check_doc_resume_token (const bson_t *doc, const bson_t *resume_token) -{ - bson_t document_resume_token; - - bson_lookup_doc (doc, "_id", &document_resume_token); - ASSERT (bson_equal (resume_token, &document_resume_token)); - - bson_destroy (&document_resume_token); -} - - -void -prose_test_11 (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - bson_error_t error; - const bson_t *next_doc = NULL; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t opts = BSON_INITIALIZER; - const bson_t *resume_token; - _data_change_stream_t *post_batch_expected; - - client = test_framework_client_new (); - ASSERT (client); - - coll = drop_and_get_coll (client, "db", "coll_resume"); - ASSERT (coll); - - /* Set the batch size to 1 so we only get one document per call to next. */ - stream = mongoc_collection_watch ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 1}")); - ASSERT (stream); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - - /* The resume token should be updated to the post batch resume token */ - ASSERT (!mongoc_change_stream_next (stream, &next_doc)); - ASSERT (!next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - - /* Look into the struct and get the actual post batch resume token, assert it - * is equal to our resume token */ - post_batch_expected = (_data_change_stream_t *) stream->cursor->impl.data; - ASSERT (bson_compare (resume_token, - &post_batch_expected->post_batch_resume_token) == 0); - - mongoc_write_concern_set_wmajority (wc, 30000); - mongoc_write_concern_append (wc, &opts); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 0}"), &opts, NULL, &error), - error); - - /* Checking that a resume token is returned */ - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - ASSERT (next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - ASSERT (bson_compare (resume_token, - &post_batch_expected->post_batch_resume_token) == 0); - - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); -} - - -void -prose_test_12 (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - bson_error_t error; - const bson_t *next_doc = NULL; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t opts = BSON_INITIALIZER; - const bson_t *resume_token; - bson_iter_t iter, child; - bson_t expected_token; - bson_t expected_doc; - - client = test_framework_client_new (); - ASSERT (client); - - coll = drop_and_get_coll (client, "db", "coll_resume"); - ASSERT (coll); - - /* Set the batch size to 1 so we only get one document per call to next. */ - stream = mongoc_collection_watch ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 1}")); - ASSERT (stream); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - - mongoc_write_concern_set_wmajority (wc, 30000); - mongoc_write_concern_append (wc, &opts); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 0}"), &opts, NULL, &error), - error); - - /* Checking that a resume token is returned */ - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - ASSERT (next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - - /* Need to now check that we are getting back the _id of the last inserted - * document when we iterate to the last document */ - bson_copy_to (next_doc, &expected_doc); - _check_doc_resume_token (&expected_doc, resume_token); - - ASSERT (bson_iter_init_find (&iter, next_doc, "documentKey")); - ASSERT (bson_iter_recurse (&iter, &child)); - ASSERT (bson_iter_find (&child, "_id") && bson_iter_int32 (&child) == 0); - - /* Must check that getResumeToken returns resumeAfter correctly when - * specified. */ - bson_copy_to (resume_token, &expected_token); - mongoc_change_stream_destroy (stream); - bson_destroy (&opts); - bson_init (&opts); - BSON_APPEND_DOCUMENT (&opts, "resumeAfter", &expected_token); - - stream = mongoc_collection_watch (coll, tmp_bson ("{}"), &opts); - ASSERT (stream); - - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (bson_equal (resume_token, &expected_token)); - - bson_destroy (&expected_doc); - bson_destroy (&expected_token); - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); -} - - -void -prose_test_13 (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - bson_error_t error; - const bson_t *next_doc = NULL; - mongoc_apm_callbacks_t *callbacks; - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - bson_t opts = BSON_INITIALIZER; - const bson_t *resume_token; - bson_iter_t iter, child; - - client = test_framework_client_new (); - ASSERT (client); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, - test_resume_token_command_start); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - - coll = drop_and_get_coll (client, "db", "coll_resume"); - ASSERT (coll); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson (NULL), NULL, NULL, &error), - error); - - /* Set the batch size to 1 so we only get one document per call to next. */ - stream = mongoc_collection_watch ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 1}")); - ASSERT (stream); - ASSERT_OR_PRINT (!mongoc_change_stream_error_document (stream, &error, NULL), - error); - - /* Insert a few docs to listen for. Use write concern majority, so subsequent - * call to watch will be guaranteed to retrieve them. */ - mongoc_write_concern_set_wmajority (wc, 30000); - mongoc_write_concern_append (wc, &opts); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 0}"), &opts, NULL, &error), - error); - - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 1}"), &opts, NULL, &error), - error); - - /* The resume token should be updated to the most recently iterated doc */ - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - ASSERT (next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - _check_doc_resume_token (next_doc, resume_token); - - ASSERT (mongoc_change_stream_next (stream, &next_doc)); - ASSERT (next_doc); - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (!bson_empty0 (resume_token)); - _check_doc_resume_token (next_doc, resume_token); - - ASSERT (bson_iter_init_find (&iter, next_doc, "documentKey")); - ASSERT (bson_iter_recurse (&iter, &child)); - ASSERT (bson_iter_find (&child, "_id") && bson_iter_int32 (&child) == 1); - - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_change_stream_destroy (stream); - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); -} - -static void -_save_operation_time_from_agg (const mongoc_apm_command_succeeded_t *event) -{ - if (0 == strcmp ("aggregate", - mongoc_apm_command_succeeded_get_command_name (event))) { - mongoc_timestamp_t *timestamp; - bson_iter_t iter; - const bson_t *cmd; - - cmd = mongoc_apm_command_succeeded_get_reply (event); - timestamp = mongoc_apm_command_succeeded_get_context (event); - /* Capture the operationTime from the first aggregate reply. */ - if (timestamp->timestamp == 0) { - BSON_ASSERT (bson_iter_init_find (&iter, cmd, "operationTime")); - _mongoc_timestamp_set_from_bson (timestamp, &iter); - } - } -} - -void -prose_test_14 (void *test_ctx) -{ - mongoc_client_t *client = test_framework_client_new (); - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - bson_t opts; - bson_error_t error; - const bson_t *resume_token; - bson_t expected_token; - const bson_t *doc = NULL; - mongoc_timestamp_t optime = {0}; - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_succeeded_cb (callbacks, - _save_operation_time_from_agg); - mongoc_client_set_apm_callbacks (client, callbacks, &optime); - mongoc_apm_callbacks_destroy (callbacks); - - coll = drop_and_get_coll (client, "db", "coll"); - bson_init (&opts); - stream = mongoc_collection_watch (coll, tmp_bson ("{}"), &opts); - /* The _save_operation_time_from_agg listener must have stored the operation - * time. */ - BSON_ASSERT (optime.timestamp != 0); - - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 0}"), &opts, NULL, &error), - error); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 1}"), &opts, NULL, &error), - error); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 2}"), &opts, NULL, &error), - error); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 3}"), &opts, NULL, &error), - error); - - ASSERT (mongoc_change_stream_next (stream, &doc)); - resume_token = mongoc_change_stream_get_resume_token (stream); - - bson_copy_to (resume_token, &expected_token); - BSON_APPEND_DOCUMENT (&opts, "startAfter", &expected_token); - - mongoc_change_stream_destroy (stream); - - /* Start a new change stream using "startAfter" set to a previously obtained - resume token to guarantee a non-empty initial batch */ - stream = mongoc_collection_watch (coll, tmp_bson ("{}"), &opts); - - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (bson_equal (resume_token, &expected_token)); - - /* Doing the same using "resumeAfter" instead */ - mongoc_change_stream_destroy (stream); - bson_destroy (&opts); - bson_init (&opts); - BSON_APPEND_DOCUMENT (&opts, "resumeAfter", &expected_token); - - stream = mongoc_collection_watch (coll, tmp_bson ("{}"), &opts); - - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (bson_equal (resume_token, &expected_token)); - mongoc_change_stream_destroy (stream); - - /* Finally, with neither. */ - bson_destroy (&opts); - bson_init (&opts); - BSON_APPEND_TIMESTAMP ( - &opts, "startAtOperationTime", optime.timestamp, optime.increment); - stream = mongoc_collection_watch (coll, tmp_bson ("{}"), &opts); - - resume_token = mongoc_change_stream_get_resume_token (stream); - ASSERT (resume_token == NULL); - - bson_destroy (&expected_token); - bson_destroy (&opts); - mongoc_change_stream_destroy (stream); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - - -void -prose_test_17 (void) -{ - mock_server_t *server; - request_t *request; - future_t *future; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *next_doc = NULL; - - server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - coll = mongoc_client_get_collection (client, "db", "coll"); - /* Pass an arbitrary document as the resume token, like {'x': 1} */ - future = future_collection_watch ( - coll, tmp_bson ("{}"), tmp_bson ("{'startAfter': {'x': 1}}")); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate': 'coll', 'pipeline' : [ { '$changeStream': { " - "'startAfter': {'x': 1} , 'resumeAfter': { '$exists': false }, " - "'startAtOperationTime': { '$exists': false } } } ]}")); - - mock_server_replies_simple ( - request, - "{'cursor': {'id': 123, 'ns': 'db.coll', 'firstBatch': []}, 'ok': 1 }"); - - request_destroy (request); - - stream = future_get_mongoc_change_stream_ptr (future); - ASSERT (stream); - future_destroy (future); - - future = future_change_stream_next (stream, &next_doc); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'getMore': {'$numberLong': '123'}, 'collection': 'coll' }")); - - mock_server_replies_simple ( - request, "{ 'code': 10107, 'errmsg': 'not master', 'ok': 0 }"); - - request_destroy (request); - - /* Resume occurs. */ - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate': 'coll', 'pipeline': [ { " - "'$changeStream': { 'startAfter': {'x': 1}, 'resumeAfter': { " - "'$exists': false }, 'startAtOperationTime': { '$exists': " - "false } } " - "}]}")); - - /* Reply with a 0 cursor ID to prevent a killCursors command. */ - mock_server_replies_simple ( - request, - "{'cursor': {'id': 0, 'ns': 'db.coll', 'firstBatch': []}, 'ok': 1 }"); - request_destroy (request); - BSON_ASSERT (!future_get_bool (future)); - future_destroy (future); - mongoc_change_stream_destroy (stream); - - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -void -prose_test_18 (void) -{ - mock_server_t *server; - request_t *request; - future_t *future; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_change_stream_t *stream; - const bson_t *next_doc = NULL; - - server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - coll = mongoc_client_get_collection (client, "db", "coll"); - /* Pass an arbitrary document as the resume token, like {'x': 1} */ - future = future_collection_watch ( - coll, tmp_bson ("{}"), tmp_bson ("{'startAfter': {'x': 1}}")); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate': 'coll', 'pipeline' : [ { '$changeStream': { " - "'startAfter': {'x': 1}, 'resumeAfter': { '$exists': false }, " - "'startAtOperationTime': { '$exists': false } } } ]}")); - - mock_server_replies_simple (request, - "{'cursor': {'id': 123, 'ns': " - "'db.coll', 'firstBatch': [{'_id': " - "{'y': 1}}]}, 'ok': 1 }"); - - request_destroy (request); - stream = future_get_mongoc_change_stream_ptr (future); - ASSERT (stream); - future_destroy (future); - - /* The first call to mongoc_change_stream_next returns the batched document. - */ - mongoc_change_stream_next (stream, &next_doc); - - future = future_change_stream_next (stream, &next_doc); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'getMore': {'$numberLong': '123'}, 'collection': 'coll' }")); - - mock_server_replies_simple ( - request, "{ 'code': 10107, 'errmsg': 'not master', 'ok': 0 }"); - - request_destroy (request); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate': 'coll', 'pipeline': [ { " - "'$changeStream': { 'resumeAfter': {'y': 1}, 'startAfter': { " - "'$exists': false }, 'startAtOperationTime': { '$exists': " - "false } } " - "}]}")); - /* Reply with a 0 cursor ID to prevent a killCursors command. */ - mock_server_replies_simple ( - request, - "{'cursor': {'id': 0, 'ns': 'db.coll', 'firstBatch': []}, 'ok': 1 }"); - request_destroy (request); - BSON_ASSERT (!future_get_bool (future)); - future_destroy (future); - mongoc_change_stream_destroy (stream); - - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -void -test_change_stream_install (TestSuite *suite) -{ - char resolved[PATH_MAX]; - TestSuite_AddMockServerTest ( - suite, "/change_stream/pipeline", test_change_stream_pipeline); - - TestSuite_AddFull (suite, - "/change_stream/live/single_server", - test_change_stream_live_single_server, - NULL, - NULL, - test_framework_skip_if_not_single_version_5); - - TestSuite_AddFull (suite, - "/change_stream/live/track_resume_token", - test_change_stream_live_track_resume_token, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6); - - TestSuite_AddFull (suite, - "/change_stream/live/batch_size", - test_change_stream_live_batch_size, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6); - - TestSuite_AddFull (suite, - "/change_stream/live/missing_resume_token", - test_change_stream_live_missing_resume_token, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6); - - TestSuite_AddFull (suite, - "/change_stream/live/invalid_resume_token", - test_change_stream_live_invalid_resume_token, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6); - - TestSuite_AddMockServerTest (suite, - "/change_stream/resumable_error", - test_change_stream_resumable_error); - - TestSuite_AddMockServerTest ( - suite, "/change_stream/options", test_change_stream_options); - - TestSuite_AddFull (suite, - "/change_stream/live/watch", - test_change_stream_live_watch, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6); - - TestSuite_AddFull (suite, - "/change_stream/live/read_prefs", - test_change_stream_live_read_prefs, - NULL, - NULL, - _skip_if_no_start_at_optime); - - TestSuite_Add (suite, - "/change_stream/server_selection_fails", - test_change_stream_server_selection_fails); - - TestSuite_AddFull (suite, - "/change_stream/next_after_error", - test_change_stream_next_after_error, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6); - - TestSuite_AddFull (suite, - "/change_stream/accepts_array", - test_change_stream_accepts_array, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6); - TestSuite_AddMockServerTest ( - suite, "/change_stream/getmore_errors", test_getmore_errors); - TestSuite_AddFull (suite, - "/change_stream/start_at_operation_time", - test_change_stream_start_at_operation_time, - NULL, - NULL, - test_framework_skip_if_not_rs_version_7, - test_framework_skip_if_no_crypto, - _skip_if_no_start_at_optime); - TestSuite_AddFull (suite, - "/change_stream/resume_at_optime", - test_change_stream_resume_at_optime, - NULL, - NULL, - test_framework_skip_if_not_rs_version_7, - test_framework_skip_if_no_crypto, - _skip_if_no_start_at_optime); - TestSuite_AddFull (suite, - "/change_stream/resume_with_post_batch_resume_token", - test_change_stream_resume_with_post_batch_resume_token, - NULL, - NULL, - test_framework_skip_if_not_rs_version_7, - test_framework_skip_if_no_crypto, - _skip_if_no_start_at_optime); - TestSuite_AddFull (suite, - "/change_stream/database", - test_change_stream_database_watch, - NULL, - NULL, - _skip_if_no_db_watch); - TestSuite_AddFull (suite, - "/change_stream/client", - test_change_stream_client_watch, - NULL, - NULL, - _skip_if_no_client_watch); - TestSuite_AddMockServerTest ( - suite, "/change_stream/resume_with_first_doc", test_resume_cases); - TestSuite_AddMockServerTest ( - suite, - "/change_stream/resume_with_first_doc/post_batch_resume_token", - test_resume_cases_with_post_batch_resume_token); - TestSuite_AddFull (suite, - "/change_stream/error_null_doc", - test_error_null_doc, - NULL, - NULL, - _skip_if_no_client_watch); - TestSuite_AddFull (suite, - "/change_stream/live/prose_test_11", - prose_test_11, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6, - test_framework_skip_if_max_wire_version_less_than_8); - TestSuite_AddFull (suite, - "/change_stream/live/prose_test_12", - prose_test_12, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6, - test_framework_skip_if_max_wire_version_more_than_7); - TestSuite_AddFull (suite, - "/change_stream/live/prose_test_13", - prose_test_13, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6, - _skip_if_no_start_at_optime); - TestSuite_AddFull (suite, - "/change_stream/live/prose_test_14", - prose_test_14, - NULL, - NULL, - test_framework_skip_if_mongos, - test_framework_skip_if_not_rs_version_7); - TestSuite_AddMockServerTest ( - suite, "/change_streams/prose_test_17", prose_test_17); - TestSuite_AddMockServerTest ( - suite, "/change_streams/prose_test_18", prose_test_18); - - - test_framework_resolve_path (JSON_DIR "/change_streams", resolved); - install_json_test_suite (suite, resolved, &test_change_stream_spec_cb); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-client-pool.c b/lib/mongoc/libmongoc/tests/test-mongoc-client-pool.c deleted file mode 100644 index 04e0584a88f5bb20d71bcbcc3a897200e5dc5272..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-client-pool.c +++ /dev/null @@ -1,309 +0,0 @@ -#include <mongoc/mongoc.h> -#include "mongoc/mongoc-client-pool-private.h" -#include "mongoc/mongoc-util-private.h" - - -#include "TestSuite.h" -#include "test-libmongoc.h" - - -static void -test_mongoc_client_pool_basic (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - mongoc_uri_t *uri; - - uri = mongoc_uri_new ("mongodb://127.0.0.1/?maxpoolsize=1"); - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - BSON_ASSERT (client); - mongoc_client_pool_push (pool, client); - mongoc_uri_destroy (uri); - mongoc_client_pool_destroy (pool); -} - - -static void -test_mongoc_client_pool_try_pop (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - mongoc_uri_t *uri; - - uri = mongoc_uri_new ("mongodb://127.0.0.1/?maxpoolsize=1"); - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - BSON_ASSERT (client); - BSON_ASSERT (!mongoc_client_pool_try_pop (pool)); - mongoc_client_pool_push (pool, client); - mongoc_uri_destroy (uri); - mongoc_client_pool_destroy (pool); -} - -static void -test_mongoc_client_pool_min_size_zero (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client1; - mongoc_client_t *client2; - mongoc_client_t *client3; - mongoc_client_t *client4; - mongoc_uri_t *uri; - - uri = mongoc_uri_new (NULL); - pool = mongoc_client_pool_new (uri); - - client1 = mongoc_client_pool_pop (pool); - client2 = mongoc_client_pool_pop (pool); - mongoc_client_pool_push (pool, client2); - mongoc_client_pool_push (pool, client1); - - BSON_ASSERT (mongoc_client_pool_get_size (pool) == 2); - client3 = mongoc_client_pool_pop (pool); - - /* min pool size zero means "no min", so clients weren't destroyed */ - BSON_ASSERT (client3 == client1); - client4 = mongoc_client_pool_pop (pool); - BSON_ASSERT (client4 == client2); - - mongoc_client_pool_push (pool, client4); - mongoc_client_pool_push (pool, client3); - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); -} - -static void -test_mongoc_client_pool_min_size_dispose (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - mongoc_uri_t *uri; - mongoc_client_t *c0, *c1, *c2, *c3; - - capture_logs (true); - uri = mongoc_uri_new ("mongodb://127.0.0.1/?minpoolsize=2"); - pool = mongoc_client_pool_new (uri); - - c0 = mongoc_client_pool_pop (pool); - BSON_ASSERT (c0); - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 1); - - c1 = mongoc_client_pool_pop (pool); - BSON_ASSERT (c1); - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 2); - - c2 = mongoc_client_pool_pop (pool); - BSON_ASSERT (c2); - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 3); - - c3 = mongoc_client_pool_pop (pool); - BSON_ASSERT (c3); - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 4); - - mongoc_client_pool_push (pool, c0); /* queue is [c0] */ - ASSERT_CMPSIZE_T (mongoc_client_pool_num_pushed (pool), ==, (size_t) 1); - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 4); - - mongoc_client_pool_push (pool, c1); /* queue is [c1, c0] */ - ASSERT_CMPSIZE_T (mongoc_client_pool_num_pushed (pool), ==, (size_t) 2); - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 4); - - mongoc_client_pool_push (pool, c2); /* queue is [c2, c1] */ - ASSERT_CMPSIZE_T (mongoc_client_pool_num_pushed (pool), ==, (size_t) 2); - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 3); - - mongoc_client_pool_push (pool, c3); /* queue is [c3, c2] */ - ASSERT_CMPSIZE_T (mongoc_client_pool_num_pushed (pool), ==, (size_t) 2); - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 2); - - /* BSON_ASSERT oldest client was destroyed, newest were stored */ - client = mongoc_client_pool_pop (pool); - BSON_ASSERT (client); - BSON_ASSERT (client == c3); - - client = mongoc_client_pool_pop (pool); - BSON_ASSERT (client); - BSON_ASSERT (client == c2); - - ASSERT_CMPSIZE_T (mongoc_client_pool_get_size (pool), ==, (size_t) 2); - - /* clean up */ - mongoc_client_pool_push (pool, c2); - mongoc_client_pool_push (pool, c3); - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); -} - -static void -test_mongoc_client_pool_set_max_size (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - mongoc_uri_t *uri; - mongoc_array_t conns; - int i; - - _mongoc_array_init (&conns, sizeof client); - - uri = mongoc_uri_new ("mongodb://127.0.0.1/?maxpoolsize=10"); - pool = mongoc_client_pool_new (uri); - - for (i = 0; i < 5; i++) { - client = mongoc_client_pool_pop (pool); - BSON_ASSERT (client); - _mongoc_array_append_val (&conns, client); - BSON_ASSERT (mongoc_client_pool_get_size (pool) == i + 1); - } - - mongoc_client_pool_max_size (pool, 3); - - BSON_ASSERT (mongoc_client_pool_try_pop (pool) == NULL); - - for (i = 0; i < 5; i++) { - client = _mongoc_array_index (&conns, mongoc_client_t *, i); - BSON_ASSERT (client); - mongoc_client_pool_push (pool, client); - } - - _mongoc_array_clear (&conns); - _mongoc_array_destroy (&conns); - mongoc_uri_destroy (uri); - mongoc_client_pool_destroy (pool); -} - -static void -test_mongoc_client_pool_set_min_size (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - mongoc_uri_t *uri; - mongoc_array_t conns; - int i; - - _mongoc_array_init (&conns, sizeof client); - - uri = mongoc_uri_new ("mongodb://127.0.0.1/?maxpoolsize=10&minpoolsize=3"); - capture_logs (true); - pool = mongoc_client_pool_new (uri); - ASSERT_CAPTURED_LOG ( - "minpoolsize URI option", MONGOC_LOG_LEVEL_WARNING, "is deprecated"); - - for (i = 0; i < 10; i++) { - client = mongoc_client_pool_pop (pool); - BSON_ASSERT (client); - _mongoc_array_append_val (&conns, client); - BSON_ASSERT (mongoc_client_pool_get_size (pool) == i + 1); - } - - capture_logs (true); - BEGIN_IGNORE_DEPRECATIONS - mongoc_client_pool_min_size (pool, 7); - END_IGNORE_DEPRECATIONS - ASSERT_CAPTURED_LOG ("mongoc_client_pool_min_size", - MONGOC_LOG_LEVEL_WARNING, - "mongoc_client_pool_min_size is deprecated"); - - for (i = 0; i < 10; i++) { - client = _mongoc_array_index (&conns, mongoc_client_t *, i); - BSON_ASSERT (client); - mongoc_client_pool_push (pool, client); - } - - BSON_ASSERT (mongoc_client_pool_get_size (pool) == 7); - - _mongoc_array_clear (&conns); - _mongoc_array_destroy (&conns); - mongoc_uri_destroy (uri); - mongoc_client_pool_destroy (pool); -} - -#ifndef MONGOC_ENABLE_SSL -static void -test_mongoc_client_pool_ssl_disabled (void) -{ - mongoc_uri_t *uri = mongoc_uri_new ("mongodb://host/?ssl=true"); - - ASSERT (uri); - capture_logs (true); - ASSERT (NULL == mongoc_client_pool_new (uri)); - - mongoc_uri_destroy (uri); -} -#endif - -static void -test_mongoc_client_pool_handshake (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - mongoc_uri_t *uri; - - uri = mongoc_uri_new ("mongodb://127.0.0.1/?maxpoolsize=1"); - pool = mongoc_client_pool_new (uri); - - - ASSERT (mongoc_client_pool_set_appname (pool, "some application")); - /* Be sure we can't set it twice */ - capture_logs (true); - ASSERT (!mongoc_client_pool_set_appname (pool, "a")); - ASSERT_CAPTURED_LOG ("_mongoc_topology_scanner_set_appname", - MONGOC_LOG_LEVEL_ERROR, - "Cannot set appname more than once"); - capture_logs (false); - - mongoc_client_pool_destroy (pool); - - /* Make sure that after we pop a client we can't set handshake anymore */ - pool = mongoc_client_pool_new (uri); - - client = mongoc_client_pool_pop (pool); - - /* Be sure a client can't set it now that we've popped them */ - capture_logs (true); - ASSERT (!mongoc_client_set_appname (client, "a")); - ASSERT_CAPTURED_LOG ("_mongoc_topology_scanner_set_appname", - MONGOC_LOG_LEVEL_ERROR, - "Cannot call set_appname on a client from a pool"); - capture_logs (false); - - mongoc_client_pool_push (pool, client); - - /* even now that we pushed the client back we shouldn't be able to set - * the handshake */ - capture_logs (true); - ASSERT (!mongoc_client_pool_set_appname (pool, "a")); - ASSERT_CAPTURED_LOG ("_mongoc_topology_scanner_set_appname", - MONGOC_LOG_LEVEL_ERROR, - "Cannot set appname after handshake initiated"); - capture_logs (false); - - mongoc_uri_destroy (uri); - mongoc_client_pool_destroy (pool); -} - -void -test_client_pool_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/ClientPool/basic", test_mongoc_client_pool_basic); - TestSuite_Add ( - suite, "/ClientPool/try_pop", test_mongoc_client_pool_try_pop); - TestSuite_Add (suite, - "/ClientPool/min_size_zero", - test_mongoc_client_pool_min_size_zero); - TestSuite_Add (suite, - "/ClientPool/min_size_dispose", - test_mongoc_client_pool_min_size_dispose); - TestSuite_Add ( - suite, "/ClientPool/set_max_size", test_mongoc_client_pool_set_max_size); - TestSuite_Add ( - suite, "/ClientPool/set_min_size", test_mongoc_client_pool_set_min_size); - - TestSuite_Add ( - suite, "/ClientPool/handshake", test_mongoc_client_pool_handshake); - -#ifndef MONGOC_ENABLE_SSL - TestSuite_Add ( - suite, "/ClientPool/ssl_disabled", test_mongoc_client_pool_ssl_disabled); -#endif -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-client-session.c b/lib/mongoc/libmongoc/tests/test-mongoc-client-session.c deleted file mode 100644 index 33abadaed589d3796a69ff4d0de669eb9234e2c5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-client-session.c +++ /dev/null @@ -1,2804 +0,0 @@ -#include <mongoc/mongoc-cursor-private.h> -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-change-stream-private.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/utlist.h" -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "mock_server/mock-server.h" -#include "mock_server/future-functions.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "session-test" - - -static void -test_session_opts_clone (void) -{ - mongoc_session_opt_t *opts; - mongoc_session_opt_t *clone; - - opts = mongoc_session_opts_new (); - clone = mongoc_session_opts_clone (opts); - /* causal is enabled by default */ - BSON_ASSERT (mongoc_session_opts_get_causal_consistency (clone)); - mongoc_session_opts_destroy (clone); - - mongoc_session_opts_set_causal_consistency (opts, false); - clone = mongoc_session_opts_clone (opts); - BSON_ASSERT (!mongoc_session_opts_get_causal_consistency (clone)); - - mongoc_session_opts_destroy (clone); - mongoc_session_opts_destroy (opts); -} - - -static void -test_session_no_crypto (void *ctx) -{ - mongoc_client_t *client; - bson_error_t error; - - client = test_framework_client_new (); - BSON_ASSERT (!mongoc_client_start_session (client, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_SESSION_FAILURE, - "need a cryptography library"); - - mongoc_client_destroy (client); -} - - -#define ASSERT_SESSIONS_MATCH(_lsid_a, _lsid_b) \ - do { \ - assert_match_bson ((_lsid_a), (_lsid_b), false); \ - } while (0) - - -#define ASSERT_SESSIONS_DIFFER(_lsid_a, _lsid_b) \ - do { \ - BSON_ASSERT (!match_bson ((_lsid_a), (_lsid_b), false)); \ - } while (0) - - -/* "Pool is LIFO" test from Driver Sessions Spec */ -static void -_test_session_pool_lifo (bool pooled) -{ - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_client_session_t *a, *b, *c, *d; - bson_t lsid_a, lsid_b; - bson_error_t error; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - a = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (a, error); - a->server_session->last_used_usec = bson_get_monotonic_time (); - bson_copy_to (mongoc_client_session_get_lsid (a), &lsid_a); - - b = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (b, error); - b->server_session->last_used_usec = bson_get_monotonic_time (); - bson_copy_to (mongoc_client_session_get_lsid (b), &lsid_b); - - /* return server sessions to pool: first "a", then "b" */ - mongoc_client_session_destroy (a); - mongoc_client_session_destroy (b); - - /* first pop returns last push */ - c = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (c, error); - ASSERT_SESSIONS_MATCH (&lsid_b, mongoc_client_session_get_lsid (c)); - - /* second pop returns previous push */ - d = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (d, error); - ASSERT_SESSIONS_MATCH (&lsid_a, mongoc_client_session_get_lsid (d)); - - mongoc_client_session_destroy (c); - mongoc_client_session_destroy (d); - - if (pooled) { - /* the pooled client never needed to connect, so it warns that - * it isn't connecting in order to send endSessions */ - capture_logs (true); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - bson_destroy (&lsid_a); - bson_destroy (&lsid_b); -} - - -static void -test_session_pool_lifo_single (void *ctx) -{ - _test_session_pool_lifo (false); -} - - -static void -test_session_pool_lifo_pooled (void *ctx) -{ - _test_session_pool_lifo (true); -} - - -/* test that a session that is timed out is not added to the pool, - * and a session that times out while it's in the pool is destroyed - */ -static void -_test_session_pool_timeout (bool pooled) -{ - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - uint32_t server_id; - mongoc_client_session_t *s; - bson_error_t error; - bson_t lsid; - int64_t almost_timeout_usec; - - almost_timeout_usec = - (test_framework_session_timeout_minutes () - 1) * 60 * 1000 * 1000; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - /* - * trigger discovery - */ - server_id = mongoc_topology_select_server_id ( - client->topology, MONGOC_SS_READ, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - - /* - * get a session, set last_used_date more than 29 minutes ago and return to - * the pool. it's timed out & freed. - */ - BSON_ASSERT (!client->topology->session_pool); - s = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (s, error); - bson_copy_to (mongoc_client_session_get_lsid (s), &lsid); - - s->server_session->last_used_usec = - (bson_get_monotonic_time () - almost_timeout_usec - 100); - - mongoc_client_session_destroy (s); - BSON_ASSERT (!client->topology->session_pool); - - /* - * get a new session, set last_used_date so it has one second left to live, - * return to the pool, wait 1.5 seconds. it's timed out & freed. - */ - s = mongoc_client_start_session (client, NULL, &error); - ASSERT_SESSIONS_DIFFER (&lsid, mongoc_client_session_get_lsid (s)); - - bson_destroy (&lsid); - bson_copy_to (mongoc_client_session_get_lsid (s), &lsid); - - s->server_session->last_used_usec = - (bson_get_monotonic_time () + 1000 * 1000 - almost_timeout_usec); - - mongoc_client_session_destroy (s); - BSON_ASSERT (client->topology->session_pool); - ASSERT_SESSIONS_MATCH (&lsid, &client->topology->session_pool->lsid); - - _mongoc_usleep (1500 * 1000); - - /* getting a new client session must start a new server session */ - s = mongoc_client_start_session (client, NULL, &error); - ASSERT_SESSIONS_DIFFER (&lsid, mongoc_client_session_get_lsid (s)); - BSON_ASSERT (!client->topology->session_pool); - mongoc_client_session_destroy (s); - - if (pooled) { - /* the pooled client never needed to connect, so it warns that - * it isn't connecting in order to send endSessions */ - capture_logs (true); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - bson_destroy (&lsid); -} - - -static void -test_session_pool_timeout_single (void *ctx) -{ - _test_session_pool_timeout (false); -} - - -static void -test_session_pool_timeout_pooled (void *ctx) -{ - _test_session_pool_timeout (true); -} - - -/* test that a session that times out while it's in the pool is reaped when - * another session is added - */ -static void -_test_session_pool_reap (bool pooled) -{ - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_client_session_t *a, *b; - bool r; - bson_error_t error; - bson_t lsid_a, lsid_b; - int64_t almost_timeout_usec; - mongoc_server_session_t *session_pool; - - almost_timeout_usec = - (test_framework_session_timeout_minutes () - 1) * 60 * 1000 * 1000; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - /* - * trigger discovery - */ - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - /* - * get a new session, set last_used_date so it has one second left to live, - * return to the pool, wait 1.5 seconds. - */ - a = mongoc_client_start_session (client, NULL, &error); - b = mongoc_client_start_session (client, NULL, &error); - bson_copy_to (mongoc_client_session_get_lsid (a), &lsid_a); - bson_copy_to (mongoc_client_session_get_lsid (b), &lsid_b); - - a->server_session->last_used_usec = - (bson_get_monotonic_time () + 1000 * 1000 - almost_timeout_usec); - - mongoc_client_session_destroy (a); - BSON_ASSERT (client->topology->session_pool); /* session is pooled */ - - _mongoc_usleep (1500 * 1000); - - /* - * returning session B causes session A to be reaped - */ - b->server_session->last_used_usec = bson_get_monotonic_time (); - mongoc_client_session_destroy (b); - BSON_ASSERT (client->topology->session_pool); - ASSERT_SESSIONS_MATCH (&lsid_b, &client->topology->session_pool->lsid); - /* session B is the only session in the pool */ - session_pool = client->topology->session_pool; - BSON_ASSERT (session_pool == session_pool->prev); - BSON_ASSERT (session_pool == session_pool->next); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - bson_destroy (&lsid_a); - bson_destroy (&lsid_b); -} - - -static void -test_session_pool_reap_single (void *ctx) -{ - _test_session_pool_reap (false); -} - - -static void -test_session_pool_reap_pooled (void *ctx) -{ - _test_session_pool_reap (true); -} - - -static void -test_session_id_bad (void *ctx) -{ - const char *bad_opts[] = { - "{'sessionId': null}", - "{'sessionId': 'foo'}", - "{'sessionId': {'$numberInt': '1'}}", - "{'sessionId': {'$numberDouble': '1'}}", - /* doesn't fit in uint32 */ - "{'sessionId': {'$numberLong': '5000000000'}}", - /* doesn't match existing mongoc_client_session_t */ - "{'sessionId': {'$numberLong': '123'}}", - NULL, - }; - - const char **bad_opt; - mongoc_client_t *client; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - for (bad_opt = bad_opts; *bad_opt; bad_opt++) { - r = mongoc_client_read_command_with_opts (client, - "admin", - tmp_bson ("{'ping': 1}"), - NULL, - tmp_bson (*bad_opt), - NULL, - &error); - - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid sessionId"); - - memset (&error, 0, sizeof (bson_error_t)); - } - - mongoc_client_destroy (client); -} - -static void -_test_session_supported (bool pooled) -{ - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - mongoc_client_session_t *session; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - if (test_framework_session_timeout_minutes () == -1) { - BSON_ASSERT (!mongoc_client_start_session (client, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_SESSION_FAILURE, - "Server does not support sessions"); - } else { - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - mongoc_client_session_destroy (session); - } - - if (pooled) { - /* the pooled client never needed to connect, so it warns that - * it isn't connecting in order to send endSessions */ - capture_logs (true); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - -static void -test_session_supported_single (void *ctx) -{ - _test_session_supported (false); -} - -static void -test_session_supported_pooled (void *ctx) -{ - _test_session_supported (true); -} - -static void -_test_mock_end_sessions (bool pooled) -{ - mock_server_t *server; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - mongoc_client_session_t *session; - bson_t lsid; - bson_t opts = BSON_INITIALIZER; - bson_t *expected_cmd; - future_t *future; - request_t *request; - bool r; - - server = mock_mongos_new (WIRE_VERSION_OP_MSG); - mock_server_run (server); - - if (pooled) { - pool = mongoc_client_pool_new (mock_server_get_uri (server)); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - } - - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - bson_copy_to (mongoc_client_session_get_lsid (session), &lsid); - r = mongoc_client_session_append (session, &opts, &error); - ASSERT_OR_PRINT (r, error); - - future = future_client_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, &opts, NULL, &error); - - request = mock_server_receives_msg ( - server, 0, tmp_bson ("{'ping': 1, 'lsid': {'$exists': true}}")); - mock_server_replies_ok_and_destroys (request); - - BSON_ASSERT (future_get_bool (future)); - future_destroy (future); - - /* before destroying the session, construct the expected endSessions cmd */ - expected_cmd = - BCON_NEW ("endSessions", - "[", - BCON_DOCUMENT (mongoc_client_session_get_lsid (session)), - "]"); - - mongoc_client_session_destroy (session); - - if (pooled) { - mongoc_client_pool_push (pool, client); - future = future_client_pool_destroy (pool); - } else { - future = future_client_destroy (client); - } - - /* check that we got the expected endSessions cmd */ - request = mock_server_receives_msg (server, 0, expected_cmd); - mock_server_replies_ok_and_destroys (request); - future_wait (future); - future_destroy (future); - - mock_server_destroy (server); - bson_destroy (expected_cmd); - bson_destroy (&lsid); - bson_destroy (&opts); -} - -static void -test_mock_end_sessions_single (void) -{ - _test_mock_end_sessions (false); -} - -static void -test_mock_end_sessions_pooled (void) -{ - _test_mock_end_sessions (true); -} - -typedef struct { - int started_calls; - int succeeded_calls; - mongoc_array_t cmds; - mongoc_client_pool_t *pool; - mongoc_client_t *client; -} endsessions_test_t; - -static void -endsessions_started_cb (const mongoc_apm_command_started_t *event) -{ - endsessions_test_t *test; - bson_t *cmd; - - if (strcmp (mongoc_apm_command_started_get_command_name (event), - "endSessions") != 0) { - return; - } - - test = (endsessions_test_t *) mongoc_apm_command_started_get_context (event); - test->started_calls++; - cmd = bson_copy (mongoc_apm_command_started_get_command (event)); - _mongoc_array_append_vals (&test->cmds, &cmd, 1); -} - -static void -endsessions_succeeded_cb (const mongoc_apm_command_succeeded_t *event) -{ - endsessions_test_t *test; - - if (strcmp (mongoc_apm_command_succeeded_get_command_name (event), - "endSessions") != 0) { - return; - } - - test = - (endsessions_test_t *) mongoc_apm_command_succeeded_get_context (event); - test->succeeded_calls++; -} - -static void -endsessions_test_init (endsessions_test_t *test, bool pooled) -{ - mongoc_apm_callbacks_t *callbacks; - - test->started_calls = test->succeeded_calls = 0; - _mongoc_array_init (&test->cmds, sizeof (bson_t *)); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, endsessions_started_cb); - mongoc_apm_set_command_succeeded_cb (callbacks, endsessions_succeeded_cb); - - if (pooled) { - test->pool = test_framework_client_pool_new (); - ASSERT ( - mongoc_client_pool_set_apm_callbacks (test->pool, callbacks, test)); - test->client = mongoc_client_pool_pop (test->pool); - } else { - test->pool = NULL; - test->client = test_framework_client_new (); - ASSERT (mongoc_client_set_apm_callbacks (test->client, callbacks, test)); - } - - mongoc_apm_callbacks_destroy (callbacks); -} - -static void -endsessions_test_destroy_client (endsessions_test_t *test) -{ - if (test->pool) { - mongoc_client_pool_push (test->pool, test->client); - mongoc_client_pool_destroy (test->pool); - } else { - mongoc_client_destroy (test->client); - } -} - -static void -endsessions_test_get_ended_lsids (endsessions_test_t *test, - size_t index, - bson_t *ended_lsids) -{ - bson_iter_t iter; - - ASSERT_CMPINT (test->started_calls, >, (int) index); - - BSON_ASSERT ( - bson_iter_init_find (&iter, - _mongoc_array_index (&test->cmds, bson_t *, index), - "endSessions")); - - BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (&iter)); - bson_iter_bson (&iter, ended_lsids); -} - -static void -endsessions_test_cleanup (endsessions_test_t *test) -{ - size_t i; - - for (i = 0; i < test->cmds.len; i++) { - bson_destroy (_mongoc_array_index (&test->cmds, bson_t *, i)); - } - - _mongoc_array_destroy (&test->cmds); -} - -static void -_test_end_sessions (bool pooled) -{ - endsessions_test_t test; - mongoc_client_t *client; - bson_error_t error; - mongoc_client_session_t *cs1; - mongoc_client_session_t *cs2; - bson_t lsid1; - bson_t lsid2; - bson_t opts1 = BSON_INITIALIZER; - bson_t opts2 = BSON_INITIALIZER; - bool lsid1_ended = false; - bool lsid2_ended = false; - bson_t ended_lsids; - bson_iter_t iter; - bson_t ended_lsid; - match_ctx_t ctx = {{0}}; - bool r; - - endsessions_test_init (&test, pooled); - client = test.client; - - /* - * create and use sessions 1 and 2 - */ - cs1 = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (cs1, error); - bson_copy_to (mongoc_client_session_get_lsid (cs1), &lsid1); - r = mongoc_client_session_append (cs1, &opts1, &error); - ASSERT_OR_PRINT (r, error); - r = mongoc_client_command_with_opts ( - client, "admin", tmp_bson ("{'count': 'c'}"), NULL, &opts1, NULL, &error); - ASSERT_OR_PRINT (r, error); - - cs2 = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (cs2, error); - bson_copy_to (mongoc_client_session_get_lsid (cs2), &lsid2); - r = mongoc_client_session_append (cs2, &opts2, &error); - ASSERT_OR_PRINT (r, error); - r = mongoc_client_command_with_opts ( - client, "admin", tmp_bson ("{'count': 'c'}"), NULL, &opts2, NULL, &error); - ASSERT_OR_PRINT (r, error); - - /* - * return server sessions to the pool - */ - mongoc_client_session_destroy (cs1); - mongoc_client_session_destroy (cs2); - endsessions_test_destroy_client (&test); - - /* - * sessions were ended on server - */ - ASSERT_CMPINT (test.started_calls, ==, 1); - ASSERT_CMPINT (test.succeeded_calls, ==, 1); - - endsessions_test_get_ended_lsids (&test, 0, &ended_lsids); - - BSON_ASSERT (bson_iter_init (&iter, &ended_lsids)); - while (bson_iter_next (&iter)) { - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - bson_iter_bson (&iter, &ended_lsid); - if (match_bson_with_ctx (&ended_lsid, &lsid1, &ctx)) { - lsid1_ended = true; - } else if (match_bson_with_ctx (&ended_lsid, &lsid2, &ctx)) { - lsid2_ended = true; - } - } - - BSON_ASSERT (lsid1_ended); - BSON_ASSERT (lsid2_ended); - - bson_destroy (&lsid1); - bson_destroy (&opts1); - bson_destroy (&lsid2); - bson_destroy (&opts2); - endsessions_test_cleanup (&test); -} - -static void -test_end_sessions_single (void *ctx) -{ - _test_end_sessions (false); -} - -static void -test_end_sessions_pooled (void *ctx) -{ - _test_end_sessions (true); -} - - -static void -_test_end_sessions_many (bool pooled) -{ - endsessions_test_t test; - mongoc_client_t *client; - int i; - mongoc_client_session_t *sessions[10001]; - bson_error_t error; - bson_t ended_lsids; - - endsessions_test_init (&test, pooled); - client = test.client; - /* connect */ - ASSERT_OR_PRINT ( - mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error), - error); - - /* - * create and destroy 10,001 sessions - */ - for (i = 0; i < sizeof sessions / sizeof (mongoc_client_session_t *); i++) { - sessions[i] = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (sessions[i], error); - } - - for (i = 0; i < sizeof sessions / sizeof (mongoc_client_session_t *); i++) { - mongoc_client_session_destroy (sessions[i]); - } - - endsessions_test_destroy_client (&test); - - /* - * sessions were ended on the server, ten thousand at a time - */ - ASSERT_CMPINT (test.started_calls, ==, 2); - ASSERT_CMPINT (test.succeeded_calls, ==, 2); - - endsessions_test_get_ended_lsids (&test, 0, &ended_lsids); - ASSERT_CMPINT (bson_count_keys (&ended_lsids), ==, 10000); - endsessions_test_get_ended_lsids (&test, 1, &ended_lsids); - ASSERT_CMPINT (bson_count_keys (&ended_lsids), ==, 1); - - endsessions_test_cleanup (&test); -} - -static void -test_end_sessions_many_single (void *ctx) -{ - _test_end_sessions_many (false); -} - -static void -test_end_sessions_many_pooled (void *ctx) -{ - _test_end_sessions_many (true); -} - -static void -_test_advance_cluster_time (mongoc_client_session_t *cs, - int new_timestamp, - int new_increment, - bool should_advance) -{ - bson_t *old_cluster_time; - bson_t *new_cluster_time; - - old_cluster_time = bson_copy (mongoc_client_session_get_cluster_time (cs)); - new_cluster_time = - tmp_bson ("{'clusterTime': {'$timestamp': {'t': %d, 'i': %d}}}", - new_timestamp, - new_increment); - - mongoc_client_session_advance_cluster_time (cs, new_cluster_time); - - if (should_advance) { - assert_match_bson ( - mongoc_client_session_get_cluster_time (cs), new_cluster_time, false); - } else { - assert_match_bson ( - mongoc_client_session_get_cluster_time (cs), old_cluster_time, false); - } - - bson_destroy (old_cluster_time); -} - -static void -test_session_advance_cluster_time (void *ctx) -{ - mongoc_client_t *client; - bson_error_t error; - mongoc_client_session_t *cs; - - client = test_framework_client_new (); - cs = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (cs, error); - BSON_ASSERT (!mongoc_client_session_get_cluster_time (cs)); - - capture_logs (true); - mongoc_client_session_advance_cluster_time (cs, tmp_bson ("{'foo': 1}")); - ASSERT_CAPTURED_LOG ("mongoc_client_session_advance_cluster_time", - MONGOC_LOG_LEVEL_ERROR, - "Cannot parse cluster time"); - - capture_logs (true); - mongoc_client_session_advance_cluster_time (cs, - tmp_bson ("{'clusterTime': 1}")); - ASSERT_CAPTURED_LOG ("mongoc_client_session_advance_cluster_time", - MONGOC_LOG_LEVEL_ERROR, - "Cannot parse cluster time"); - - mongoc_client_session_advance_cluster_time ( - cs, tmp_bson ("{'clusterTime': {'$timestamp': {'t': 1, 'i': 1}}}")); - - _test_advance_cluster_time (cs, 1, 0, false); - _test_advance_cluster_time (cs, 2, 2, true); - _test_advance_cluster_time (cs, 2, 1, false); - _test_advance_cluster_time (cs, 3, 1, true); - - mongoc_client_session_destroy (cs); - mongoc_client_destroy (client); -} - - -static void -_test_advance_operation_time (mongoc_client_session_t *cs, - uint32_t t, - uint32_t i, - bool should_advance) -{ - uint32_t old_t, old_i; - uint32_t new_t, new_i; - - mongoc_client_session_get_operation_time (cs, &old_t, &old_i); - mongoc_client_session_advance_operation_time (cs, t, i); - mongoc_client_session_get_operation_time (cs, &new_t, &new_i); - - if (should_advance) { - ASSERT_CMPUINT32 (new_t, ==, t); - ASSERT_CMPUINT32 (new_i, ==, i); - } else if (new_t == t && new_i == i) { - fprintf (stderr, - "Shouldn't have advanced from operationTime %" PRIu32 - ", %" PRIu32 " to %" PRIu32 ", %" PRIu32 "\n", - old_t, - old_i, - t, - i); - abort (); - } -} - - -static void -test_session_advance_operation_time (void *ctx) -{ - mongoc_client_t *client; - bson_error_t error; - mongoc_client_session_t *cs; - uint32_t t, i; - - client = test_framework_client_new (); - cs = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (cs, error); - mongoc_client_session_get_operation_time (cs, &t, &i); - - ASSERT_CMPUINT32 (t, ==, 0); - ASSERT_CMPUINT32 (t, ==, 0); - - mongoc_client_session_advance_operation_time (cs, 1, 1); - - _test_advance_operation_time (cs, 1, 0, false); - _test_advance_operation_time (cs, 2, 2, true); - _test_advance_operation_time (cs, 2, 1, false); - _test_advance_operation_time (cs, 3, 1, true); - - mongoc_client_session_destroy (cs); - mongoc_client_destroy (client); -} - - -typedef enum { - CORRECT_CLIENT, - INCORRECT_CLIENT, -} session_test_correct_t; - - -typedef enum { - CAUSAL, - NOT_CAUSAL, -} session_test_causal_t; - -typedef struct { - bool verbose; - mongoc_client_t *session_client, *client; - mongoc_database_t *session_db, *db; - mongoc_collection_t *session_collection, *collection; - mongoc_client_session_t *cs; - mongoc_client_session_t *wrong_cs; - bson_t opts; - bson_error_t error; - int n_started; - int n_succeeded; - bool expect_explicit_lsid; - bool acknowledged; - bool succeeded; - mongoc_array_t cmds; - mongoc_array_t replies; - bson_t sent_lsid; - bson_t sent_cluster_time; - bson_t received_cluster_time; -} session_test_t; - - -static void -started (const mongoc_apm_command_started_t *event) -{ - match_ctx_t ctx = {{0}}; - bson_iter_t iter; - bool has_cluster_time; - bson_t cluster_time; - bson_t lsid; - const bson_t *client_session_lsid; - bson_t *cmd = bson_copy (mongoc_apm_command_started_get_command (event)); - const char *cmd_name = mongoc_apm_command_started_get_command_name (event); - session_test_t *test = - (session_test_t *) mongoc_apm_command_started_get_context (event); - - ctx.strict_numeric_types = false; - - if (test->verbose) { - char *s = bson_as_json (cmd, NULL); - printf ("%s\n", s); - bson_free (s); - } - - if (!strcmp (cmd_name, "endSessions")) { - BSON_ASSERT (!bson_has_field (cmd, "lsid")); - bson_destroy (cmd); - return; - } - - if (test->acknowledged) { - if (!bson_iter_init_find (&iter, cmd, "lsid")) { - fprintf (stderr, "no lsid sent with command %s\n", cmd_name); - abort (); - } - - bson_iter_bson (&iter, &lsid); - client_session_lsid = &test->cs->server_session->lsid; - - if (test->expect_explicit_lsid) { - if (!match_bson_with_ctx (&lsid, client_session_lsid, &ctx)) { - fprintf (stderr, - "command %s should have used client session's lsid\n", - cmd_name); - abort (); - } - } else { - if (match_bson_with_ctx (&lsid, client_session_lsid, &ctx)) { - fprintf (stderr, - "command %s should not have used client session's lsid\n", - cmd_name); - abort (); - } - } - - if (bson_empty (&test->sent_lsid)) { - bson_destroy (&test->sent_lsid); - bson_copy_to (&lsid, &test->sent_lsid); - } else { - if (!match_bson_with_ctx (&lsid, &test->sent_lsid, &ctx)) { - fprintf (stderr, - "command %s used different lsid than previous command\n", - cmd_name); - abort (); - } - } - } else { - /* unacknowledged commands should never include lsid */ - BSON_ASSERT (!bson_has_field (cmd, "lsid")); - } - - has_cluster_time = bson_iter_init_find (&iter, cmd, "$clusterTime"); - if (test->acknowledged && !has_cluster_time) { - fprintf (stderr, "no $clusterTime sent with command %s\n", cmd_name); - abort (); - } - - if (has_cluster_time) { - /* like $clusterTime: {clusterTime: <timestamp>} */ - bson_iter_bson (&iter, &cluster_time); - bson_destroy (&test->sent_cluster_time); - bson_copy_to (&cluster_time, &test->sent_cluster_time); - } - - _mongoc_array_append_vals (&test->cmds, &cmd, 1); - - test->n_started++; -} - - -static void -succeeded (const mongoc_apm_command_succeeded_t *event) -{ - bson_iter_t iter; - bool has_cluster_time; - bson_t cluster_time; - bson_t *reply = bson_copy (mongoc_apm_command_succeeded_get_reply (event)); - const char *cmd_name = mongoc_apm_command_succeeded_get_command_name (event); - session_test_t *test = - (session_test_t *) mongoc_apm_command_succeeded_get_context (event); - - if (test->verbose) { - char *s = bson_as_json (reply, NULL); - printf ("<-- %s\n", s); - bson_free (s); - } - - has_cluster_time = bson_iter_init_find (&iter, reply, "$clusterTime"); - if (test->acknowledged && !has_cluster_time) { - fprintf (stderr, "no $clusterTime in reply to command %s\n", cmd_name); - abort (); - } - - if (strcmp (cmd_name, "endSessions") == 0) { - bson_destroy (reply); - return; - } - - if (has_cluster_time) { - /* like $clusterTime: {clusterTime: <timestamp>} */ - bson_iter_bson (&iter, &cluster_time); - bson_destroy (&test->received_cluster_time); - bson_copy_to (&cluster_time, &test->received_cluster_time); - } - - _mongoc_array_append_vals (&test->replies, &reply, 1); - - test->n_succeeded++; -} - - -static void -failed (const mongoc_apm_command_failed_t *event) -{ - const char *cmd_name; - bson_error_t error; - - session_test_t *test = - (session_test_t *) mongoc_apm_command_failed_get_context (event); - - if (!test->verbose) { - return; - } - - cmd_name = mongoc_apm_command_failed_get_command_name (event); - mongoc_apm_command_failed_get_error (event, &error); - printf ("<-- %s: %s\n", cmd_name, error.message); -} - - -static void -set_session_test_callbacks (session_test_t *test) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, started); - mongoc_apm_set_command_succeeded_cb (callbacks, succeeded); - mongoc_apm_set_command_failed_cb (callbacks, failed); - mongoc_client_set_apm_callbacks (test->client, callbacks, test); - - mongoc_apm_callbacks_destroy (callbacks); -} - - -static session_test_t * -session_test_new (session_test_correct_t correct_client, - session_test_causal_t causal) -{ - session_test_t *test; - mongoc_session_opt_t *cs_opts; - bson_error_t error; - - test = bson_malloc0 (sizeof (session_test_t)); - - test->verbose = test_framework_getenv_bool ("MONGOC_TEST_SESSION_VERBOSE"); - - test->n_started = 0; - test->expect_explicit_lsid = true; - test->acknowledged = true; - test->succeeded = false; - _mongoc_array_init (&test->cmds, sizeof (bson_t *)); - _mongoc_array_init (&test->replies, sizeof (bson_t *)); - bson_init (&test->sent_cluster_time); - bson_init (&test->received_cluster_time); - bson_init (&test->sent_lsid); - - test->session_client = test_framework_client_new (); - mongoc_client_set_error_api (test->session_client, 2); - test->session_db = mongoc_client_get_database (test->session_client, "db"); - test->session_collection = - mongoc_database_get_collection (test->session_db, "collection"); - - bson_init (&test->opts); - - if (correct_client == CORRECT_CLIENT) { - test->client = test->session_client; - test->db = test->session_db; - test->collection = test->session_collection; - } else { - /* test each function with a session from the correct client and a session - * from the wrong client */ - test->client = test_framework_client_new (); - mongoc_client_set_error_api (test->client, 2); - test->wrong_cs = mongoc_client_start_session (test->client, NULL, &error); - ASSERT_OR_PRINT (test->wrong_cs, error); - test->db = mongoc_client_get_database (test->client, "db"); - test->collection = - mongoc_database_get_collection (test->db, "collection"); - } - - set_session_test_callbacks (test); - - cs_opts = mongoc_session_opts_new (); - mongoc_session_opts_set_causal_consistency (cs_opts, causal == CAUSAL); - test->cs = - mongoc_client_start_session (test->session_client, cs_opts, &error); - ASSERT_OR_PRINT (test->cs, error); - - mongoc_session_opts_destroy (cs_opts); - - return test; -} - - -static void -check_session_returned (session_test_t *test, const bson_t *lsid) -{ - match_ctx_t ctx = {{0}}; - mongoc_server_session_t *ss; - bool found; - - ctx.strict_numeric_types = false; - - found = false; - CDL_FOREACH (test->session_client->topology->session_pool, ss) - { - if (match_bson_with_ctx (&ss->lsid, lsid, &ctx)) { - found = true; - break; - } - } - - if (!found) { - fprintf (stderr, - "server session %s not returned to pool\n", - bson_as_json (lsid, NULL)); - abort (); - } -} - -static const bson_t * -first_cmd (session_test_t *test) -{ - ASSERT_CMPSIZE_T (test->cmds.len, >, (size_t) 0); - return _mongoc_array_index (&test->cmds, bson_t *, 0); -} - - -static const bson_t * -last_non_getmore_cmd (session_test_t *test) -{ - ssize_t i; - const bson_t *cmd; - - ASSERT_CMPSIZE_T (test->cmds.len, >, (size_t) 0); - - for (i = test->replies.len - 1; i >= 0; i--) { - cmd = _mongoc_array_index (&test->cmds, bson_t *, i); - if (strcmp (_mongoc_get_command_name (cmd), "getMore") != 0) { - return cmd; - } - } - - fprintf (stderr, "No commands besides getMore were recorded\n"); - abort (); -} - - -static const bson_t * -last_reply (session_test_t *test) -{ - ASSERT_CMPSIZE_T (test->replies.len, >, (size_t) 0); - return _mongoc_array_index (&test->replies, bson_t *, test->replies.len - 1); -} - - -static void -clear_history (session_test_t *test) -{ - size_t i; - - for (i = 0; i < test->cmds.len; i++) { - bson_destroy (_mongoc_array_index (&test->cmds, bson_t *, i)); - } - - for (i = 0; i < test->replies.len; i++) { - bson_destroy (_mongoc_array_index (&test->replies, bson_t *, i)); - } - - test->cmds.len = 0; - test->replies.len = 0; -} - - -static void -session_test_destroy (session_test_t *test) -{ - bson_t session_lsid; - size_t i; - - bson_copy_to (mongoc_client_session_get_lsid (test->cs), &session_lsid); - - mongoc_client_session_destroy (test->cs); - - check_session_returned (test, &session_lsid); - bson_destroy (&session_lsid); - - /* for implicit sessions, ensure the implicit session was returned */ - check_session_returned (test, &test->sent_lsid); - - if (test->client != test->session_client) { - mongoc_client_session_destroy (test->wrong_cs); - mongoc_collection_destroy (test->collection); - mongoc_database_destroy (test->db); - mongoc_client_destroy (test->client); - } - - mongoc_collection_destroy (test->session_collection); - mongoc_database_destroy (test->session_db); - mongoc_client_destroy (test->session_client); - bson_destroy (&test->opts); - bson_destroy (&test->sent_cluster_time); - bson_destroy (&test->received_cluster_time); - bson_destroy (&test->sent_lsid); - - for (i = 0; i < test->cmds.len; i++) { - bson_destroy (_mongoc_array_index (&test->cmds, bson_t *, i)); - } - - _mongoc_array_destroy (&test->cmds); - - for (i = 0; i < test->replies.len; i++) { - bson_destroy (_mongoc_array_index (&test->replies, bson_t *, i)); - } - - _mongoc_array_destroy (&test->replies); - - bson_free (test); -} - - -static void -check_sessions_from_same_client_enforced (session_test_t *test) -{ - if (test->session_client != test->client) { - BSON_ASSERT (!test->succeeded); - ASSERT_ERROR_CONTAINS (test->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid sessionId"); - } -} - - -static void -check_sessions_with_w0_prohibited (session_test_t *test) -{ - if (test->expect_explicit_lsid && !test->acknowledged) { - BSON_ASSERT (!test->succeeded); - ASSERT_ERROR_CONTAINS (test->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "session with unacknowledged"); - } -} - - -static void -check_success (session_test_t *test) -{ - check_sessions_from_same_client_enforced (test); - check_sessions_with_w0_prohibited (test); - - if (test->session_client == test->client && - test->expect_explicit_lsid == test->acknowledged) { - ASSERT_OR_PRINT (test->succeeded, test->error); - } - - if (test->succeeded) { - ASSERT_CMPINT (test->n_started, >, 0); - ASSERT_CMPINT (test->n_succeeded, >, 0); - } -} - - -static void -check_cluster_time (session_test_t *test) -{ - const bson_t *session_time; - - session_time = mongoc_client_session_get_cluster_time (test->cs); - BSON_ASSERT (session_time); /* should be set during handshake */ - - /* fail if cluster_time_greater logs an error */ - capture_logs (true); - if (_mongoc_cluster_time_greater (&test->received_cluster_time, - session_time)) { - fprintf (stderr, "client session's cluster time is outdated\n"); - abort (); - } - - ASSERT_NO_CAPTURED_LOGS ("_mongoc_cluster_time_greater"); - capture_logs (false); -} - - -typedef void (*session_test_fn_t) (session_test_t *); - - -/* - * the following tests check session logic for a variety of operations. most of - * the asserts are in the APM started/succeeded/failed callbacks above - */ - -/* use the same client for the session and the operation, expect success */ -static void -_test_explicit_session_lsid (session_test_fn_t test_fn) -{ - session_test_t *test; - bson_error_t error; - int64_t start; - - test = session_test_new (CORRECT_CLIENT, NOT_CAUSAL); - ASSERT_CMPINT64 (test->cs->server_session->last_used_usec, ==, (int64_t) -1); - ASSERT_OR_PRINT ( - mongoc_client_session_append (test->cs, &test->opts, &error), error); - - start = bson_get_monotonic_time (); - test_fn (test); - check_success (test); - ASSERT_CMPINT (test->n_started, >, 0); - ASSERT_CMPINT (test->n_succeeded, >, 0); - check_cluster_time (test); - ASSERT_CMPINT64 (test->cs->server_session->last_used_usec, >=, start); - session_test_destroy (test); -} - - -/* use a session from the wrong client, expect failure. this is the - * "session argument is for right client" test from Driver Sessions Spec */ -static void -_test_session_from_wrong_client (session_test_fn_t test_fn) -{ - session_test_t *test; - bson_error_t error; - - test = session_test_new (INCORRECT_CLIENT, NOT_CAUSAL); - ASSERT_OR_PRINT ( - mongoc_client_session_append (test->cs, &test->opts, &error), error); - - test_fn (test); - check_success (test); - mongoc_collection_drop_with_opts (test->session_collection, NULL, NULL); - session_test_destroy (test); -} - - -/* implicit session - all commands should use an internally-acquired lsid */ -static void -_test_implicit_session_lsid (session_test_fn_t test_fn) -{ - session_test_t *test; - int64_t start; - - test = session_test_new (CORRECT_CLIENT, NOT_CAUSAL); - test->expect_explicit_lsid = false; - start = bson_get_monotonic_time (); - test_fn (test); - check_success (test); - mongoc_collection_drop_with_opts (test->session_collection, NULL, NULL); - BSON_ASSERT (test->client->topology->session_pool); - ASSERT_CMPINT64 ( - test->client->topology->session_pool->last_used_usec, >=, start); - session_test_destroy (test); -} - - -typedef struct { - uint32_t t; - uint32_t i; -} op_time_t; - - -static void -parse_read_concern_time (const bson_t *cmd, op_time_t *op_time) -{ - bson_iter_t iter; - bson_iter_t rc; - - BSON_ASSERT (bson_iter_init_find (&iter, cmd, "readConcern")); - BSON_ASSERT (bson_iter_recurse (&iter, &rc)); - BSON_ASSERT (bson_iter_find (&rc, "afterClusterTime")); - BSON_ASSERT (BSON_ITER_HOLDS_TIMESTAMP (&rc)); - bson_iter_timestamp (&rc, &op_time->t, &op_time->i); -} - - -static void -parse_reply_time (const bson_t *reply, op_time_t *op_time) -{ - bson_iter_t iter; - - BSON_ASSERT (bson_iter_init_find (&iter, reply, "operationTime")); - BSON_ASSERT (BSON_ITER_HOLDS_TIMESTAMP (&iter)); - bson_iter_timestamp (&iter, &op_time->t, &op_time->i); -} - - -#define ASSERT_OP_TIMES_EQUAL(_a, _b) \ - if ((_a).t != (_b).t || (_a).i != (_b).i) { \ - fprintf (stderr, \ - #_a " (%d, %d) does not match " #_b " (%d, %d)\n", \ - (_a).t, \ - (_a).i, \ - (_b).t, \ - (_b).i); \ - abort (); \ - } - - -static void -_test_causal_consistency (session_test_fn_t test_fn, bool allow_read_concern) -{ - session_test_t *test; - op_time_t session_time, read_concern_time, reply_time; - bson_error_t error; - const bson_t *cmd; - size_t i; - - /* - * first causal exchange: don't send readConcern, receive opTime - */ - test = session_test_new (CORRECT_CLIENT, CAUSAL); - ASSERT_OR_PRINT ( - mongoc_client_session_append (test->cs, &test->opts, &error), error); - - test_fn (test); - check_success (test); - BSON_ASSERT (!bson_has_field (first_cmd (test), "readConcern")); - mongoc_client_session_get_operation_time ( - test->cs, &session_time.t, &session_time.i); - BSON_ASSERT (session_time.t != 0); - parse_reply_time (last_reply (test), &reply_time); - ASSERT_OP_TIMES_EQUAL (session_time, reply_time); - - /* - * second exchange: send previous opTime and receive an opTime. - * send readConcern if this function supports readConcern, like - * mongoc_collection_find_with_opts or mongoc_client_read_command_with_opts. - * don't send readConcern for generic command helpers like - * mongoc_client_command_with_opts or mongoc_client_command. - */ - clear_history (test); - test_fn (test); - check_success (test); - - if (allow_read_concern) { - parse_read_concern_time (first_cmd (test), &read_concern_time); - ASSERT_OP_TIMES_EQUAL (reply_time, read_concern_time); - mongoc_client_session_get_operation_time ( - test->cs, &session_time.t, &session_time.i); - BSON_ASSERT (session_time.t != 0); - parse_reply_time (last_reply (test), &reply_time); - ASSERT_OP_TIMES_EQUAL (session_time, reply_time); - } else { - /* readConcern prohibited */ - for (i = 0; i < test->cmds.len; i++) { - cmd = _mongoc_array_index (&test->cmds, bson_t *, i); - if (bson_has_field (cmd, "readConcern")) { - fprintf (stderr, - "Command should not have included readConcern: %s\n", - bson_as_json (cmd, NULL)); - abort (); - } - } - } - - session_test_destroy (test); -} - - -static void -_run_session_test (session_test_fn_t test_fn, bool allow_read_concern) -{ - _test_explicit_session_lsid (test_fn); - _test_session_from_wrong_client (test_fn); - _test_implicit_session_lsid (test_fn); - _test_causal_consistency (test_fn, allow_read_concern); -} - - -static void -run_session_test (void *ctx) -{ - _run_session_test ((session_test_fn_t) ctx, true); -} - - -/* test a command that doesn't allow readConcern, and therefore isn't causal */ -static void -run_session_test_no_rc (void *ctx) -{ - _run_session_test ((session_test_fn_t) ctx, false); -} - - -/* skip _test_session_from_wrong_client, which would abort with bulk op */ -static void -run_session_test_bulk_operation (void *ctx) -{ - _test_explicit_session_lsid ((session_test_fn_t) ctx); - _test_implicit_session_lsid ((session_test_fn_t) ctx); - _test_causal_consistency ((session_test_fn_t) ctx, false /* read concern */); -} - - -static void -insert_10_docs (session_test_t *test) -{ - mongoc_bulk_operation_t *bulk; - bson_error_t error; - int i; - bool r; - - /* disable callbacks, we're not testing insert's lsid */ - mongoc_client_set_apm_callbacks (test->session_client, NULL, NULL); - bulk = mongoc_collection_create_bulk_operation_with_opts ( - test->session_collection, NULL); - - for (i = 0; i < 10; i++) { - mongoc_bulk_operation_insert (bulk, tmp_bson ("{}")); - } - - r = (bool) mongoc_bulk_operation_execute (bulk, NULL, &error); - ASSERT_OR_PRINT (r, error); - - mongoc_bulk_operation_destroy (bulk); - - set_session_test_callbacks (test); -} - - -static void -test_cmd (session_test_t *test) -{ - test->succeeded = - mongoc_client_command_with_opts (test->client, - "db", - tmp_bson ("{'listCollections': 1}"), - NULL, - &test->opts, - NULL, - &test->error); -} - - -static void -test_read_cmd (session_test_t *test) -{ - test->succeeded = - mongoc_client_read_command_with_opts (test->client, - "db", - tmp_bson ("{'listCollections': 1}"), - NULL, - &test->opts, - NULL, - &test->error); -} - - -static void -test_write_cmd (session_test_t *test) -{ - bson_t *cmd = - tmp_bson ("{'delete': 'collection', 'deletes': [{'q': {}, 'limit': 1}]}"); - - test->succeeded = mongoc_client_write_command_with_opts ( - test->client, "db", cmd, &test->opts, NULL, &test->error); -} - - -static void -test_read_write_cmd (session_test_t *test) -{ - bson_t *cmd = tmp_bson ("{" - " 'aggregate': 'collection'," - " 'cursor': {}," - " 'pipeline': [{'$out': 'collection2'}]" - "}"); - - test->succeeded = mongoc_client_read_write_command_with_opts ( - test->client, "db", cmd, NULL, &test->opts, NULL, &test->error); -} - - -static void -test_db_cmd (session_test_t *test) -{ - test->succeeded = - mongoc_database_command_with_opts (test->db, - tmp_bson ("{'listCollections': 1}"), - NULL, - &test->opts, - NULL, - &test->error); -} - - -static void -test_count (session_test_t *test) -{ - test->succeeded = - (-1 != mongoc_collection_count_with_opts (test->collection, - MONGOC_QUERY_NONE, - NULL, - 0, - 0, - &test->opts, - NULL, - &test->error)); -} - - -static void -test_cursor (session_test_t *test) -{ - mongoc_cursor_t *cursor; - const bson_t *doc; - - /* ensure multiple batches */ - insert_10_docs (test); - - cursor = mongoc_collection_find_with_opts ( - test->collection, tmp_bson ("{}"), &test->opts, NULL); - - mongoc_cursor_set_batch_size (cursor, 2); - while (mongoc_cursor_next (cursor, &doc)) { - } - - test->succeeded = !mongoc_cursor_error (cursor, &test->error); - - mongoc_cursor_destroy (cursor); -} - - -static void -test_drop (session_test_t *test) -{ - /* create the collection so that "drop" can succeed */ - insert_10_docs (test); - - test->succeeded = mongoc_collection_drop_with_opts ( - test->collection, &test->opts, &test->error); -} - - -static void -test_drop_index (session_test_t *test) -{ - bson_error_t error; - bool r; - - /* create the index so that "dropIndexes" can succeed */ - r = mongoc_database_write_command_with_opts ( - test->session_db, - tmp_bson ("{'createIndexes': '%s'," - " 'indexes': [{'key': {'a': 1}, 'name': 'foo'}]}", - test->session_collection->collection), - &test->opts, - NULL, - &error); - - ASSERT_OR_PRINT (r, error); - - test->succeeded = mongoc_collection_drop_index_with_opts ( - test->collection, "foo", &test->opts, &test->error); -} - -static void -test_create_index (session_test_t *test) -{ - BEGIN_IGNORE_DEPRECATIONS - test->succeeded = - mongoc_collection_create_index_with_opts (test->collection, - tmp_bson ("{'a': 1}"), - NULL, - &test->opts, - NULL, - &test->error); - END_IGNORE_DEPRECATIONS -} - -static void -test_replace_one (session_test_t *test) -{ - test->succeeded = mongoc_collection_replace_one (test->collection, - tmp_bson ("{}"), - tmp_bson ("{}"), - &test->opts, - NULL, - &test->error); -} - -static void -test_update_one (session_test_t *test) -{ - test->succeeded = - mongoc_collection_update_one (test->collection, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'x': 1}}"), - &test->opts, - NULL, - &test->error); -} - -static void -test_update_many (session_test_t *test) -{ - test->succeeded = - mongoc_collection_update_many (test->collection, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'x': 1}}"), - &test->opts, - NULL, - &test->error); -} - -static void -test_insert_one (session_test_t *test) -{ - test->succeeded = mongoc_collection_insert_one ( - test->collection, tmp_bson ("{}"), &test->opts, NULL, &test->error); -} - -static void -test_insert_many (session_test_t *test) -{ - bson_t *docs[2] = {tmp_bson ("{}"), tmp_bson ("{}")}; - test->succeeded = mongoc_collection_insert_many (test->collection, - (const bson_t **) docs, - 2, - &test->opts, - NULL, - &test->error); -} - -static void -test_delete_one (session_test_t *test) -{ - test->succeeded = mongoc_collection_delete_one ( - test->collection, tmp_bson ("{}"), &test->opts, NULL, &test->error); -} - -static void -test_delete_many (session_test_t *test) -{ - test->succeeded = mongoc_collection_delete_many ( - test->collection, tmp_bson ("{}"), &test->opts, NULL, &test->error); -} - -static void -test_rename (session_test_t *test) -{ - mongoc_collection_t *collection; - - /* ensure "rename" can succeed */ - insert_10_docs (test); - - /* mongoc_collection_rename_with_opts mutates the struct! */ - collection = mongoc_collection_copy (test->collection); - test->succeeded = mongoc_collection_rename_with_opts ( - collection, "db", "newname", true, &test->opts, &test->error); - - mongoc_collection_destroy (collection); -} - -static void -test_fam (session_test_t *test) -{ - mongoc_find_and_modify_opts_t *fam_opts; - - fam_opts = mongoc_find_and_modify_opts_new (); - mongoc_find_and_modify_opts_set_update (fam_opts, - tmp_bson ("{'$set': {'x': 1}}")); - BSON_ASSERT (mongoc_find_and_modify_opts_append (fam_opts, &test->opts)); - test->succeeded = mongoc_collection_find_and_modify_with_opts ( - test->collection, tmp_bson ("{}"), fam_opts, NULL, &test->error); - - mongoc_find_and_modify_opts_destroy (fam_opts); -} - -static void -test_db_drop (session_test_t *test) -{ - test->succeeded = - mongoc_database_drop_with_opts (test->db, &test->opts, &test->error); -} - -static void -test_gridfs_find (session_test_t *test) -{ - mongoc_gridfs_t *gfs; - bson_error_t error; - mongoc_gridfs_file_list_t *list; - mongoc_gridfs_file_t *f; - - /* work around lack of mongoc_client_get_gridfs_with_opts for now, can't yet - * include lsid with the GridFS createIndexes command */ - mongoc_client_set_apm_callbacks (test->client, NULL, NULL); - gfs = mongoc_client_get_gridfs (test->client, "test", NULL, &error); - ASSERT_OR_PRINT (gfs, error); - set_session_test_callbacks (test); - list = mongoc_gridfs_find_with_opts (gfs, tmp_bson ("{}"), &test->opts); - f = mongoc_gridfs_file_list_next (list); - test->succeeded = !mongoc_gridfs_file_list_error (list, &test->error); - - if (f) { - mongoc_gridfs_file_destroy (f); - } - - mongoc_gridfs_file_list_destroy (list); - mongoc_gridfs_destroy (gfs); -} - -static void -test_gridfs_find_one (session_test_t *test) -{ - mongoc_gridfs_t *gfs; - bson_error_t error; - mongoc_gridfs_file_t *f; - - /* work around lack of mongoc_client_get_gridfs_with_opts for now, can't yet - * include lsid with the GridFS createIndexes command */ - mongoc_client_set_apm_callbacks (test->client, NULL, NULL); - gfs = mongoc_client_get_gridfs (test->client, "test", NULL, &error); - ASSERT_OR_PRINT (gfs, error); - set_session_test_callbacks (test); - f = mongoc_gridfs_find_one_with_opts ( - gfs, tmp_bson ("{}"), &test->opts, &test->error); - - test->succeeded = test->error.domain == 0; - - if (f) { - mongoc_gridfs_file_destroy (f); - } - - mongoc_gridfs_destroy (gfs); -} - - -static void -test_watch (session_test_t *test) -{ - mongoc_change_stream_t *change_stream; - - insert_10_docs (test); - change_stream = - mongoc_collection_watch (test->collection, tmp_bson ("{}"), &test->opts); - - test->succeeded = - !mongoc_change_stream_error_document (change_stream, &test->error, NULL); - mongoc_change_stream_destroy (change_stream); -} - - -static void -test_aggregate (session_test_t *test) -{ - bson_t opts; - mongoc_cursor_t *cursor; - const bson_t *doc; - - /* ensure multiple batches */ - insert_10_docs (test); - - bson_copy_to (&test->opts, &opts); - BSON_APPEND_INT32 (&opts, "batchSize", 2); - - cursor = mongoc_collection_aggregate ( - test->collection, MONGOC_QUERY_NONE, tmp_bson ("{}"), &opts, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - } - - test->succeeded = !mongoc_cursor_error (cursor, &test->error); - - mongoc_cursor_destroy (cursor); - bson_destroy (&opts); -} - - -static void -test_create (session_test_t *test) -{ - mongoc_collection_t *collection; - - /* ensure "create" can succeed */ - mongoc_database_write_command_with_opts (test->session_db, - tmp_bson ("{'drop': 'newname'}"), - &test->opts, - NULL, - NULL); - - collection = mongoc_database_create_collection ( - test->db, "newname", &test->opts, &test->error); - - test->succeeded = (collection != NULL); - - if (collection) { - mongoc_collection_destroy (collection); - } -} - - -static void -test_database_names (session_test_t *test) -{ - char **names; - - names = mongoc_client_get_database_names_with_opts ( - test->client, &test->opts, &test->error); - - test->succeeded = (names != NULL); - - if (names) { - bson_strfreev (names); - } -} - - -static void -test_find_databases (session_test_t *test) -{ - mongoc_cursor_t *cursor; - const bson_t *doc; - - cursor = mongoc_client_find_databases_with_opts (test->client, &test->opts); - - while (mongoc_cursor_next (cursor, &doc)) { - } - - test->succeeded = !mongoc_cursor_error (cursor, &test->error); - mongoc_cursor_destroy (cursor); -} - - -static void -test_find_collections (session_test_t *test) -{ - mongoc_cursor_t *cursor; - const bson_t *doc; - - cursor = mongoc_database_find_collections_with_opts (test->db, &test->opts); - - while (mongoc_cursor_next (cursor, &doc)) { - } - - test->succeeded = !mongoc_cursor_error (cursor, &test->error); - mongoc_cursor_destroy (cursor); -} - - -static void -test_collection_names (session_test_t *test) -{ - char **strv; - - strv = mongoc_database_get_collection_names_with_opts ( - test->db, &test->opts, &test->error); - test->succeeded = (strv != NULL); - bson_strfreev (strv); -} - - -static void -test_find_indexes (session_test_t *test) -{ - mongoc_cursor_t *cursor; - const bson_t *doc; - - /* ensure the collection exists so the listIndexes command succeeds */ - insert_10_docs (test); - - cursor = - mongoc_collection_find_indexes_with_opts (test->collection, &test->opts); - - while (mongoc_cursor_next (cursor, &doc)) { - } - - test->succeeded = !mongoc_cursor_error (cursor, &test->error); - mongoc_cursor_destroy (cursor); -} - - -static void -_test_bulk (session_test_t *test, mongoc_bulk_operation_t *bulk) -{ - uint32_t i; - - test->succeeded = mongoc_bulk_operation_insert_with_opts ( - bulk, tmp_bson ("{}"), NULL, &test->error); - - check_sessions_from_same_client_enforced (test); - - test->succeeded = mongoc_bulk_operation_update_one_with_opts ( - bulk, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'x': 1}}"), - NULL, - &test->error); - check_sessions_from_same_client_enforced (test); - - test->succeeded = mongoc_bulk_operation_remove_one_with_opts ( - bulk, tmp_bson ("{}"), NULL, &test->error); - check_sessions_from_same_client_enforced (test); - - i = mongoc_bulk_operation_execute (bulk, NULL, &test->error); - test->succeeded = (i != 0); - check_sessions_with_w0_prohibited (test); - - mongoc_bulk_operation_destroy (bulk); -} - - -/* test the standard mongoc_collection_create_bulk_operation_with_opts */ -static void -test_bulk (session_test_t *test) -{ - mongoc_bulk_operation_t *bulk; - - bulk = mongoc_collection_create_bulk_operation_with_opts (test->collection, - &test->opts); - - _test_bulk (test, bulk); -} - - -/* instead of the standard mongoc_collection_create_bulk_operation_with_opts, - * test a quirky way of setting the client session on an existing bulk */ -static void -test_bulk_set_session (session_test_t *test) -{ - mongoc_bulk_operation_t *bulk; - bson_iter_t iter; - mongoc_client_session_t *cs; - bson_error_t error; - bool r; - - bulk = mongoc_bulk_operation_new (true /* ordered */); - mongoc_bulk_operation_set_client (bulk, test->client); - mongoc_bulk_operation_set_database (bulk, - mongoc_database_get_name (test->db)); - - mongoc_bulk_operation_set_collection ( - bulk, mongoc_collection_get_name (test->collection)); - - if (bson_iter_init_find (&iter, &test->opts, "sessionId")) { - r = _mongoc_client_session_from_iter ( - test->session_client, &iter, &cs, &error); - - ASSERT_OR_PRINT (r, error); - mongoc_bulk_operation_set_client_session (bulk, cs); - } - - _test_bulk (test, bulk); -} - - -/* like test_bulk_set_session, but set session first, then client */ -static void -test_bulk_set_client (session_test_t *test) -{ - mongoc_bulk_operation_t *bulk; - bson_iter_t iter; - mongoc_client_session_t *cs; - bson_error_t error; - bool r; - - bulk = mongoc_bulk_operation_new (true /* ordered */); - - if (bson_iter_init_find (&iter, &test->opts, "sessionId")) { - r = _mongoc_client_session_from_iter ( - test->session_client, &iter, &cs, &error); - - ASSERT_OR_PRINT (r, error); - mongoc_bulk_operation_set_client_session (bulk, cs); - } - - mongoc_bulk_operation_set_client (bulk, test->client); - mongoc_bulk_operation_set_database (bulk, - mongoc_database_get_name (test->db)); - - mongoc_bulk_operation_set_collection ( - bulk, mongoc_collection_get_name (test->collection)); - - _test_bulk (test, bulk); -} - - -#define ASSERT_POOL_SIZE(_topology, _expected_size) \ - do { \ - const mongoc_server_session_t *_tmp; \ - int _n_sessions; \ - CDL_COUNT ((_topology)->session_pool, _tmp, _n_sessions); \ - ASSERT_CMPINT (_n_sessions, ==, (int) (_expected_size)); \ - } while (0) - - -static void -test_cursor_implicit_session (void *ctx) -{ - session_test_t *test; - mongoc_topology_t *topology; - mongoc_cursor_t *cursor; - const bson_t *doc; - mongoc_client_session_t *cs; - bson_t find_lsid; - bson_error_t error; - - test = session_test_new (CORRECT_CLIENT, NOT_CAUSAL); - test->expect_explicit_lsid = false; - topology = test->client->topology; - cs = mongoc_client_start_session (test->client, NULL, &error); - ASSERT_OR_PRINT (cs, error); - - mongoc_collection_drop_with_opts (test->session_collection, NULL, NULL); - insert_10_docs (test); - cursor = mongoc_collection_find_with_opts ( - test->collection, tmp_bson ("{}"), &test->opts, NULL); - - BSON_ASSERT (!cursor->client_session); - mongoc_cursor_set_batch_size (cursor, 2); - - /* start the cursor. it makes an implicit session & sends it with "find" */ - BSON_ASSERT (mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (cursor->client_session); - BSON_ASSERT (!cursor->explicit_session); - bson_copy_to (&cursor->client_session->server_session->lsid, &find_lsid); - ASSERT_POOL_SIZE (topology, 0); - ASSERT_SESSIONS_MATCH (&test->sent_lsid, &find_lsid); - - /* push a new server session into the pool */ - mongoc_client_session_destroy (cs); - ASSERT_POOL_SIZE (topology, 1); - ASSERT_SESSIONS_DIFFER (&find_lsid, &topology->session_pool->lsid); - - /* "getMore" uses the same lsid as "find" did */ - bson_reinit (&test->sent_lsid); - ASSERT_CURSOR_COUNT (9, cursor); - ASSERT_SESSIONS_MATCH (&test->sent_lsid, &find_lsid); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - /* lsid returned after last batch, doesn't wait for mongoc_cursor_destroy */ - check_session_returned (test, &find_lsid); - ASSERT_POOL_SIZE (topology, 2); - - bson_destroy (&find_lsid); - mongoc_cursor_destroy (cursor); - session_test_destroy (test); -} - - -static void -test_change_stream_implicit_session (void *ctx) -{ - session_test_t *test; - mongoc_topology_t *topology; - mongoc_client_session_t *cs; - bson_error_t error; - mongoc_change_stream_t *change_stream; - bson_t pipeline = BSON_INITIALIZER; - const bson_t *doc; - bson_t aggregate_lsid; - - test = session_test_new (CORRECT_CLIENT, NOT_CAUSAL); - test->expect_explicit_lsid = false; - topology = test->client->topology; - cs = mongoc_client_start_session (test->client, NULL, &error); - ASSERT_OR_PRINT (cs, error); - change_stream = - mongoc_collection_watch (test->session_collection, &pipeline, NULL); - bson_destroy (&pipeline); - bson_copy_to (&test->sent_lsid, &aggregate_lsid); - ASSERT_POOL_SIZE (topology, 0); - BSON_ASSERT (change_stream->implicit_session); - - /* push a new server session into the pool */ - mongoc_client_session_destroy (cs); - ASSERT_POOL_SIZE (topology, 1); - ASSERT_SESSIONS_DIFFER (&aggregate_lsid, &topology->session_pool->lsid); - - /* "getMore" uses the same lsid as "aggregate" did */ - bson_reinit (&test->sent_lsid); - mongoc_change_stream_next (change_stream, &doc); - ASSERT_SESSIONS_MATCH ( - &test->sent_lsid, &change_stream->implicit_session->server_session->lsid); - ASSERT_SESSIONS_MATCH ( - &test->sent_lsid, - &change_stream->cursor->client_session->server_session->lsid); - ASSERT_SESSIONS_MATCH (&test->sent_lsid, &aggregate_lsid); - ASSERT_OR_PRINT ( - !mongoc_change_stream_error_document (change_stream, &error, NULL), - error); - bson_destroy (&aggregate_lsid); - mongoc_change_stream_destroy (change_stream); - session_test_destroy (test); -} - - -static void -test_cmd_error (void *ctx) -{ - session_test_t *test; - bson_error_t error; - - test = session_test_new (CORRECT_CLIENT, CAUSAL); - - /* - * explicit session. command error still updates operation time - */ - test->expect_explicit_lsid = true; - ASSERT_OR_PRINT ( - mongoc_client_session_append (test->cs, &test->opts, &error), error); - - BSON_ASSERT (test->cs->operation_timestamp == 0); - BSON_ASSERT (!mongoc_client_command_with_opts (test->session_client, - "db", - tmp_bson ("{'bad': 1}"), - NULL, - &test->opts, - NULL, - NULL)); - - BSON_ASSERT (test->cs->operation_timestamp != 0); - - session_test_destroy (test); -} - - -static void -test_read_concern (void *ctx) -{ - session_test_t *test; - mongoc_read_concern_t *rc; - mongoc_session_opt_t *cs_opts; - bson_error_t error; - - test = session_test_new (CORRECT_CLIENT, CAUSAL); - test->expect_explicit_lsid = true; - ASSERT_OR_PRINT ( - mongoc_client_session_append (test->cs, &test->opts, &error), error); - - /* first exchange sets session's operationTime */ - test_read_cmd (test); - check_success (test); - BSON_ASSERT (!bson_has_field (last_non_getmore_cmd (test), "readConcern")); - - /* - * default: no explicit read concern, driver sends afterClusterTime - */ - test_read_cmd (test); - check_success (test); - ASSERT_MATCH (last_non_getmore_cmd (test), - "{" - " 'readConcern': {" - " 'level': {'$exists': false}," - " 'afterClusterTime': {'$exists': true}" - " }" - "}"); - - /* - * explicit read concern - */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_LOCAL); - BSON_ASSERT (mongoc_read_concern_append (rc, &test->opts)); - test_read_cmd (test); - check_success (test); - ASSERT_MATCH (last_non_getmore_cmd (test), - "{" - " 'readConcern': {" - " 'level': 'local'," - " 'afterClusterTime': {'$exists': true}" - " }" - "}"); - - /* - * explicit read concern, not causal - */ - cs_opts = mongoc_session_opts_new (); - mongoc_session_opts_set_causal_consistency (cs_opts, false); - mongoc_client_session_destroy (test->cs); - test->cs = mongoc_client_start_session (test->client, cs_opts, &error); - ASSERT_OR_PRINT (test->cs, error); - bson_reinit (&test->opts); - ASSERT_OR_PRINT ( - mongoc_client_session_append (test->cs, &test->opts, &error), error); - BSON_ASSERT (mongoc_read_concern_append (rc, &test->opts)); - /* set new session's operationTime */ - test_read_cmd (test); - check_success (test); - ASSERT_CMPUINT32 (test->cs->operation_timestamp, >, (uint32_t) 0); - /* afterClusterTime is not sent */ - test_read_cmd (test); - check_success (test); - ASSERT_MATCH (last_non_getmore_cmd (test), - "{" - " 'readConcern': {" - " 'level': 'local'," - " 'afterClusterTime': {'$exists': false}" - " }" - "}"); - - /* - * no read concern, not causal - */ - bson_reinit (&test->opts); - ASSERT_OR_PRINT ( - mongoc_client_session_append (test->cs, &test->opts, &error), error); - /* afterClusterTime is not sent */ - test_read_cmd (test); - check_success (test); - ASSERT_MATCH (last_non_getmore_cmd (test), - "{'readConcern': {'$exists': false}}"); - - mongoc_session_opts_destroy (cs_opts); - mongoc_read_concern_destroy (rc); - session_test_destroy (test); -} - - -static void -_test_unacknowledged (session_test_fn_t test_fn, - bool explicit_cs, - bool inherit_wc) -{ - session_test_t *test; - mongoc_write_concern_t *wc; - bson_error_t error; - - /* The following tests assert that unacknowledged command does not set the - * operationTime. Additionally, the "started" APM callback asserts that the - * command does not include an lsid. */ - test = session_test_new (CORRECT_CLIENT, CAUSAL); - test->expect_explicit_lsid = explicit_cs; - test->acknowledged = false; - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - - if (explicit_cs) { - ASSERT_OR_PRINT ( - mongoc_client_session_append (test->cs, &test->opts, &error), error); - } - - if (inherit_wc) { - mongoc_client_set_write_concern (test->client, wc); - mongoc_database_set_write_concern (test->db, wc); - mongoc_collection_set_write_concern (test->collection, wc); - } else { - BSON_ASSERT (mongoc_write_concern_append_bad (wc, &test->opts)); - } - - test_fn (test); - check_success (test); - - if (test->succeeded) { - ASSERT_MATCH (last_non_getmore_cmd (test), "{'writeConcern': {'w': 0}}"); - ASSERT_CMPUINT32 (test->cs->operation_timestamp, ==, (uint32_t) 0); - } - - mongoc_write_concern_destroy (wc); - session_test_destroy (test); -} - - -static void -test_unacknowledged_explicit_cs_inherit_wc (void *ctx) -{ - _test_unacknowledged ((session_test_fn_t) ctx, true, true); -} - - -static void -test_unacknowledged_implicit_cs_explicit_wc (void *ctx) -{ - _test_unacknowledged ((session_test_fn_t) ctx, true, false); -} - - -static void -test_unacknowledged_implicit_cs_inherit_wc (void *ctx) -{ - _test_unacknowledged ((session_test_fn_t) ctx, false, true); -} - - -static void -test_unacknowledged_explicit_cs_explicit_wc (void *ctx) -{ - _test_unacknowledged ((session_test_fn_t) ctx, false, false); -} - - -#define add_session_test(_suite, _name, _test_fn, _allow_read_concern) \ - TestSuite_AddFull (_suite, \ - _name, \ - (_allow_read_concern) ? run_session_test \ - : run_session_test_no_rc, \ - NULL, \ - (void *) (_test_fn), \ - test_framework_skip_if_no_cluster_time, \ - test_framework_skip_if_no_crypto) - -#define add_session_test_wc(_suite, _name, _test_fn, _allow_read_concern, ...) \ - TestSuite_AddFull (_suite, \ - _name, \ - (_allow_read_concern) ? run_session_test \ - : run_session_test_no_rc, \ - NULL, \ - (void *) (_test_fn), \ - test_framework_skip_if_no_cluster_time, \ - test_framework_skip_if_no_crypto, \ - __VA_ARGS__) - -#define add_unacknowledged_test( \ - _suite, _name, _test_fn, _explicit_cs, _inherit_wc) \ - TestSuite_AddFull ( \ - _suite, \ - _name, \ - (_explicit_cs) \ - ? (_inherit_wc ? test_unacknowledged_explicit_cs_inherit_wc \ - : test_unacknowledged_implicit_cs_explicit_wc) \ - : (_inherit_wc ? test_unacknowledged_implicit_cs_inherit_wc \ - : test_unacknowledged_explicit_cs_explicit_wc), \ - NULL, \ - (void *) (_test_fn), \ - test_framework_skip_if_no_cluster_time, \ - test_framework_skip_if_no_crypto) - - -void -test_session_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Session/opts/clone", test_session_opts_clone); - TestSuite_AddFull (suite, - "/Session/no_crypto", - test_session_no_crypto, - NULL, - NULL, - TestSuite_CheckLive, - test_framework_skip_if_no_sessions, - test_framework_skip_if_crypto); - TestSuite_AddFull (suite, - "/Session/lifo/single", - 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", - 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", - test_session_pool_timeout_single, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Session/timeout/pooled", - test_session_pool_timeout_pooled, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Session/reap/single", - test_session_pool_reap_single, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Session/reap/pooled", - test_session_pool_reap_pooled, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Session/id_bad", - test_session_id_bad, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto); - TestSuite_AddFull (suite, - "/Session/supported/single", - test_session_supported_single, - NULL, - NULL, - TestSuite_CheckLive, - test_framework_skip_if_no_crypto); - TestSuite_AddFull (suite, - "/Session/supported/pooled", - test_session_supported_pooled, - NULL, - NULL, - TestSuite_CheckLive, - test_framework_skip_if_no_crypto); - TestSuite_AddMockServerTest (suite, - "/Session/end/mock/single", - test_mock_end_sessions_single, - test_framework_skip_if_no_crypto); - TestSuite_AddMockServerTest (suite, - "/Session/end/mock/pooled", - test_mock_end_sessions_pooled, - test_framework_skip_if_no_crypto); - TestSuite_AddFull (suite, - "/Session/end/single", - test_end_sessions_single, - NULL, - NULL, - test_framework_skip_if_no_crypto, - test_framework_skip_if_max_wire_version_less_than_6); - TestSuite_AddFull (suite, - "/Session/end/pooled", - test_end_sessions_pooled, - NULL, - NULL, - test_framework_skip_if_no_crypto, - test_framework_skip_if_max_wire_version_less_than_6); - TestSuite_AddFull (suite, - "/Session/end/many/single", - test_end_sessions_many_single, - NULL, - NULL, - test_framework_skip_if_no_crypto, - test_framework_skip_if_max_wire_version_less_than_6); - TestSuite_AddFull (suite, - "/Session/end/many/pooled", - test_end_sessions_many_pooled, - NULL, - NULL, - test_framework_skip_if_no_crypto, - test_framework_skip_if_max_wire_version_less_than_6); - TestSuite_AddFull (suite, - "/Session/advance_cluster_time", - 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", - test_session_advance_operation_time, - NULL, - NULL, - test_framework_skip_if_no_crypto, - test_framework_skip_if_no_sessions); - - /* "true" is for tests that expect readConcern: afterClusterTime for causally - * consistent sessions, "false" is for tests that prohibit readConcern */ - add_session_test (suite, "/Session/cmd", test_cmd, false); - add_session_test (suite, "/Session/read_cmd", test_read_cmd, true); - add_session_test (suite, "/Session/write_cmd", test_write_cmd, false); - add_session_test ( - suite, "/Session/read_write_cmd", test_read_write_cmd, true); - add_session_test (suite, "/Session/db_cmd", test_db_cmd, false); - add_session_test (suite, "/Session/count", test_count, true); - add_session_test (suite, "/Session/cursor", test_cursor, true); - add_session_test (suite, "/Session/drop", test_drop, false); - add_session_test (suite, "/Session/drop_index", test_drop_index, false); - add_session_test (suite, "/Session/create_index", test_create_index, false); - add_session_test (suite, "/Session/replace_one", test_replace_one, false); - add_session_test (suite, "/Session/update_one", test_update_one, false); - add_session_test (suite, "/Session/update_many", test_update_many, false); - add_session_test (suite, "/Session/insert_one", test_insert_one, false); - add_session_test (suite, "/Session/insert_many", test_insert_many, false); - add_session_test (suite, "/Session/delete_one", test_delete_one, false); - add_session_test (suite, "/Session/delete_many", test_delete_many, false); - add_session_test (suite, "/Session/rename", test_rename, false); - add_session_test (suite, "/Session/fam", test_fam, true); - add_session_test (suite, "/Session/db_drop", test_db_drop, false); - add_session_test (suite, "/Session/gridfs_find", test_gridfs_find, true); - add_session_test ( - suite, "/Session/gridfs_find_one", test_gridfs_find_one, true); - add_session_test_wc (suite, - "/Session/watch", - test_watch, - true, - test_framework_skip_if_not_rs_version_6); - add_session_test (suite, "/Session/aggregate", test_aggregate, true); - add_session_test (suite, "/Session/create", test_create, false); - add_session_test ( - suite, "/Session/database_names", test_database_names, true); - add_session_test ( - suite, "/Session/find_databases", test_find_databases, true); - add_session_test ( - suite, "/Session/find_collections", test_find_collections, true); - add_session_test ( - suite, "/Session/collection_names", test_collection_names, true); - add_session_test (suite, "/Session/bulk", test_bulk, false); - add_session_test (suite, "/Session/find_indexes", test_find_indexes, true); - TestSuite_AddFull (suite, - "/Session/bulk_set_session", - run_session_test_bulk_operation, - NULL, - test_bulk_set_session, - test_framework_skip_if_no_cluster_time, - test_framework_skip_if_no_crypto); - TestSuite_AddFull (suite, - "/Session/bulk_set_client", - run_session_test_bulk_operation, - NULL, - test_bulk_set_client, - test_framework_skip_if_no_cluster_time, - test_framework_skip_if_no_crypto); - TestSuite_AddFull (suite, - "/Session/cursor_implicit_session", - 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", - 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", - test_cmd_error, - NULL, - NULL, - test_framework_skip_if_no_cluster_time, - test_framework_skip_if_no_crypto); - TestSuite_AddFull (suite, - "/Session/read_concern", - test_read_concern, - NULL, - NULL, - test_framework_skip_if_no_cluster_time, - test_framework_skip_if_no_crypto); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/insert_one/explicit_cs/inherit_wc", - test_insert_one, - true, - true); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/insert_one/explicit_cs/explicit_wc", - test_insert_one, - true, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/insert_one/implicit_cs/inherit_wc", - test_insert_one, - false, - true); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/insert_one/implicit_cs/explicit_wc", - test_insert_one, - false, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/bulk/explicit_cs/inherit_wc", - test_bulk, - true, - true); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/bulk/explicit_cs/explicit_wc", - test_bulk, - true, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/bulk/implicit_cs/inherit_wc", - test_bulk, - false, - true); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/bulk/implicit_cs/explicit_wc", - test_bulk, - false, - false); - /* find_and_modify_with_opts only inherits acknowledged write concerns, so - * skip tests that inherit a write concern. Technically, an explicit - * unacknowledged write concern doesn't make much sense with findAndModify, - * but this is testing the common code path for command execution. */ - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/find_and_modify/explicit_cs/explicit_wc", - test_fam, - true, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/find_and_modify/implicit_cs/explicit_wc", - test_fam, - false, - false); - /* command_with_opts also does not inherit write concerns, but we still want - * to test the common code path for command execution. */ - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/db_cmd/explicit_cs/explicit_wc", - test_db_cmd, - true, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/db_cmd/implicit_cs/explicit_wc", - test_db_cmd, - false, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/read_write_cmd/explicit_cs/inherit_wc", - test_read_write_cmd, - true, - true); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/read_write_cmd/explicit_cs/explicit_wc", - test_read_write_cmd, - true, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/read_write_cmd/implicit_cs/inherit_wc", - test_read_write_cmd, - false, - true); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/read_write_cmd/implicit_cs/explicit_wc", - test_read_write_cmd, - false, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/write_cmd/explicit_cs/inherit_wc", - test_write_cmd, - true, - true); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/write_cmd/explicit_cs/explicit_wc", - test_write_cmd, - true, - false); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/write_cmd/implicit_cs/inherit_wc", - test_write_cmd, - false, - true); - add_unacknowledged_test ( - suite, - "/Session/unacknowledged/write_cmd/implicit_cs/explicit_wc", - test_write_cmd, - false, - false); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-client-side-encryption.c b/lib/mongoc/libmongoc/tests/test-mongoc-client-side-encryption.c deleted file mode 100644 index 1bd0a711cd3a9141efe05e213009a6d6d41034ba..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-client-side-encryption.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2019-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 "json-test.h" -#include "test-libmongoc.h" - -static void -_before_test (json_test_ctx_t *ctx, const bson_t *test) -{ - mongoc_client_t *client; - mongoc_collection_t *key_vault_coll; - bson_iter_t iter; - bson_error_t error; - bool ret; - mongoc_write_concern_t *wc; - bson_t insert_opts; - - /* Insert data into the key vault. */ - client = test_framework_client_new (); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_wmajority (wc, 1000); - bson_init (&insert_opts); - mongoc_write_concern_append (wc, &insert_opts); - - if (bson_iter_init_find (&iter, ctx->config->scenario, "key_vault_data")) { - key_vault_coll = - mongoc_client_get_collection (client, "admin", "datakeys"); - - /* Drop and recreate, inserting data. */ - ret = mongoc_collection_drop (key_vault_coll, &error); - if (!ret) { - /* Ignore "namespace does not exist" error. */ - ASSERT_OR_PRINT (error.code == 26, error); - } - - bson_iter_recurse (&iter, &iter); - while (bson_iter_next (&iter)) { - bson_t doc; - - bson_iter_bson (&iter, &doc); - ret = mongoc_collection_insert_one ( - key_vault_coll, &doc, &insert_opts, NULL /* reply */, &error); - ASSERT_OR_PRINT (ret, error); - } - mongoc_collection_destroy (key_vault_coll); - } - - /* Collmod to include the json schema. Data was already inserted. */ - if (bson_iter_init_find (&iter, ctx->config->scenario, "json_schema")) { - bson_t *cmd; - bson_t json_schema; - - bson_iter_bson (&iter, &json_schema); - cmd = BCON_NEW ("collMod", - BCON_UTF8 (mongoc_collection_get_name (ctx->collection)), - "validator", - "{", - "$jsonSchema", - BCON_DOCUMENT (&json_schema), - "}"); - ret = mongoc_client_command_simple ( - client, mongoc_database_get_name (ctx->db), cmd, NULL, NULL, &error); - ASSERT_OR_PRINT (ret, error); - bson_destroy (cmd); - } - - bson_destroy (&insert_opts); - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); -} - -static bool -_run_operation (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation) -{ - bson_t reply; - bool res; - - res = - json_test_operation (ctx, test, operation, ctx->collection, NULL, &reply); - - bson_destroy (&reply); - - return res; -} - -static void -test_client_side_encryption_cb (bson_t *scenario) -{ - json_test_config_t config = JSON_TEST_CONFIG_INIT; - config.before_test_cb = _before_test; - config.run_operation_cb = _run_operation; - config.scenario = scenario; - config.command_started_events_only = true; - config.command_monitoring_allow_subset = false; - run_json_general_test (&config); -} - -void -test_client_side_encryption_install (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - ASSERT (realpath (JSON_DIR "/client_side_encryption", resolved)); - install_json_test_suite_with_check ( - suite, - resolved, - test_client_side_encryption_cb, - test_framework_skip_if_no_client_side_encryption); -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-client.c b/lib/mongoc/libmongoc/tests/test-mongoc-client.c deleted file mode 100644 index f822a7bd6889ce2df655758c931753f855fe7b85..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-client.c +++ /dev/null @@ -1,3948 +0,0 @@ -#include <fcntl.h> -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-cluster-private.h" -#include "mongoc/mongoc-database-private.h" -#include "mongoc/mongoc-handshake-private.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-set-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-concern-private.h" - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" -#include "mock_server/mock-rs.h" - - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "client-test" - - -static void -test_client_cmd_w_server_id (void) -{ - mock_rs_t *rs; - mongoc_client_t *client; - bson_error_t error; - bson_t *opts; - bson_t reply; - future_t *future; - request_t *request; - - rs = mock_rs_with_autoismaster (WIRE_VERSION_READ_CONCERN, - true /* has primary */, - 1 /* secondary */, - 0 /* arbiters */); - - mock_rs_run (rs); - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - - /* use serverId instead of prefs to select the secondary */ - opts = tmp_bson ("{'serverId': 2, 'readConcern': {'level': 'local'}}"); - future = future_client_read_command_with_opts (client, - "db", - tmp_bson ("{'ping': 1}"), - NULL /* prefs */, - opts, - &reply, - &error); - - /* recognized that wire version is recent enough for readConcern */ - request = mock_rs_receives_command (rs, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'ping': 1," - " 'readConcern': {'level': 'local'}," - " 'serverId': {'$exists': false}}"); - - ASSERT (mock_rs_request_is_to_secondary (rs, request)); - mock_rs_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - - bson_destroy (&reply); - future_destroy (future); - request_destroy (request); - mongoc_client_destroy (client); - mock_rs_destroy (rs); -} - - -static void -test_client_cmd_w_server_id_sharded (void) -{ - mock_server_t *server; - mongoc_client_t *client; - bson_error_t error; - bson_t *opts; - bson_t reply; - future_t *future; - request_t *request; - - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - opts = tmp_bson ("{'serverId': 1}"); - future = future_client_read_command_with_opts (client, - "db", - tmp_bson ("{'ping': 1}"), - NULL /* prefs */, - opts, - &reply, - &error); - - /* does NOT set slave ok, since this is a sharded topology */ - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_NONE, - "{'ping': 1, 'serverId': {'$exists': false}}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - - bson_destroy (&reply); - future_destroy (future); - request_destroy (request); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_server_id_option (void *ctx) -{ - mongoc_client_t *client; - bson_error_t error; - bson_t *cmd; - bool r; - - client = test_framework_client_new (); - cmd = tmp_bson ("{'ping': 1}"); - r = mongoc_client_read_command_with_opts (client, - "test", - cmd, - NULL /* prefs */, - tmp_bson ("{'serverId': 'foo'}"), - NULL, - &error); - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "must be an integer"); - - r = mongoc_client_read_command_with_opts (client, - "test", - cmd, - NULL /* prefs */, - tmp_bson ("{'serverId': 0}"), - NULL, - &error); - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "must be >= 1"); - - r = mongoc_client_read_command_with_opts (client, - "test", - cmd, - NULL /* prefs */, - tmp_bson ("{'serverId': 1}"), - NULL, - &error); - - ASSERT_OR_PRINT (r, error); - - mongoc_client_destroy (client); -} - - -static void -test_client_cmd_w_write_concern (void *ctx) -{ - mongoc_write_concern_t *good_wc; - mongoc_write_concern_t *bad_wc; - mongoc_client_t *client; - bson_t *command = tmp_bson ("{'insert' : 'test', " - "'documents' : [{'hello' : 'world'}]}"); - bson_t reply; - bson_t *opts = NULL; - bson_error_t error; - - opts = bson_new (); - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - - good_wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (good_wc, 1); - - bad_wc = mongoc_write_concern_new (); - /* writeConcern that will not pass mongoc_write_concern_is_valid */ - bad_wc->wtimeout = -10; - - mongoc_write_concern_append (good_wc, opts); - ASSERT_OR_PRINT (mongoc_client_write_command_with_opts ( - client, "test", command, opts, &reply, &error), - error); - - bson_reinit (opts); - bson_destroy (&reply); - - mongoc_write_concern_append_bad (bad_wc, opts); - ASSERT (!mongoc_client_write_command_with_opts ( - client, "test", command, opts, &reply, &error)); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - bad_wc->wtimeout = 0; - bson_destroy (&reply); - error.code = 0; - error.domain = 0; - - if (!test_framework_is_mongos ()) { - mongoc_write_concern_set_w (bad_wc, 99); - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - - /* bad write concern in opts */ - ASSERT (!mongoc_client_write_command_with_opts ( - client, "test", command, opts, &reply, &error)); - if (test_framework_is_replset ()) { /* replset */ - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:"); - } else { /* standalone */ - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CMPINT (error.code, ==, 2); - } - bson_destroy (&reply); - } - - mongoc_write_concern_destroy (good_wc); - mongoc_write_concern_destroy (bad_wc); - bson_destroy (opts); - mongoc_client_destroy (client); -} - - -/* - * test_client_cmd_write_concern: - * - * This test ensures that there is a lack of special - * handling for write concerns and write concern - * errors in generic functions that support commands - * that write. - * - */ - -static void -test_client_cmd_write_concern (void) -{ - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - mock_server_t *server; - char *cmd; - - /* set up client and wire protocol version */ - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - /* command with invalid writeConcern */ - cmd = "{'foo' : 1, " - "'writeConcern' : {'w' : 99 }}"; - future = future_client_command_simple ( - client, "test", tmp_bson (cmd), NULL, &reply, &error); - request = - mock_server_receives_command (server, "test", MONGOC_QUERY_SLAVE_OK, cmd); - BSON_ASSERT (request); - - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - - future_destroy (future); - bson_destroy (&reply); - - /* standalone response */ - future = future_client_command_simple ( - client, "test", tmp_bson (cmd), NULL, &reply, &error); - request = - mock_server_receives_command (server, "test", MONGOC_QUERY_SLAVE_OK, cmd); - BSON_ASSERT (request); - - mock_server_replies_simple ( - request, - "{ 'ok' : 0, 'errmsg' : 'cannot use w > 1 when a " - "host is not replicated', 'code' : 2 }"); - - BSON_ASSERT (!future_get_bool (future)); - future_destroy (future); - request_destroy (request); - bson_destroy (&reply); - - /* replicaset response */ - future = future_client_command_simple ( - client, "test", tmp_bson (cmd), NULL, &reply, &error); - request = - mock_server_receives_command (server, "test", MONGOC_QUERY_SLAVE_OK, cmd); - mock_server_replies_simple ( - request, - "{ 'ok' : 1, 'n': 1, " - "'writeConcernError': {'code': 17, 'errmsg': 'foo'}}"); - BSON_ASSERT (future_get_bool (future)); - - bson_destroy (&reply); - future_destroy (future); - mock_server_destroy (server); - mongoc_client_destroy (client); - request_destroy (request); -} - - -static void -test_client_cmd_write_concern_fam (void) -{ - mongoc_client_t *client; - mongoc_write_concern_t *wc; - bson_t *fam; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - mock_server_t *server; - - server = mock_server_with_autoismaster (WIRE_VERSION_FAM_WRITE_CONCERN - 1); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_client_set_write_concern (client, wc); - fam = tmp_bson ("{'findAndModify': 'collection'}"); - - future = future_client_read_write_command_with_opts ( - client, "test", fam, NULL, NULL, &reply, &error); - - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_NONE, - "{'findAndModify': 'collection', 'writeConcern': {'$exists': false}}"); - - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - future_destroy (future); - mock_server_destroy (server); - mongoc_client_destroy (client); - bson_destroy (&reply); - - server = mock_server_with_autoismaster (WIRE_VERSION_FAM_WRITE_CONCERN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - mongoc_client_set_write_concern (client, wc); - - future = future_client_read_write_command_with_opts ( - client, "test", fam, NULL, NULL, &reply, &error); - - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_NONE, - "{'findAndModify': 'collection', 'writeConcern': {'w': 2}}"); - - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - - bson_destroy (&reply); - future_destroy (future); - mock_server_destroy (server); - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); -} - - -static char * -gen_test_user (void) -{ - return bson_strdup_printf ( - "testuser_%u_%u", (unsigned) time (NULL), (unsigned) gettestpid ()); -} - - -static char * -gen_good_uri (const char *username, const char *dbname) -{ - char *host = test_framework_get_host (); - uint16_t port = test_framework_get_port (); - char *uri = bson_strdup_printf ( - "mongodb://%s:testpass@%s:%hu/%s", username, host, port, dbname); - - bson_free (host); - return uri; -} - - -static void -test_mongoc_client_authenticate (void *context) -{ - mongoc_client_t *admin_client; - char *username; - char *uri; - bson_t roles; - mongoc_database_t *database; - char *uri_str_no_auth; - char *uri_str_auth; - mongoc_collection_t *collection; - mongoc_client_t *auth_client; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - bool r; - bson_t q; - - /* - * Log in as admin. - */ - admin_client = test_framework_client_new (); - - /* - * Add a user to the test database. - */ - username = gen_test_user (); - uri = gen_good_uri (username, "test"); - - database = mongoc_client_get_database (admin_client, "test"); - (void) mongoc_database_remove_user (database, username, &error); - bson_init (&roles); - BCON_APPEND (&roles, "0", "{", "role", "read", "db", "test", "}"); - - r = mongoc_database_add_user (database, - username, - "testpass", - tmp_bson ("[{'role': 'read', 'db': 'test'}]"), - NULL, - &error); - - ASSERT_OR_PRINT (r, error); - mongoc_database_destroy (database); - - /* - * Try authenticating with that user. - */ - bson_init (&q); - uri_str_no_auth = test_framework_get_uri_str_no_auth ("test"); - uri_str_auth = - test_framework_add_user_password (uri_str_no_auth, username, "testpass"); - auth_client = mongoc_client_new (uri_str_auth); - test_framework_set_ssl_opts (auth_client); - collection = mongoc_client_get_collection (auth_client, "test", "test"); - cursor = mongoc_collection_find_with_opts (collection, &q, NULL, NULL); - r = mongoc_cursor_next (cursor, &doc); - if (!r) { - r = mongoc_cursor_error (cursor, &error); - if (r) { - fprintf (stderr, "Authentication failure: \"%s\"", error.message); - } - BSON_ASSERT (!r); - } - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (auth_client); - - /* - * Remove all test users. - */ - database = mongoc_client_get_database (admin_client, "test"); - r = mongoc_database_remove_all_users (database, &error); - BSON_ASSERT (r); - - bson_destroy (&q); - bson_free (uri_str_no_auth); - bson_free (uri_str_auth); - bson_destroy (&roles); - bson_free (uri); - bson_free (username); - mongoc_database_destroy (database); - mongoc_client_destroy (admin_client); -} - - -static void -test_mongoc_client_authenticate_cached (bool pooled) -{ - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_t insert = BSON_INITIALIZER; - const bson_t *doc; - bson_error_t error; - bool r; - int i = 0; - uint32_t server_id; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - collection = mongoc_client_get_collection (client, "test", "test"); - mongoc_collection_insert_one (collection, &insert, NULL, NULL, &error); - for (i = 0; i < 10; i++) { - mongoc_topology_scanner_node_t *scanner_node; - - cursor = - mongoc_collection_find_with_opts (collection, &insert, NULL, NULL); - r = mongoc_cursor_next (cursor, &doc); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - ASSERT (r); - server_id = mongoc_cursor_get_hint (cursor); - mongoc_cursor_destroy (cursor); - - if (pooled) { - mongoc_cluster_disconnect_node ( - &client->cluster, server_id, false /* invalidate */, NULL); - } else { - scanner_node = mongoc_topology_scanner_get_node ( - client->topology->scanner, server_id); - mongoc_stream_destroy (scanner_node->stream); - scanner_node->stream = NULL; - } - } - - /* screw up the cache */ - memcpy (client->cluster.scram_cache->client_key, "foo", 3); - cursor = mongoc_collection_find_with_opts (collection, &insert, NULL, NULL); - capture_logs (true); - r = mongoc_cursor_next (cursor, &doc); - - if (pooled) { - ASSERT_CAPTURED_LOG ("The cachekey broke", - MONGOC_LOG_LEVEL_WARNING, - "Failed authentication"); - } - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, ""); - ASSERT (!r); - mongoc_cursor_destroy (cursor); - - mongoc_collection_destroy (collection); - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - bson_destroy (&insert); -} - - -static void -test_mongoc_client_authenticate_cached_pooled (void *context) -{ - test_mongoc_client_authenticate_cached (true); -} - - -static void -test_mongoc_client_authenticate_cached_single (void *context) -{ - test_mongoc_client_authenticate_cached (false); -} - - -static void -test_mongoc_client_authenticate_failure (void *context) -{ - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - mongoc_client_t *client; - const bson_t *doc; - bson_error_t error; - bool r; - bson_t q; - bson_t empty = BSON_INITIALIZER; - char *host = test_framework_get_host (); - char *uri_str_no_auth = test_framework_get_uri_str_no_auth (NULL); - char *bad_uri_str = - test_framework_add_user_password (uri_str_no_auth, "baduser", "badpass"); - - capture_logs (true); - - /* - * Try authenticating with bad user. - */ - bson_init (&q); - client = mongoc_client_new (bad_uri_str); - test_framework_set_ssl_opts (client); - - collection = mongoc_client_get_collection (client, "test", "test"); - cursor = mongoc_collection_find_with_opts (collection, &q, NULL, NULL); - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (!r); - r = mongoc_cursor_error (cursor, &error); - BSON_ASSERT (r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_CLIENT); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_CLIENT_AUTHENTICATE); - mongoc_cursor_destroy (cursor); - - /* - * Try various commands while in the failed state to ensure we get the - * same sort of errors. - */ - r = mongoc_collection_insert_one (collection, &empty, NULL, NULL, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_CLIENT); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_CLIENT_AUTHENTICATE); - - /* - * Try various commands while in the failed state to ensure we get the - * same sort of errors. - */ - r = mongoc_collection_update ( - collection, MONGOC_UPDATE_NONE, &q, &empty, NULL, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_CLIENT); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_CLIENT_AUTHENTICATE); - - bson_destroy (&q); - bson_destroy (&empty); - bson_free (host); - bson_free (uri_str_no_auth); - bson_free (bad_uri_str); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_mongoc_client_authenticate_timeout (void *context) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_username (uri, "user"); - mongoc_uri_set_password (uri, "password"); - mongoc_uri_set_option_as_int32 (uri, "socketTimeoutMS", 10); - client = mongoc_client_new_from_uri (uri); - - future = future_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, &reply, &error); - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, NULL); - - ASSERT (request); - ASSERT_CMPSTR (request->command_name, "saslStart"); - - /* don't reply */ - BSON_ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_CLIENT, - MONGOC_ERROR_CLIENT_AUTHENTICATE, - "Failed to send \"saslStart\" command with database \"admin\":" - " socket error or timeout"); - - bson_destroy (&reply); - future_destroy (future); - request_destroy (request); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_wire_version (void) -{ - mongoc_uri_t *uri; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - mongoc_client_t *client; - mock_server_t *server; - const bson_t *doc; - bson_error_t error; - bson_t q = BSON_INITIALIZER; - future_t *future; - request_t *request; - - if (!test_framework_skip_if_slow ()) { - bson_destroy (&q); - return; - } - - server = mock_server_new (); - - /* too new */ - mock_server_auto_ismaster (server, - "{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 10," - " 'maxWireVersion': 11}"); - - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500); - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "test", "test"); - - cursor = mongoc_collection_find_with_opts (collection, &q, NULL, NULL); - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); - BSON_ASSERT (error.domain == MONGOC_ERROR_PROTOCOL); - BSON_ASSERT (error.code == MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION); - mongoc_cursor_destroy (cursor); - - /* too old */ - mock_server_auto_ismaster (server, - "{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': -1," - " 'maxWireVersion': -1}"); - - /* wait until it's time for next heartbeat */ - _mongoc_usleep (600 * 1000); - - cursor = mongoc_collection_find_with_opts (collection, &q, NULL, NULL); - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); - BSON_ASSERT (error.domain == MONGOC_ERROR_PROTOCOL); - BSON_ASSERT (error.code == MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION); - mongoc_cursor_destroy (cursor); - - /* compatible again */ - mock_server_auto_ismaster (server, - "{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 2," - " 'maxWireVersion': 5}"); - - /* wait until it's time for next heartbeat */ - _mongoc_usleep (600 * 1000); - cursor = mongoc_collection_find_with_opts (collection, &q, NULL, NULL); - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_request (server); - mock_server_replies_to_find ( - request, MONGOC_QUERY_SLAVE_OK, 0, 0, "test.test", "{}", true); - - /* no error */ - BSON_ASSERT (future_get_bool (future)); - BSON_ASSERT (!mongoc_cursor_error (cursor, &error)); - - bson_destroy (&q); - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -static void -test_mongoc_client_command (void) -{ - mongoc_client_t *client; - mongoc_cursor_t *cursor; - const bson_t *doc; - bool r; - bson_t cmd = BSON_INITIALIZER; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - bson_append_int32 (&cmd, "ping", 4, 1); - - cursor = mongoc_client_command ( - client, "admin", MONGOC_QUERY_NONE, 0, 1, 0, &cmd, NULL, NULL); - - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (r); - BSON_ASSERT (doc); - - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (!r); - BSON_ASSERT (!doc); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); - bson_destroy (&cmd); -} - - -static void -test_mongoc_client_command_defaults (void) -{ - mongoc_client_t *client; - mongoc_read_prefs_t *read_prefs; - mongoc_read_concern_t *read_concern; - mongoc_cursor_t *cursor; - - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, "majority"); - - client = test_framework_client_new (); - mongoc_client_set_read_prefs (client, read_prefs); - mongoc_client_set_read_concern (client, read_concern); - - cursor = mongoc_client_command (client, - "admin", - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{'ping': 1}"), - NULL, - NULL); - - /* Read and Write Concern spec: "If your driver offers a generic RunCommand - * method on your database object, ReadConcern MUST NOT be applied - * automatically to any command. A user wishing to use a ReadConcern in a - * generic command must supply it manually." Server Selection Spec: "The - * generic command method MUST ignore any default read preference from - * client, database or collection configuration. The generic command method - * SHOULD allow an optional read preference argument." - */ - ASSERT (cursor->read_concern->level == NULL); - ASSERT (cursor->read_prefs->mode == MONGOC_READ_PRIMARY); - - mongoc_cursor_destroy (cursor); - mongoc_read_concern_destroy (read_concern); - mongoc_read_prefs_destroy (read_prefs); - mongoc_client_destroy (client); -} - - -static void -test_mongoc_client_command_secondary (void) -{ - mongoc_client_t *client; - mongoc_cursor_t *cursor; - mongoc_read_prefs_t *read_prefs; - bson_t cmd = BSON_INITIALIZER; - const bson_t *reply; - - capture_logs (true); - - client = test_framework_client_new (); - BSON_ASSERT (client); - - BSON_APPEND_INT32 (&cmd, "invalid_command_here", 1); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - cursor = mongoc_client_command ( - client, "admin", MONGOC_QUERY_NONE, 0, 1, 0, &cmd, NULL, read_prefs); - mongoc_cursor_next (cursor, &reply); - - if (test_framework_is_replset ()) { - BSON_ASSERT (test_framework_server_is_secondary ( - client, mongoc_cursor_get_hint (cursor))); - } - - mongoc_read_prefs_destroy (read_prefs); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); - bson_destroy (&cmd); -} - - -static void -_test_command_read_prefs (bool simple, bool pooled) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_read_prefs_t *secondary_pref; - bson_t *cmd; - future_t *future; - bson_error_t error; - request_t *request; - mongoc_cursor_t *cursor; - const bson_t *reply; - - /* mock mongos: easiest way to test that read preference is configured */ - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - secondary_pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_uri_set_read_prefs_t (uri, secondary_pref); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - } - - ASSERT_CMPINT ( - MONGOC_READ_SECONDARY, - ==, - mongoc_read_prefs_get_mode (mongoc_client_get_read_prefs (client))); - - cmd = tmp_bson ("{'foo': 1}"); - - if (simple) { - /* simple, without read preference */ - future = - future_client_command_simple (client, "db", cmd, NULL, NULL, &error); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, "{'foo': 1}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - request_destroy (request); - - /* with read preference */ - future = future_client_command_simple ( - client, "db", cmd, secondary_pref, NULL, &error); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'foo': 1}," - " '$readPreference': {'mode': 'secondary'}}"); - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - request_destroy (request); - } else { - /* not simple, no read preference */ - cursor = mongoc_client_command ( - client, "db", MONGOC_QUERY_NONE, 0, 0, 0, cmd, NULL, NULL); - future = future_cursor_next (cursor, &reply); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, "{'foo': 1}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - - /* with read preference */ - cursor = mongoc_client_command ( - client, "db", MONGOC_QUERY_NONE, 0, 0, 0, cmd, NULL, secondary_pref); - future = future_cursor_next (cursor, &reply); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'foo': 1}," - " '$readPreference': {'mode': 'secondary'}}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - } - - mongoc_uri_destroy (uri); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_read_prefs_destroy (secondary_pref); - mock_server_destroy (server); -} - - -static void -test_command_simple_read_prefs_single (void) -{ - _test_command_read_prefs (true, false); -} - - -static void -test_command_simple_read_prefs_pooled (void) -{ - _test_command_read_prefs (true, true); -} - - -static void -test_command_read_prefs_single (void) -{ - _test_command_read_prefs (false, false); -} - - -static void -test_command_read_prefs_pooled (void) -{ - _test_command_read_prefs (false, true); -} - - -static void -test_command_not_found (void) -{ - mongoc_client_t *client; - const bson_t *doc; - bson_error_t error; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - cursor = mongoc_client_command (client, - "test", - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{'foo': 1}"), - NULL, - NULL); - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_QUERY); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); -} - - -static void -test_command_not_found_simple (void) -{ - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - - client = test_framework_client_new (); - ASSERT (!mongoc_client_command_simple ( - client, "test", tmp_bson ("{'foo': 1}"), NULL, &reply, &error)); - - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_QUERY); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND); - - bson_destroy (&reply); - mongoc_client_destroy (client); -} - - -static void -test_command_with_opts_read_prefs (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_read_prefs_t *read_prefs; - bson_t *cmd; - bson_t *opts; - bson_error_t error; - future_t *future; - request_t *request; - - server = mock_mongos_new (WIRE_VERSION_READ_CONCERN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_client_set_read_prefs (client, read_prefs); - - /* read prefs omitted for command that writes */ - cmd = tmp_bson ("{'create': 'db'}"); - future = future_client_write_command_with_opts ( - client, "admin", cmd, NULL /* opts */, NULL, &error); - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_NONE, "{'create': 'db'}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* read prefs are included for read command */ - cmd = tmp_bson ("{'count': 'collection'}"); - future = future_client_read_command_with_opts ( - client, "admin", cmd, NULL, NULL /* opts */, NULL, &error); - - /* Server Selection Spec: "For mode 'secondary', drivers MUST set the slaveOK - * wire protocol flag and MUST also use $readPreference". - */ - request = mock_server_receives_command ( - server, - "admin", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'count': 'collection'}," - " '$readPreference': {'mode': 'secondary'}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* read prefs not included for read/write command, but read concern is */ - cmd = tmp_bson ("{'whatever': 1}"); - opts = tmp_bson ("{'readConcern': {'level': 'majority'}}"); - future = future_client_read_write_command_with_opts ( - client, "admin", cmd, NULL, opts, NULL, &error); - - request = - mock_server_receives_command (server, - "admin", - MONGOC_QUERY_NONE, - "{'whatever': 1," - " 'readConcern': {'level': 'majority'}," - " '$readPreference': {'$exists': false}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - mongoc_read_prefs_destroy (read_prefs); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_read_write_cmd_with_opts (void) -{ - mock_rs_t *rs; - mongoc_client_t *client; - mongoc_read_prefs_t *secondary; - bson_error_t error; - bson_t reply; - future_t *future; - request_t *request; - - rs = mock_rs_with_autoismaster (WIRE_VERSION_MIN, - true /* has primary */, - 1 /* secondary */, - 0 /* arbiters */); - - mock_rs_run (rs); - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - secondary = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - /* mongoc_client_read_write_command_with_opts must ignore read prefs - * CDRIVER-2224 - */ - future = future_client_read_write_command_with_opts ( - client, "db", tmp_bson ("{'ping': 1}"), secondary, NULL, &reply, &error); - - request = - mock_rs_receives_command (rs, "db", MONGOC_QUERY_NONE, "{'ping': 1}"); - - ASSERT (mock_rs_request_is_to_primary (rs, request)); - mock_rs_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - - bson_destroy (&reply); - future_destroy (future); - request_destroy (request); - mongoc_read_prefs_destroy (secondary); - mongoc_client_destroy (client); - mock_rs_destroy (rs); -} - - -static void -test_command_with_opts_legacy (void) -{ - mock_server_t *server; - mongoc_client_t *client; - bson_t *opts; - bson_t *cmd; - mongoc_write_concern_t *wc; - mongoc_read_concern_t *read_concern; - bson_error_t error; - future_t *future; - request_t *request; - - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_client_set_write_concern (client, wc); - - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, "local"); - mongoc_client_set_read_concern (client, read_concern); - - /* writeConcern is omitted */ - cmd = tmp_bson ("{'create': 'db'}"); - future = future_client_write_command_with_opts ( - client, "admin", cmd, NULL, NULL, &error); - - request = mock_server_receives_command ( - server, - "admin", - MONGOC_QUERY_NONE, - "{'create': 'db', 'writeConcern': {'$exists': false}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* readConcern causes error */ - cmd = tmp_bson ("{'count': 'collection'}"); - ASSERT (!mongoc_client_read_command_with_opts ( - client, "db", cmd, NULL, NULL, NULL, &error)); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "does not support readConcern"); - - mongoc_client_set_read_concern (client, NULL); - - /* collation causes error */ - cmd = tmp_bson ("{'create': 'db'}"); - opts = tmp_bson ("{'collation': {'locale': 'en_US'}}"); - ASSERT (!mongoc_client_read_command_with_opts ( - client, "db", cmd, NULL, opts, NULL, &error)); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "does not support collation"); - - mongoc_read_concern_destroy (read_concern); - mongoc_client_destroy (client); - mongoc_write_concern_destroy (wc); - mock_server_destroy (server); -} - - -static void -test_read_command_with_opts (void) -{ - mock_server_t *server; - mongoc_client_t *client; - bson_t *cmd; - bson_t *opts; - mongoc_write_concern_t *wc; - mongoc_read_concern_t *read_concern; - bson_error_t error; - future_t *future; - request_t *request; - - server = mock_mongos_new (5); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - /* collation allowed */ - cmd = tmp_bson ("{'create': 'db'}"); - opts = tmp_bson ("{'collation': {'locale': 'en_US'}}"); - future = future_client_write_command_with_opts ( - client, "admin", cmd, opts, NULL, &error); - - request = mock_server_receives_command ( - server, - "admin", - MONGOC_QUERY_NONE, - "{'create': 'db', 'collation': {'locale': 'en_US'}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* writeConcern included */ - cmd = tmp_bson ("{'create': 'db'}"); - opts = tmp_bson ("{'writeConcern': {'w': 1}}"); - future = future_client_write_command_with_opts ( - client, "admin", cmd, opts, NULL, &error); - - request = mock_server_receives_command ( - server, - "admin", - MONGOC_QUERY_NONE, - "{'create': 'db', 'writeConcern': {'w': 1}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* apply client's write concern by default */ - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 1); - mongoc_client_set_write_concern (client, wc); - future = future_client_write_command_with_opts ( - client, "admin", cmd, NULL /* opts */, NULL, &error); - - request = mock_server_receives_command ( - server, - "admin", - MONGOC_QUERY_NONE, - "{'create': 'db', 'writeConcern': {'w': 1}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* apply write concern from opts, not client */ - opts = tmp_bson ("{'writeConcern': {'w': 2}}"); - mongoc_write_concern_destroy (wc); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 4); - mongoc_client_set_write_concern (client, wc); - future = future_client_write_command_with_opts ( - client, "admin", cmd, opts, NULL, &error); - - request = mock_server_receives_command ( - server, - "admin", - MONGOC_QUERY_NONE, - "{'create': 'db', 'writeConcern': {'w': 2}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* readConcern allowed */ - cmd = tmp_bson ("{'count': 'collection'}"); - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, "local"); - opts = tmp_bson (NULL); - mongoc_read_concern_append (read_concern, opts); - future = future_client_read_command_with_opts ( - client, "admin", cmd, NULL, opts, NULL, &error); - - request = mock_server_receives_command ( - server, - "admin", - MONGOC_QUERY_NONE, - "{'count': 'collection', 'readConcern': {'level': 'local'}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* apply client's readConcern by default */ - mongoc_client_set_read_concern (client, read_concern); - future = future_client_read_command_with_opts ( - client, "admin", cmd, NULL, NULL /* opts */, NULL, &error); - - request = mock_server_receives_command ( - server, - "admin", - MONGOC_QUERY_NONE, - "{'count': 'collection', 'readConcern': {'level': 'local'}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - mongoc_read_concern_destroy (read_concern); - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_command_with_opts (void) -{ - mock_server_t *server; - mongoc_client_t *client; - bson_t *cmd; - mongoc_write_concern_t *wc; - mongoc_read_concern_t *read_concern; - mongoc_read_prefs_t *prefs; - bson_error_t error; - future_t *future; - request_t *request; - bson_t opts = BSON_INITIALIZER; - - server = mock_mongos_new (5); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - /* client's write concern, read concern, read prefs are ignored */ - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_client_set_write_concern (client, wc); - - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, "majority"); - mongoc_client_set_read_concern (client, read_concern); - - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_client_set_read_prefs (client, prefs); - - cmd = tmp_bson ("{'create': 'db'}"); - future = future_client_command_with_opts ( - client, "admin", cmd, NULL, NULL, NULL, &error); - - request = - mock_server_receives_command (server, - "admin", - MONGOC_QUERY_NONE, - "{" - " 'create': 'db'," - " 'readConcern': {'$exists': false}," - " 'writeConcern': {'$exists': false}" - "}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* write concern, read concern, and read preference passed in explicitly */ - mongoc_write_concern_append (wc, &opts); - mongoc_read_concern_append (read_concern, &opts); - future = future_client_command_with_opts ( - client, "admin", cmd, prefs, &opts, NULL, &error); - - request = - mock_server_receives_command (server, - "admin", - MONGOC_QUERY_SLAVE_OK, - "{" - " '$query': {" - " 'create':'db'," - " 'writeConcern': {'w': 2}," - " 'readConcern': {'level':'majority'}" - " }," - " '$readPreference': {" - " 'mode':'secondary'" - " }" - "}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - bson_destroy (&opts); - mongoc_read_prefs_destroy (prefs); - mongoc_read_concern_destroy (read_concern); - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_command_with_opts_op_msg (void) -{ - mock_server_t *server; - mongoc_client_t *client; - bson_t *cmd; - mongoc_write_concern_t *wc; - mongoc_read_concern_t *read_concern; - mongoc_read_prefs_t *prefs; - bson_error_t error; - future_t *future; - request_t *request; - bson_t opts = BSON_INITIALIZER; - - server = mock_mongos_new (WIRE_VERSION_OP_MSG); - - mock_server_auto_endsessions (server); - - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - /* client's write concern, read concern, read prefs are ignored */ - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_client_set_write_concern (client, wc); - - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, "majority"); - mongoc_client_set_read_concern (client, read_concern); - - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_client_set_read_prefs (client, prefs); - - cmd = tmp_bson ("{'create': 'db'}"); - future = future_client_command_with_opts ( - client, "admin", cmd, NULL, NULL, NULL, &error); - - request = mock_server_receives_msg ( - server, - 0, - tmp_bson ("{" - " 'create': 'db'," - " 'readConcern': {'$exists': false}," - " 'writeConcern': {'$exists': false}" - "}")); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* write concern, read concern, and read preference passed in explicitly */ - mongoc_write_concern_append (wc, &opts); - mongoc_read_concern_append (read_concern, &opts); - future = future_client_command_with_opts ( - client, "admin", cmd, prefs, &opts, NULL, &error); - - request = mock_server_receives_msg ( - server, - 0, - tmp_bson ("{" - " 'create':'db'," - " 'writeConcern': {'w': 2}," - " 'readConcern': {'level':'majority'}," - " '$readPreference': {" - " 'mode':'secondary'" - " }" - "}")); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - bson_destroy (&opts); - mongoc_read_prefs_destroy (prefs); - mongoc_read_concern_destroy (read_concern); - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_command_empty (void) -{ - mongoc_client_t *client; - mongoc_write_concern_t *wc; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{}"), NULL, NULL, &error); - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Empty command document"); - - r = mongoc_client_command_with_opts ( - client, "admin", tmp_bson ("{}"), NULL, tmp_bson ("{}"), NULL, &error); - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Empty command document"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 1); - mongoc_client_set_write_concern (client, wc); - - r = mongoc_client_write_command_with_opts ( - client, "admin", tmp_bson ("{}"), NULL, NULL, &error); - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Empty command document"); - - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); -} - - -static void -test_command_no_errmsg (void) -{ - mock_server_t *server; - mongoc_client_t *client; - bson_t *cmd; - bson_error_t error; - future_t *future; - request_t *request; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - mongoc_client_set_error_api (client, 2); - - cmd = tmp_bson ("{'command': 1}"); - future = - future_client_command_simple (client, "admin", cmd, NULL, NULL, &error); - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, NULL); - - /* auth errors have $err, not errmsg. we'd raised "Unknown command error", - * see CDRIVER-1928 */ - mock_server_replies_simple (request, "{'ok': 0, 'code': 7, '$err': 'bad!'}"); - ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 7, "bad!"); - - future_destroy (future); - request_destroy (request); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_unavailable_seeds (void) -{ - mock_server_t *servers[2]; - char **uri_strs; - char **uri_str; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_t query = BSON_INITIALIZER; - const bson_t *doc; - bson_error_t error; - - int i; - - for (i = 0; i < 2; i++) { - servers[i] = mock_server_down (); /* hangs up on all requests */ - mock_server_run (servers[i]); - } - - uri_str = uri_strs = bson_malloc0 (7 * sizeof (char *)); - *(uri_str++) = bson_strdup_printf ( - "mongodb://%s", mock_server_get_host_and_port (servers[0])); - - *(uri_str++) = - bson_strdup_printf ("mongodb://%s,%s", - mock_server_get_host_and_port (servers[0]), - mock_server_get_host_and_port (servers[1])); - - *(uri_str++) = - bson_strdup_printf ("mongodb://%s,%s/?replicaSet=rs", - mock_server_get_host_and_port (servers[0]), - mock_server_get_host_and_port (servers[1])); - - *(uri_str++) = bson_strdup_printf ( - "mongodb://u:p@%s", mock_server_get_host_and_port (servers[0])); - - *(uri_str++) = - bson_strdup_printf ("mongodb://u:p@%s,%s", - mock_server_get_host_and_port (servers[0]), - mock_server_get_host_and_port (servers[1])); - - *(uri_str++) = - bson_strdup_printf ("mongodb://u:p@%s,%s/?replicaSet=rs", - mock_server_get_host_and_port (servers[0]), - mock_server_get_host_and_port (servers[1])); - - for (i = 0; i < (sizeof (uri_strs) / sizeof (const char *)); i++) { - client = mongoc_client_new (uri_strs[i]); - BSON_ASSERT (client); - - collection = mongoc_client_get_collection (client, "test", "test"); - cursor = - mongoc_collection_find_with_opts (collection, &query, NULL, NULL); - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER_SELECTION); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_SERVER_SELECTION_FAILURE); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - } - - for (i = 0; i < 2; i++) { - mock_server_destroy (servers[i]); - } - - bson_strfreev (uri_strs); - bson_destroy (&query); -} - - -typedef enum { NO_CONNECT, CONNECT, RECONNECT } connection_option_t; - - -static bool -responder (request_t *request, void *data) -{ - if (!strcmp (request->command_name, "foo")) { - mock_server_replies_simple (request, "{'ok': 1}"); - request_destroy (request); - return true; - } - - return false; -} - - -/* mongoc_set_for_each callback */ -static bool -host_equals (void *item, void *ctx) -{ - mongoc_server_description_t *sd; - const char *host_and_port; - - sd = (mongoc_server_description_t *) item; - host_and_port = (const char *) ctx; - - return !strcasecmp (sd->host.host_and_port, host_and_port); -} - - -/* CDRIVER-721 catch errors in _mongoc_cluster_destroy */ -static void -test_seed_list (bool rs, connection_option_t connection_option, bool pooled) -{ - mock_server_t *server; - mock_server_t *down_servers[3]; - int i; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_topology_t *topology; - mongoc_topology_description_t *td; - mongoc_read_prefs_t *primary_pref; - uint32_t discovered_nodes_len; - bson_t reply; - bson_error_t error; - uint32_t id; - - server = mock_server_new (); - mock_server_run (server); - - for (i = 0; i < 3; i++) { - down_servers[i] = mock_server_down (); - mock_server_run (down_servers[i]); - } - - uri_str = - bson_strdup_printf ("mongodb://%s,%s,%s,%s", - mock_server_get_host_and_port (server), - mock_server_get_host_and_port (down_servers[0]), - mock_server_get_host_and_port (down_servers[1]), - mock_server_get_host_and_port (down_servers[2])); - - uri = mongoc_uri_new (uri_str); - BSON_ASSERT (uri); - - if (pooled) { - /* must be >= minHeartbeatFrequencyMS=500 or the "reconnect" - * case won't have time to succeed */ - mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 1000); - } - - if (rs) { - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'ismaster': true," - " 'setName': 'rs'," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - } else { - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'ismaster': true," - " 'msg': 'isdbgrid'}"); - } - - /* auto-respond to "foo" command */ - mock_server_autoresponds (server, responder, NULL, NULL); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - } - - topology = client->topology; - td = &topology->description; - - /* a mongos load-balanced connection never removes down nodes */ - discovered_nodes_len = rs ? 1 : 4; - - primary_pref = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - if (connection_option == CONNECT || connection_option == RECONNECT) { - /* only localhost:port responds to initial discovery. the other seeds are - * discarded from replica set topology, but remain for sharded. */ - ASSERT_OR_PRINT (mongoc_client_command_simple (client, - "test", - tmp_bson ("{'foo': 1}"), - primary_pref, - &reply, - &error), - error); - - bson_destroy (&reply); - - ASSERT_CMPINT (discovered_nodes_len, ==, (int) td->servers->items_len); - - if (rs) { - ASSERT_CMPINT (td->type, ==, MONGOC_TOPOLOGY_RS_WITH_PRIMARY); - } else { - ASSERT_CMPINT (td->type, ==, MONGOC_TOPOLOGY_SHARDED); - } - - if (pooled) { - /* nodes created on demand when we use servers for actual operations */ - ASSERT_CMPINT ((int) client->cluster.nodes->items_len, ==, 1); - } - } - - if (connection_option == RECONNECT) { - id = mongoc_set_find_id (td->servers, - host_equals, - (void *) mock_server_get_host_and_port (server)); - ASSERT_CMPINT (id, !=, 0); - bson_set_error ( - &error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "err"); - mongoc_topology_invalidate_server (topology, id, &error); - if (rs) { - ASSERT_CMPINT (td->type, ==, MONGOC_TOPOLOGY_RS_NO_PRIMARY); - } else { - ASSERT_CMPINT (td->type, ==, MONGOC_TOPOLOGY_SHARDED); - } - - ASSERT_OR_PRINT (mongoc_client_command_simple (client, - "test", - tmp_bson ("{'foo': 1}"), - primary_pref, - &reply, - &error), - error); - - bson_destroy (&reply); - - ASSERT_CMPINT (discovered_nodes_len, ==, (int) td->servers->items_len); - - if (pooled) { - ASSERT_CMPINT ((int) client->cluster.nodes->items_len, ==, 1); - } - } - - /* testing for crashes like CDRIVER-721 */ - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_read_prefs_destroy (primary_pref); - mongoc_uri_destroy (uri); - bson_free (uri_str); - - for (i = 0; i < 3; i++) { - mock_server_destroy (down_servers[i]); - } - - mock_server_destroy (server); -} - - -static void -test_rs_seeds_no_connect_single (void) -{ - test_seed_list (true, NO_CONNECT, false); -} - - -static void -test_rs_seeds_no_connect_pooled (void) -{ - test_seed_list (true, NO_CONNECT, true); -} - - -static void -test_rs_seeds_connect_single (void) -{ - test_seed_list (true, CONNECT, false); -} - -static void -test_rs_seeds_connect_pooled (void) -{ - test_seed_list (true, CONNECT, true); -} - - -static void -test_rs_seeds_reconnect_single (void) -{ - test_seed_list (true, RECONNECT, false); -} - - -static void -test_rs_seeds_reconnect_pooled (void) -{ - test_seed_list (true, RECONNECT, true); -} - - -static void -test_mongos_seeds_no_connect_single (void) -{ - test_seed_list (false, NO_CONNECT, false); -} - - -static void -test_mongos_seeds_no_connect_pooled (void) -{ - test_seed_list (false, NO_CONNECT, true); -} - - -static void -test_mongos_seeds_connect_single (void) -{ - test_seed_list (false, CONNECT, false); -} - - -static void -test_mongos_seeds_connect_pooled (void) -{ - test_seed_list (false, CONNECT, true); -} - - -static void -test_mongos_seeds_reconnect_single (void) -{ - test_seed_list (false, RECONNECT, false); -} - - -static void -test_mongos_seeds_reconnect_pooled (void) -{ - test_seed_list (false, RECONNECT, true); -} - - -static void -test_recovering (void *ctx) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_read_mode_t read_mode; - mongoc_read_prefs_t *prefs; - bson_error_t error; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - server = mock_server_new (); - mock_server_run (server); - - /* server is "recovering": not master, not secondary */ - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'ismaster': false," - " 'secondary': false," - " 'setName': 'rs'," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - client = mongoc_client_new_from_uri (uri); - prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - /* recovering member matches no read mode */ - for (read_mode = MONGOC_READ_PRIMARY; read_mode <= MONGOC_READ_NEAREST; - read_mode++) { - mongoc_read_prefs_set_mode (prefs, read_mode); - BSON_ASSERT (!mongoc_topology_select ( - client->topology, MONGOC_SS_READ, prefs, &error)); - } - - mongoc_read_prefs_destroy (prefs); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -static void -test_server_status (void) -{ - mongoc_client_t *client; - bson_error_t error; - bson_iter_t iter; - bson_t reply; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - BEGIN_IGNORE_DEPRECATIONS - ASSERT_OR_PRINT ( - mongoc_client_get_server_status (client, NULL, &reply, &error), error); - END_IGNORE_DEPRECATIONS - - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "host")); - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "version")); - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "ok")); - - bson_destroy (&reply); - - mongoc_client_destroy (client); -} - - -static void -test_get_database_names (void) -{ - mock_server_t *server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mongoc_client_t *client; - bson_error_t error; - future_t *future; - request_t *request; - char **names; - - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - future = future_client_get_database_names_with_opts (client, NULL, &error); - request = - mock_server_receives_command (server, - "admin", - MONGOC_QUERY_SLAVE_OK, - "{'listDatabases': 1, 'nameOnly': true}"); - mock_server_replies ( - request, - 0, - 0, - 0, - 1, - "{'ok': 1.0, 'databases': [{'name': 'a'}, {'name': 'local'}]}"); - names = future_get_char_ptr_ptr (future); - BSON_ASSERT (!strcmp (names[0], "a")); - BSON_ASSERT (!strcmp (names[1], "local")); - BSON_ASSERT (NULL == names[2]); - - bson_strfreev (names); - request_destroy (request); - future_destroy (future); - - future = future_client_get_database_names_with_opts (client, NULL, &error); - request = - mock_server_receives_command (server, - "admin", - MONGOC_QUERY_SLAVE_OK, - "{'listDatabases': 1, 'nameOnly': true}"); - mock_server_replies ( - request, 0, 0, 0, 1, "{'ok': 0.0, 'code': 17, 'errmsg': 'err'}"); - - names = future_get_char_ptr_ptr (future); - BSON_ASSERT (!names); - ASSERT_CMPINT (MONGOC_ERROR_QUERY, ==, error.domain); - ASSERT_CMPSTR ("err", error.message); - - request_destroy (request); - future_destroy (future); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -_test_mongoc_client_ipv6 (bool pooled) -{ - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - - uri_str = test_framework_add_user_password_from_env ("mongodb://[::1]/"); - uri = mongoc_uri_new (uri_str); - BSON_ASSERT (uri); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - test_framework_set_pool_ssl_opts (pool); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - } - - ASSERT_OR_PRINT ( - mongoc_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, &error), - error); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); - bson_free (uri_str); -} - - -static void -test_mongoc_client_ipv6_single (void) -{ - _test_mongoc_client_ipv6 (false); -} - - -static void -test_mongoc_client_ipv6_pooled (void) -{ - _test_mongoc_client_ipv6 (true); -} - - -static void -test_mongoc_client_unix_domain_socket (void *context) -{ - mongoc_client_t *client; - bson_error_t error; - char *uri_str; - - uri_str = test_framework_get_unix_domain_socket_uri_str (); - client = mongoc_client_new (uri_str); - test_framework_set_ssl_opts (client); - - BSON_ASSERT (client); - - ASSERT_OR_PRINT ( - mongoc_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, &error), - error); - - mongoc_client_destroy (client); - bson_free (uri_str); -} - - -static void -test_mongoc_client_mismatched_me (void) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_read_prefs_t *prefs; - bson_error_t error; - future_t *future; - request_t *request; - char *reply; - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - client = mongoc_client_new_from_uri (uri); - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - /* any operation should fail with server selection error */ - future = future_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), prefs, NULL, &error); - - request = mock_server_receives_ismaster (server); - reply = bson_strdup_printf ("{'ok': 1," - " 'setName': 'rs'," - " 'ismaster': false," - " 'secondary': true," - " 'minWireVersion': 2, 'maxWireVersion': 5," - " 'me': 'foo.com'," /* mismatched "me" field */ - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - capture_logs (true); - mock_server_replies_simple (request, reply); - - BSON_ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "No suitable servers"); - ASSERT_CAPTURED_LOG ( - "client", MONGOC_LOG_LEVEL_WARNING, "Last server removed from topology"); - capture_logs (false); - - bson_free (reply); - request_destroy (request); - future_destroy (future); - mongoc_read_prefs_destroy (prefs); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -#ifdef MONGOC_ENABLE_SSL -static void -_test_mongoc_client_ssl_opts (bool pooled) -{ - char *host_and_port; - char *uri_str; - char *uri_str_auth; - char *uri_str_auth_ssl; - mongoc_uri_t *uri; - const mongoc_ssl_opt_t *ssl_opts; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bool ret; - bson_error_t error; - int add_ssl_to_uri; - - host_and_port = test_framework_get_host_and_port (); - uri_str = bson_strdup_printf ( - "mongodb://%s/?serverSelectionTimeoutMS=1000&connectTimeoutMS=1000", - host_and_port); - - uri_str_auth = test_framework_add_user_password_from_env (uri_str); - uri_str_auth_ssl = bson_strdup_printf ("%s&ssl=true", uri_str_auth); - - ssl_opts = test_framework_get_ssl_opts (); - - /* client uses SSL once SSL options are set, regardless of "ssl=true" */ - for (add_ssl_to_uri = 0; add_ssl_to_uri < 2; add_ssl_to_uri++) { - if (add_ssl_to_uri) { - uri = mongoc_uri_new (uri_str_auth_ssl); - } else { - uri = mongoc_uri_new (uri_str_auth); - } - - if (pooled) { - pool = mongoc_client_pool_new (uri); - mongoc_client_pool_set_ssl_opts (pool, ssl_opts); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - mongoc_client_set_ssl_opts (client, ssl_opts); - } - - /* any operation */ - ret = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - if (test_framework_get_ssl ()) { - ASSERT_OR_PRINT (ret, error); - } else { - /* TODO: CDRIVER-936 check the err msg has "SSL handshake failed" */ - ASSERT (!ret); - ASSERT_CMPINT (MONGOC_ERROR_SERVER_SELECTION, ==, error.domain); - } - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); - } - - bson_free (uri_str_auth_ssl); - bson_free (uri_str_auth); - bson_free (uri_str); - bson_free (host_and_port); -}; - - -static void -test_ssl_single (void) -{ - _test_mongoc_client_ssl_opts (false); -} - - -static void -test_ssl_pooled (void) -{ - _test_mongoc_client_ssl_opts (true); -} - -static void -test_client_buildinfo_hang (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - mongoc_database_t *database; - bson_error_t error; - bson_t command; - bson_t reply; - - pool = test_framework_client_pool_new (); - BSON_ASSERT (pool); - client = mongoc_client_pool_pop (pool); - - database = mongoc_client_get_database (client, "admin"); - bson_init (&command); - bson_append_int32 (&command, "buildInfo", -1, 1); - - /* Prior to a bug fix this command caused a hang - see CDRIVER-3318 */ - ASSERT_OR_PRINT ( - mongoc_database_command_simple (database, &command, NULL, &reply, &error), - error); - - bson_destroy (&command); - bson_destroy (&reply); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - mongoc_client_pool_destroy (pool); -} - -#else -/* MONGOC_ENABLE_SSL is not defined */ -static void -test_mongoc_client_ssl_disabled (void) -{ - capture_logs (true); - ASSERT (NULL == mongoc_client_new ("mongodb://host/?ssl=true")); -} -#endif - - -static void -_test_mongoc_client_get_description (bool pooled) -{ - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - uint32_t server_id; - mongoc_server_description_t *sd; - mongoc_host_list_t host; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - /* bad server_id handled correctly */ - ASSERT (NULL == mongoc_client_get_server_description (client, 1234)); - - collection = get_test_collection (client, "test_mongoc_client_description"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), NULL, NULL); - ASSERT (!mongoc_cursor_next (cursor, &doc)); - server_id = mongoc_cursor_get_hint (cursor); - ASSERT (0 != server_id); - sd = mongoc_client_get_server_description (client, server_id); - ASSERT (sd); - mongoc_cursor_get_host (cursor, &host); - ASSERT ( - _mongoc_host_list_equal (&host, mongoc_server_description_host (sd))); - - mongoc_server_description_destroy (sd); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - - -static void -test_mongoc_client_get_description_single (void) -{ - _test_mongoc_client_get_description (false); -} - - -static void -test_mongoc_client_get_description_pooled (void) -{ - _test_mongoc_client_get_description (true); -} - - -static void -test_mongoc_client_descriptions (void) -{ - mongoc_client_t *client; - mongoc_client_pool_t *pool; - mongoc_server_description_t **sds; - size_t n, expected_n; - bson_error_t error; - bool r; - bson_t *ping = tmp_bson ("{'ping': 1}"); - int64_t start; - - expected_n = test_framework_server_count (); - - /* - * single-threaded - */ - client = test_framework_client_new (); - - /* before connecting */ - sds = mongoc_client_get_server_descriptions (client, &n); - ASSERT_CMPSIZE_T (n, ==, (size_t) 0); - bson_free (sds); - - /* connect */ - r = mongoc_client_command_simple (client, "db", ping, NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - sds = mongoc_client_get_server_descriptions (client, &n); - ASSERT_CMPSIZE_T (n, ==, expected_n); - - mongoc_server_descriptions_destroy_all (sds, n); - mongoc_client_destroy (client); - - /* - * pooled - */ - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - - /* wait for background thread to discover all members */ - start = bson_get_monotonic_time (); - do { - _mongoc_usleep (1000); - if (bson_get_monotonic_time () - start > 1000 * 1000) { - test_error ("still have %d descriptions, not expected %d, after 1 sec", - (int) n, - (int) expected_n); - abort (); - } - - sds = mongoc_client_get_server_descriptions (client, &n); - mongoc_server_descriptions_destroy_all (sds, n); - } while (n != expected_n); - - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); -} - - -static void -_test_mongoc_client_select_server (bool pooled) -{ - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - mongoc_server_description_t *sd; - const char *server_type; - bson_error_t error; - mongoc_read_prefs_t *prefs; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - sd = mongoc_client_select_server (client, - true, /* for writes */ - NULL, - &error); - - ASSERT (sd); - server_type = mongoc_server_description_type (sd); - ASSERT (!strcmp (server_type, "Standalone") || - !strcmp (server_type, "RSPrimary") || - !strcmp (server_type, "Mongos")); - - mongoc_server_description_destroy (sd); - sd = mongoc_client_select_server (client, - false, /* for reads */ - NULL, - &error); - - ASSERT (sd); - server_type = mongoc_server_description_type (sd); - ASSERT (!strcmp (server_type, "Standalone") || - !strcmp (server_type, "RSPrimary") || - !strcmp (server_type, "Mongos")); - - mongoc_server_description_destroy (sd); - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - sd = mongoc_client_select_server (client, - false, /* for reads */ - prefs, - &error); - - ASSERT (sd); - server_type = mongoc_server_description_type (sd); - ASSERT (!strcmp (server_type, "Standalone") || - !strcmp (server_type, "RSSecondary") || - !strcmp (server_type, "Mongos")); - - mongoc_server_description_destroy (sd); - mongoc_read_prefs_destroy (prefs); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - - -static void -test_mongoc_client_select_server_single (void) -{ - _test_mongoc_client_select_server (false); -} - - -static void -test_mongoc_client_select_server_pooled (void) -{ - _test_mongoc_client_select_server (true); -} - - -static void -_test_mongoc_client_select_server_error (bool pooled) -{ - mongoc_uri_t *uri = NULL; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_server_description_t *sd; - bson_error_t error; - mongoc_read_prefs_t *prefs; - mongoc_topology_description_type_t tdtype; - const char *server_type; - - if (pooled) { - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 1000); - pool = mongoc_client_pool_new (uri); - test_framework_set_pool_ssl_opts (pool); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - test_framework_set_ssl_opts (client); - } - - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_read_prefs_set_tags (prefs, tmp_bson ("[{'does-not-exist': 'x'}]")); - sd = mongoc_client_select_server (client, - true, /* for writes */ - prefs, - &error); - - ASSERT (!sd); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "Cannot use read preference"); - - sd = mongoc_client_select_server (client, - false, /* for reads */ - prefs, - &error); - - /* Server Selection Spec: "With topology type Single, the single server is - * always suitable for reads if it is available." */ - tdtype = client->topology->description.type; - if (tdtype == MONGOC_TOPOLOGY_SINGLE || tdtype == MONGOC_TOPOLOGY_SHARDED) { - ASSERT (sd); - server_type = mongoc_server_description_type (sd); - ASSERT (!strcmp (server_type, "Standalone") || - !strcmp (server_type, "Mongos")); - mongoc_server_description_destroy (sd); - } else { - ASSERT (!sd); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER_SELECTION); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_SERVER_SELECTION_FAILURE); - } - - mongoc_read_prefs_destroy (prefs); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); - } else { - mongoc_client_destroy (client); - } -} - - -static void -test_mongoc_client_select_server_error_single (void) -{ - _test_mongoc_client_select_server_error (false); -} - - -static void -test_mongoc_client_select_server_error_pooled (void) -{ - _test_mongoc_client_select_server_error (true); -} - - -/* CDRIVER-2172: in single mode, if the selected server has a socket that's been - * idle for socketCheckIntervalMS, check it with ping. If it fails, retry once. - */ -static void -_test_mongoc_client_select_server_retry (bool retry_succeeds) -{ - char *ismaster; - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - bson_error_t error; - request_t *request; - future_t *future; - mongoc_server_description_t *sd; - - server = mock_server_new (); - mock_server_run (server); - ismaster = bson_strdup_printf ("{'ok': 1, 'ismaster': true," - " 'secondary': false," - " 'minWireVersion': 2, 'maxWireVersion': 5," - " 'setName': 'rs', 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - mongoc_uri_set_option_as_int32 (uri, "socketCheckIntervalMS", 50); - client = mongoc_client_new_from_uri (uri); - - /* first selection succeeds */ - future = future_client_select_server (client, true, NULL, &error); - request = mock_server_receives_ismaster (server); - mock_server_replies_simple (request, ismaster); - request_destroy (request); - sd = future_get_mongoc_server_description_ptr (future); - ASSERT_OR_PRINT (sd, error); - - future_destroy (future); - mongoc_server_description_destroy (sd); - - /* let socketCheckIntervalMS pass */ - _mongoc_usleep (100 * 1000); - - /* second selection requires ping, which fails */ - future = future_client_select_server (client, true, NULL, &error); - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - - mock_server_hangs_up (request); - request_destroy (request); - - /* mongoc_client_select_server retries once */ - request = mock_server_receives_ismaster (server); - if (retry_succeeds) { - mock_server_replies_simple (request, ismaster); - sd = future_get_mongoc_server_description_ptr (future); - ASSERT_OR_PRINT (sd, error); - mongoc_server_description_destroy (sd); - } else { - mock_server_hangs_up (request); - sd = future_get_mongoc_server_description_ptr (future); - BSON_ASSERT (sd == NULL); - } - - future_destroy (future); - request_destroy (request); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - bson_free (ismaster); - mock_server_destroy (server); -} - - -static void -test_mongoc_client_select_server_retry_succeed (void) -{ - _test_mongoc_client_select_server_retry (true); -} - -static void -test_mongoc_client_select_server_retry_fail (void) -{ - _test_mongoc_client_select_server_retry (false); -} - - -/* CDRIVER-2172: in single mode, if the selected server has a socket that's been - * idle for socketCheckIntervalMS, check it with ping. If it fails, retry once. - */ -static void -_test_mongoc_client_fetch_stream_retry (bool retry_succeeds) -{ - char *ismaster; - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - bson_error_t error; - request_t *request; - future_t *future; - - server = mock_server_new (); - mock_server_run (server); - ismaster = bson_strdup_printf ( - "{'ok': 1, 'ismaster': true, 'minWireVersion': 2, 'maxWireVersion': 5}"); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "socketCheckIntervalMS", 50); - client = mongoc_client_new_from_uri (uri); - - /* first time succeeds */ - future = future_client_command_simple ( - client, "db", tmp_bson ("{'cmd': 1}"), NULL, NULL, &error); - request = mock_server_receives_ismaster (server); - mock_server_replies_simple (request, ismaster); - request_destroy (request); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'cmd': 1}"); - mock_server_replies_simple (request, "{'ok': 1}"); - request_destroy (request); - - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* let socketCheckIntervalMS pass */ - _mongoc_usleep (100 * 1000); - - /* second selection requires ping, which fails */ - future = future_client_command_simple ( - client, "db", tmp_bson ("{'cmd': 1}"), NULL, NULL, &error); - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - - mock_server_hangs_up (request); - request_destroy (request); - - /* mongoc_client_select_server retries once */ - request = mock_server_receives_ismaster (server); - if (retry_succeeds) { - mock_server_replies_simple (request, ismaster); - request_destroy (request); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'cmd': 1}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - } else { - mock_server_hangs_up (request); - BSON_ASSERT (!future_get_bool (future)); - } - - future_destroy (future); - request_destroy (request); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - bson_free (ismaster); - mock_server_destroy (server); -} - - -static void -test_mongoc_client_fetch_stream_retry_succeed (void) -{ - _test_mongoc_client_fetch_stream_retry (true); -} - -static void -test_mongoc_client_fetch_stream_retry_fail (void) -{ - _test_mongoc_client_fetch_stream_retry (false); -} - - -#if defined(MONGOC_ENABLE_SSL_OPENSSL) || \ - defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) -static bool -_cmd (mock_server_t *server, - mongoc_client_t *client, - bool server_replies, - bson_error_t *error) -{ - future_t *future; - request_t *request; - bool r; - - future = future_client_command_simple ( - client, "db", tmp_bson ("{'cmd': 1}"), NULL, NULL, error); - request = - mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, NULL); - ASSERT (request); - - if (server_replies) { - mock_server_replies_simple (request, "{'ok': 1}"); - } - - r = future_get_bool (future); - - future_destroy (future); - request_destroy (request); - - return r; -} - -static void -test_client_set_ssl_copies_args (bool pooled) -{ - mock_server_t *server; - mongoc_ssl_opt_t client_opts = {0}; - mongoc_ssl_opt_t server_opts = {0}; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - char *mutable_client_ca = NULL; - const size_t ca_bufsize = strlen (CERT_CA) + 1; - - mutable_client_ca = bson_malloc (ca_bufsize); - bson_strncpy (mutable_client_ca, CERT_CA, ca_bufsize); - - client_opts.ca_file = mutable_client_ca; - - server_opts.weak_cert_validation = true; - server_opts.ca_file = CERT_CA; - server_opts.pem_file = CERT_SERVER; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_set_ssl_opts (server, &server_opts); - mock_server_run (server); - - if (pooled) { - capture_logs (true); - pool = mongoc_client_pool_new (mock_server_get_uri (server)); - mongoc_client_pool_set_ssl_opts (pool, &client_opts); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - mongoc_client_set_ssl_opts (client, &client_opts); - } - - /* Now change the client ca string to be something else */ - bson_strncpy (mutable_client_ca, "garbage", ca_bufsize); - - ASSERT_OR_PRINT (_cmd (server, client, true /* server replies */, &error), - error); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - bson_free (mutable_client_ca); - mock_server_destroy (server); -} - -static void -test_ssl_client_single_copies_args (void) -{ - test_client_set_ssl_copies_args (false); -} - - -static void -test_ssl_client_pooled_copies_args (void) -{ - test_client_set_ssl_copies_args (true); -} - - -static void -_test_ssl_reconnect (bool pooled) -{ - mongoc_uri_t *uri; - mock_server_t *server; - mongoc_ssl_opt_t client_opts = {0}; - mongoc_ssl_opt_t server_opts = {0}; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - future_t *future; - - client_opts.ca_file = CERT_CA; - - server_opts.weak_cert_validation = true; - server_opts.ca_file = CERT_CA; - server_opts.pem_file = CERT_SERVER; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_set_ssl_opts (server, &server_opts); - mock_server_run (server); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "socketTimeoutMS", 1000); - - if (pooled) { - capture_logs (true); - pool = mongoc_client_pool_new (uri); - mongoc_client_pool_set_ssl_opts (pool, &client_opts); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - mongoc_client_set_ssl_opts (client, &client_opts); - } - - ASSERT_OR_PRINT (_cmd (server, client, true /* server replies */, &error), - error); - - /* man-in-the-middle: certificate changed, for example expired */ - server_opts.pem_file = CERT_EXPIRED; - mock_server_set_ssl_opts (server, &server_opts); - - /* network timeout */ - - ASSERT (!_cmd (server, client, false /* server hangs up */, &error)); - if (pooled) { - ASSERT_CAPTURED_LOG ( - "failed to write data because server closed the connection", - MONGOC_LOG_LEVEL_WARNING, - "Failed to buffer 36 bytes"); - } - - /* next operation comes on a new connection, server verification fails */ - future = future_client_command_simple ( - client, "db", tmp_bson ("{'cmd': 1}"), NULL, NULL, &error); - - ASSERT (!future_get_bool (future)); - ASSERT_CONTAINS (error.message, "TLS handshake failed"); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - future_destroy (future); - mock_server_destroy (server); - mongoc_uri_destroy (uri); -} - - -static void -test_ssl_reconnect_single (void) -{ - _test_ssl_reconnect (false); -} - - -static void -test_ssl_reconnect_pooled (void) -{ - _test_ssl_reconnect (true); -} -#endif /* OpenSSL or Secure Transport */ - - -static void -test_mongoc_client_application_handshake (void) -{ - enum { BUFFER_SIZE = HANDSHAKE_MAX_SIZE }; - char big_string[BUFFER_SIZE]; - const char *short_string = "hallo thar"; - mongoc_client_t *client; - - client = mongoc_client_new ("mongodb://example"); - - memset (big_string, 'a', BUFFER_SIZE - 1); - big_string[BUFFER_SIZE - 1] = '\0'; - - /* Check that setting too long a name causes failure */ - capture_logs (true); - ASSERT (!mongoc_client_set_appname (client, big_string)); - ASSERT_CAPTURED_LOG ("_mongoc_topology_scanner_set_appname", - MONGOC_LOG_LEVEL_ERROR, - "is invalid"); - clear_captured_logs (); - - /* Success case */ - ASSERT (mongoc_client_set_appname (client, short_string)); - - /* Make sure we can't set it twice */ - ASSERT (!mongoc_client_set_appname (client, "a")); - ASSERT_CAPTURED_LOG ("_mongoc_topology_scanner_set_appname", - MONGOC_LOG_LEVEL_ERROR, - "Cannot set appname more than once"); - capture_logs (false); - - mongoc_client_destroy (client); -} - -static void -_assert_ismaster_valid (request_t *request, bool needs_meta) -{ - const bson_t *request_doc; - - ASSERT (request); - request_doc = request_get_doc (request, 0); - ASSERT (request_doc); - ASSERT (bson_has_field (request_doc, "isMaster")); - ASSERT (bson_has_field (request_doc, HANDSHAKE_FIELD) == needs_meta); -} - -/* For single threaded clients, to cause an isMaster to be sent, we must wait - * until we're overdue for a heartbeat, and then execute some command */ -static future_t * -_force_ismaster_with_ping (mongoc_client_t *client, int heartbeat_ms) -{ - future_t *future; - - /* Wait until we're overdue to send an isMaster */ - _mongoc_usleep (heartbeat_ms * 2 * 1000); - - /* Send a ping */ - future = future_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL); - ASSERT (future); - return future; -} - -/* Call after we've dealt with the isMaster sent by - * _force_ismaster_with_ping */ -static void -_respond_to_ping (future_t *future, mock_server_t *server) -{ - request_t *request; - - ASSERT (future); - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); -} - -static void -test_mongoc_handshake_pool (void) -{ - mock_server_t *server; - request_t *request1; - request_t *request2; - mongoc_uri_t *uri; - mongoc_client_t *client1; - mongoc_client_t *client2; - mongoc_client_pool_t *pool; - const char *const server_reply = - "{'ok': 1, 'ismaster': true, 'minWireVersion': 2, 'maxWireVersion': 5}"; - future_t *future; - - server = mock_server_new (); - mock_server_run (server); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - ASSERT (mongoc_uri_set_appname (uri, BSON_FUNC)); - - pool = mongoc_client_pool_new (uri); - - client1 = mongoc_client_pool_pop (pool); - request1 = mock_server_receives_ismaster (server); - _assert_ismaster_valid (request1, true); - mock_server_replies_simple (request1, server_reply); - request_destroy (request1); - - client2 = mongoc_client_pool_pop (pool); - future = future_client_command_simple ( - client2, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL); - - request2 = mock_server_receives_ismaster (server); - _assert_ismaster_valid (request2, true); - mock_server_replies_simple (request2, server_reply); - request_destroy (request2); - - request2 = mock_server_receives_command ( - server, "test", MONGOC_QUERY_SLAVE_OK, NULL); - mock_server_replies_ok_and_destroys (request2); - ASSERT (future_get_bool (future)); - future_destroy (future); - - mongoc_client_pool_push (pool, client1); - mongoc_client_pool_push (pool, client2); - - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - -static void -_test_client_sends_handshake (bool pooled) -{ - mock_server_t *server; - request_t *request; - mongoc_uri_t *uri; - future_t *future; - mongoc_client_t *client; - mongoc_client_pool_t *pool; - const char *const server_reply = - "{'ok': 1, 'ismaster': true, 'minWireVersion': 2, 'maxWireVersion': 5}"; - const int heartbeat_ms = 500; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", heartbeat_ms); - mongoc_uri_set_option_as_int32 (uri, "connectTimeoutMS", 100); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - - /* Pop a client to trigger the topology scanner */ - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - future = _force_ismaster_with_ping (client, heartbeat_ms); - } - - request = mock_server_receives_ismaster (server); - - /* Make sure the isMaster request has a "client" field: */ - _assert_ismaster_valid (request, true); - mock_server_replies_simple (request, server_reply); - request_destroy (request); - - if (!pooled) { - _respond_to_ping (future, server); - - /* Wait until another isMaster is sent */ - future = _force_ismaster_with_ping (client, heartbeat_ms); - } - - request = mock_server_receives_ismaster (server); - _assert_ismaster_valid (request, false); - - mock_server_replies_simple (request, server_reply); - request_destroy (request); - - if (!pooled) { - _respond_to_ping (future, server); - future = _force_ismaster_with_ping (client, heartbeat_ms); - } - - /* Now wait for the client to send another isMaster command, but this - * time the server hangs up */ - request = mock_server_receives_ismaster (server); - _assert_ismaster_valid (request, false); - mock_server_hangs_up (request); - request_destroy (request); - - /* Client retries once (CDRIVER-2075) */ - request = mock_server_receives_ismaster (server); - _assert_ismaster_valid (request, true); - mock_server_hangs_up (request); - request_destroy (request); - - if (!pooled) { - /* The ping wasn't sent since we hung up with isMaster */ - ASSERT (!future_get_bool (future)); - future_destroy (future); - - /* We're in cooldown for the next few seconds, so we're not - * allowed to send isMasters. Wait for the cooldown to end. */ - _mongoc_usleep ((MONGOC_TOPOLOGY_COOLDOWN_MS + 1000) * 1000); - future = _force_ismaster_with_ping (client, heartbeat_ms); - } - - /* Now the client should try to reconnect. They think the server's down - * so now they SHOULD send isMaster */ - request = mock_server_receives_ismaster (server); - _assert_ismaster_valid (request, true); - - mock_server_replies_simple (request, server_reply); - request_destroy (request); - - if (!pooled) { - _respond_to_ping (future, server); - } - - /* cleanup */ - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - -static void -test_client_sends_handshake_single (void *ctx) -{ - _test_client_sends_handshake (false); -} - -static void -test_client_sends_handshake_pooled (void) -{ - _test_client_sends_handshake (true); -} - -static void -test_client_appname (bool pooled, bool use_uri) -{ - mock_server_t *server; - request_t *request; - mongoc_uri_t *uri; - future_t *future; - mongoc_client_t *client; - mongoc_client_pool_t *pool; - const char *const server_reply = - "{'ok': 1, 'ismaster': true, 'minWireVersion': 2, 'maxWireVersion': 5}"; - const int heartbeat_ms = 500; - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", heartbeat_ms); - mongoc_uri_set_option_as_int32 (uri, "connectTimeoutMS", 120 * 1000); - - if (use_uri) { - mongoc_uri_set_option_as_utf8 (uri, "appname", "testapp"); - } - - if (pooled) { - pool = mongoc_client_pool_new (uri); - if (!use_uri) { - ASSERT (mongoc_client_pool_set_appname (pool, "testapp")); - } - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - if (!use_uri) { - ASSERT (mongoc_client_set_appname (client, "testapp")); - } - future = _force_ismaster_with_ping (client, heartbeat_ms); - } - - request = mock_server_receives_command (server, - "admin", - MONGOC_QUERY_SLAVE_OK, - "{'isMaster': 1," - " 'client': {" - " 'application': {" - " 'name': 'testapp'}}}"); - - mock_server_replies_simple (request, server_reply); - if (!pooled) { - _respond_to_ping (future, server); - } - - request_destroy (request); - - /* cleanup */ - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - -static void -test_client_appname_single_uri (void) -{ - test_client_appname (false, true); -} - -static void -test_client_appname_single_no_uri (void) -{ - test_client_appname (false, false); -} - -static void -test_client_appname_pooled_uri (void) -{ - test_client_appname (true, true); -} - -static void -test_client_appname_pooled_no_uri (void) -{ - test_client_appname (true, false); -} - -/* test a disconnect with a NULL bson_error_t * passed to command_simple() */ -static void -_test_null_error_pointer (bool pooled) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - future_t *future; - request_t *request; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - capture_logs (true); - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 1000); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - } - - /* connect */ - future = future_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL); - request = mock_server_receives_command ( - server, "test", MONGOC_QUERY_SLAVE_OK, NULL); - mock_server_replies_ok_and_destroys (request); - ASSERT (future_get_bool (future)); - future_destroy (future); - - /* disconnect */ - mock_server_destroy (server); - if (pooled) { - mongoc_cluster_disconnect_node (&client->cluster, 1, false, NULL); - } else { - mongoc_topology_scanner_node_t *scanner_node; - - scanner_node = - mongoc_topology_scanner_get_node (client->topology->scanner, 1); - mongoc_stream_destroy (scanner_node->stream); - scanner_node->stream = NULL; - } - - /* doesn't abort with assertion failure */ - future = future_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL /* error */); - - ASSERT (!future_get_bool (future)); - future_destroy (future); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); -} - -static void -test_null_error_pointer_single (void *ctx) -{ - _test_null_error_pointer (false); -} - -static void -test_null_error_pointer_pooled (void *ctx) -{ - _test_null_error_pointer (true); -} - -#ifdef MONGOC_ENABLE_SSL -static void -test_set_ssl_opts (void) -{ - const mongoc_ssl_opt_t *opts = mongoc_ssl_opt_get_default (); - - ASSERT (opts->pem_file == NULL); - ASSERT (opts->pem_pwd == NULL); - ASSERT (opts->ca_file == NULL); - ASSERT (opts->ca_dir == NULL); - ASSERT (opts->crl_file == NULL); - ASSERT (!opts->weak_cert_validation); - ASSERT (!opts->allow_invalid_hostname); -} -#endif - -static void -test_client_reset_sessions (void) -{ - bson_error_t error; - mock_server_t *server; - mongoc_client_t *client; - mongoc_client_session_t *session; - mongoc_client_session_t *session_lookup; - future_t *future; - request_t *request; - bson_t opts = BSON_INITIALIZER; - uint32_t csid; - bson_t lsid; - bool res; - - server = mock_mongos_new (WIRE_VERSION_OP_MSG); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - ASSERT (client->generation == 0); - - /* Ensure that resetting client removes existing sessions from its set */ - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - ASSERT (session->client_generation == client->generation); - csid = session->client_session_id; - - mongoc_client_reset (client); - ASSERT (client->generation == 1); - - ASSERT ( - !_mongoc_client_lookup_session (client, csid, &session_lookup, &error)); - - /* Ensure that resetting did not send endSessions. To do this, we wait for - a ping, so if we receive endSessions instead we will fail. */ - future = future_client_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, &error); - - request = mock_server_receives_msg ( - server, 0, tmp_bson ("{'ping': 1, 'lsid': {'$exists': true}}")); - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (future_get_bool (future)); - - future_destroy (future); - - /* Ensure that a session left over from before the reset call cannot - be used for any operations. */ - bson_copy_to (mongoc_client_session_get_lsid (session), &lsid); - res = (mongoc_client_session_append (session, &opts, &error)); - ASSERT_OR_PRINT (res, error); - future = future_client_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, &opts, NULL, &error); - - ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid sessionId"); - - /* Add an autoresponder for endSessions to unblock the test. */ - mock_server_auto_endsessions (server); - - bson_destroy (&opts); - bson_destroy (&lsid); - request_destroy (request); - future_destroy (future); - mongoc_client_session_destroy (session); - mongoc_client_session_destroy (session_lookup); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_client_reset_cursors (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - mongoc_database_t *database; - mongoc_collection_t *coll; - future_t *future; - request_t *request; - bson_error_t error; - const bson_t *doc; - - server = mock_server_with_autoismaster (WIRE_VERSION_KILLCURSORS_CMD); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - /* Ensure that cursors with an old client generation don't send killCursors. - This test should timeout and fail if the client does send killCursors. */ - - coll = mongoc_client_get_collection (client, "test", "test"); - cursor = mongoc_collection_find ( - coll, MONGOC_QUERY_NONE, 0, 0, 0, tmp_bson (NULL), NULL, NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command ( - server, "test", MONGOC_QUERY_SLAVE_OK, "{'find': 'test'}"); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 4," - " 'ns': 'test.test'," - " 'firstBatch': [{}]}}"); - - BSON_ASSERT (future_get_bool (future)); - ASSERT (cursor->cursor_id); - - mongoc_client_reset (client); - - /* Attempt to call next() on the cursor after a reset--should fail without - sending any requests to the server. */ - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot advance cursor after client reset"); - - mongoc_cursor_destroy (cursor); - - request_destroy (request); - future_destroy (future); - - /* Expect a ping here, and send one after destroying cursor. If a killCursors - command intervened, this test will fail. */ - database = mongoc_client_get_database (client, "admin"); - future = future_database_command_simple ( - database, tmp_bson ("{'ping': 1}"), NULL, NULL, NULL); - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_client_destroy (client); - mongoc_collection_destroy (coll); - mongoc_database_destroy (database); - mock_server_destroy (server); -} - -static bool -mongoc_topology_scanner_is_connected (mongoc_topology_scanner_t *scanner) -{ - mongoc_topology_scanner_node_t *node; - - BSON_ASSERT (scanner); - node = scanner->nodes; - - if (!node) { - return false; - } - - while (node) { - if (!node->stream) { - return false; - } - - node = node->next; - } - - return true; -} - -static void -test_client_reset_connections (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_database_t *database; - mongoc_uri_t *uri; - future_t *future; - request_t *request; - int autoresponder_id; - - server = mock_server_new (); - autoresponder_id = mock_server_auto_ismaster (server, "{ 'isMaster': 1.0 }"); - mock_server_run (server); - - /* After calling reset, check that connections are left as-is. Set - heartbeat frequency high, so a background scan won't interfere. */ - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 99999); - client = mongoc_client_new_from_uri (uri); - - database = mongoc_client_get_database (client, "admin"); - future = future_database_command_simple ( - database, tmp_bson ("{'ping': 1}"), NULL, NULL, NULL); - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (future_get_bool (future)); - - mock_server_remove_autoresponder (server, autoresponder_id); - - ASSERT (mongoc_topology_scanner_is_connected (client->topology->scanner)); - - mongoc_client_reset (client); - - ASSERT (mongoc_topology_scanner_is_connected (client->topology->scanner)); - - request_destroy (request); - future_destroy (future); - mongoc_uri_destroy (uri); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_get_database (void) -{ - mongoc_client_t *client; - mongoc_database_t *database; - mongoc_write_concern_t *wc; - mongoc_read_concern_t *rc; - mongoc_read_prefs_t *read_prefs; - - client = mongoc_client_new (NULL); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_client_set_write_concern (client, wc); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, "majority"); - mongoc_client_set_read_concern (client, rc); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_client_set_read_prefs (client, read_prefs); - - database = mongoc_client_get_database (client, "test"); - - ASSERT_CMPINT32 (database->write_concern->w, ==, 2); - ASSERT_CMPSTR (database->read_concern->level, "majority"); - ASSERT_CMPINT (database->read_prefs->mode, ==, MONGOC_READ_SECONDARY); - - mongoc_database_destroy (database); - mongoc_read_prefs_destroy (read_prefs); - mongoc_read_concern_destroy (rc); - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); -} - - -void -test_client_install (TestSuite *suite) -{ - if (test_framework_getenv_bool ("MONGOC_CHECK_IPV6")) { - /* try to validate ipv6 too */ - TestSuite_AddLive ( - suite, "/Client/ipv6/single", test_mongoc_client_ipv6_single); - - /* try to validate ipv6 too */ - TestSuite_AddLive ( - suite, "/Client/ipv6/single", 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/authenticate_cached/pool", - test_mongoc_client_authenticate_cached_pooled, - NULL, - NULL, - test_framework_skip_if_no_auth); - TestSuite_AddFull (suite, - "/Client/authenticate_cached/client", - test_mongoc_client_authenticate_cached_single, - NULL, - NULL, - test_framework_skip_if_no_auth); - TestSuite_AddFull (suite, - "/Client/authenticate_failure", - test_mongoc_client_authenticate_failure, - NULL, - NULL, - test_framework_skip_if_no_auth); - TestSuite_AddFull (suite, - "/Client/authenticate_timeout", - test_mongoc_client_authenticate_timeout, - NULL, - NULL, - test_framework_skip_if_no_auth); - TestSuite_AddLive (suite, "/Client/command", test_mongoc_client_command); - TestSuite_AddLive ( - suite, "/Client/command_defaults", test_mongoc_client_command_defaults); - TestSuite_AddLive ( - suite, "/Client/command_secondary", test_mongoc_client_command_secondary); - 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, - test_framework_skip_if_max_wire_version_less_than_5); - 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 (suite, - "/Client/command/read_prefs/simple/single", - test_command_simple_read_prefs_single); - TestSuite_AddMockServerTest (suite, - "/Client/command/read_prefs/simple/pooled", - test_command_simple_read_prefs_pooled); - TestSuite_AddMockServerTest (suite, - "/Client/command/read_prefs/single", - test_command_read_prefs_single); - TestSuite_AddMockServerTest (suite, - "/Client/command/read_prefs/pooled", - test_command_read_prefs_pooled); - TestSuite_AddLive ( - suite, "/Client/command_not_found/cursor", test_command_not_found); - TestSuite_AddLive ( - suite, "/Client/command_not_found/simple", test_command_not_found_simple); - TestSuite_AddMockServerTest (suite, - "/Client/command_with_opts/read_prefs", - test_command_with_opts_read_prefs); - TestSuite_AddMockServerTest (suite, - "/Client/command_with_opts/read_write", - test_read_write_cmd_with_opts); - TestSuite_AddMockServerTest ( - suite, "/Client/command_with_opts/legacy", test_command_with_opts_legacy); - TestSuite_AddMockServerTest ( - suite, "/Client/command_with_opts", test_command_with_opts); - TestSuite_AddMockServerTest ( - suite, "/Client/command_with_opts/op_msg", test_command_with_opts_op_msg); - TestSuite_AddMockServerTest ( - suite, "/Client/command_with_opts/read", test_read_command_with_opts); - TestSuite_AddLive (suite, "/Client/command/empty", test_command_empty); - TestSuite_AddMockServerTest ( - suite, "/Client/command/no_errmsg", test_command_no_errmsg); - TestSuite_AddMockServerTest ( - suite, "/Client/unavailable_seeds", test_unavailable_seeds); - TestSuite_AddMockServerTest (suite, - "/Client/rs_seeds_no_connect/single", - test_rs_seeds_no_connect_single); - TestSuite_AddMockServerTest (suite, - "/Client/rs_seeds_no_connect/pooled", - test_rs_seeds_no_connect_pooled); - TestSuite_AddMockServerTest ( - suite, "/Client/rs_seeds_connect/single", test_rs_seeds_connect_single); - TestSuite_AddMockServerTest ( - suite, "/Client/rs_seeds_connect/pooled", test_rs_seeds_connect_pooled); - TestSuite_AddMockServerTest (suite, - "/Client/rs_seeds_reconnect/single", - test_rs_seeds_reconnect_single); - TestSuite_AddMockServerTest (suite, - "/Client/rs_seeds_reconnect/pooled", - test_rs_seeds_reconnect_pooled); - TestSuite_AddMockServerTest (suite, - "/Client/mongos_seeds_no_connect/single", - test_mongos_seeds_no_connect_single); - TestSuite_AddMockServerTest (suite, - "/Client/mongos_seeds_no_connect/pooled", - test_mongos_seeds_no_connect_pooled); - TestSuite_AddMockServerTest (suite, - "/Client/mongos_seeds_connect/single", - test_mongos_seeds_connect_single); - TestSuite_AddMockServerTest (suite, - "/Client/mongos_seeds_connect/pooled", - test_mongos_seeds_connect_pooled); - TestSuite_AddMockServerTest (suite, - "/Client/mongos_seeds_reconnect/single", - test_mongos_seeds_reconnect_single); - 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_AddLive (suite, "/Client/server_status", test_server_status); - 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_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", - test_client_sends_handshake_single, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_Add (suite, - "/Client/sends_handshake_pooled", - test_client_sends_handshake_pooled); - TestSuite_AddMockServerTest ( - suite, "/Client/appname_single_uri", test_client_appname_single_uri); - TestSuite_AddMockServerTest (suite, - "/Client/appname_single_no_uri", - test_client_appname_single_no_uri); - TestSuite_AddMockServerTest ( - suite, "/Client/appname_pooled_uri", test_client_appname_pooled_uri); - TestSuite_AddMockServerTest (suite, - "/Client/appname_pooled_no_uri", - test_client_appname_pooled_no_uri); - TestSuite_AddMockServerTest ( - suite, "/Client/wire_version", test_wire_version); -#ifdef MONGOC_ENABLE_SSL - TestSuite_AddLive (suite, "/Client/ssl_opts/single", test_ssl_single); - TestSuite_AddLive (suite, "/Client/ssl_opts/pooled", test_ssl_pooled); - TestSuite_Add (suite, "/Client/set_ssl_opts", test_set_ssl_opts); - -#if defined(MONGOC_ENABLE_SSL_OPENSSL) || \ - defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) - TestSuite_AddMockServerTest (suite, - "/Client/ssl_opts/copies_single", - test_ssl_client_single_copies_args); - TestSuite_AddMockServerTest (suite, - "/Client/ssl_opts/copies_pooled", - test_ssl_client_pooled_copies_args); - TestSuite_AddMockServerTest ( - suite, "/Client/ssl/reconnect/single", test_ssl_reconnect_single); - TestSuite_AddMockServerTest ( - suite, "/Client/ssl/reconnect/pooled", test_ssl_reconnect_pooled); - - TestSuite_AddLive (suite, "/Client/ssl_hang", test_client_buildinfo_hang); - -#endif -#else - /* No SSL support at all */ - TestSuite_Add ( - suite, "/Client/ssl_disabled", test_mongoc_client_ssl_disabled); -#endif - - TestSuite_AddMockServerTest (suite, - "/Client/client_reset/sessions", - test_client_reset_sessions, - test_framework_skip_if_no_crypto); - - TestSuite_AddMockServerTest ( - suite, "/Client/client_reset/cursors", test_client_reset_cursors); - TestSuite_AddMockServerTest ( - suite, "/Client/client_reset/connections", test_client_reset_connections); - - 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", test_mongoc_client_descriptions); - 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); - TestSuite_AddLive (suite, - "/Client/select_server/err/pooled", - test_mongoc_client_select_server_error_pooled); - TestSuite_AddMockServerTest (suite, - "/Client/select_server/retry/succeed", - test_mongoc_client_select_server_retry_succeed); - TestSuite_AddMockServerTest (suite, - "/Client/select_server/retry/fail", - test_mongoc_client_select_server_retry_fail); - TestSuite_AddMockServerTest (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", - test_null_error_pointer_single, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Client/null_error_pointer/pooled", - test_null_error_pointer_pooled, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_Add (suite, "/Client/get_database", test_get_database); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-cluster.c b/lib/mongoc/libmongoc/tests/test-mongoc-cluster.c deleted file mode 100644 index 646fe9d9fff6b9e6462b1d70aa6815a41b03d866..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-cluster.c +++ /dev/null @@ -1,1691 +0,0 @@ -#include <mongoc/mongoc-util-private.h> -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-uri-private.h" - -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "test-conveniences.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "cluster-test" - - -static uint32_t -server_id_for_reads (mongoc_cluster_t *cluster) -{ - bson_error_t error; - mongoc_server_stream_t *server_stream; - uint32_t id; - - server_stream = - mongoc_cluster_stream_for_reads (cluster, NULL, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - id = server_stream->sd->id; - - mongoc_server_stream_cleanup (server_stream); - - return id; -} - - -static void -test_get_max_bson_obj_size (void) -{ - mongoc_server_description_t *sd; - mongoc_cluster_node_t *node; - mongoc_client_pool_t *pool; - mongoc_client_t *client; - int32_t max_bson_obj_size = 16; - uint32_t id; - - /* single-threaded */ - client = test_framework_client_new (); - BSON_ASSERT (client); - - id = server_id_for_reads (&client->cluster); - sd = (mongoc_server_description_t *) mongoc_set_get ( - client->topology->description.servers, id); - sd->max_bson_obj_size = max_bson_obj_size; - BSON_ASSERT (max_bson_obj_size == - mongoc_cluster_get_max_bson_obj_size (&client->cluster)); - - mongoc_client_destroy (client); - - /* multi-threaded */ - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - - id = server_id_for_reads (&client->cluster); - node = (mongoc_cluster_node_t *) mongoc_set_get (client->cluster.nodes, id); - node->max_bson_obj_size = max_bson_obj_size; - BSON_ASSERT (max_bson_obj_size == - mongoc_cluster_get_max_bson_obj_size (&client->cluster)); - - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); -} - -static void -test_get_max_msg_size (void) -{ - mongoc_server_description_t *sd; - mongoc_cluster_node_t *node; - mongoc_client_pool_t *pool; - mongoc_client_t *client; - int32_t max_msg_size = 32; - uint32_t id; - - /* single-threaded */ - client = test_framework_client_new (); - id = server_id_for_reads (&client->cluster); - - sd = (mongoc_server_description_t *) mongoc_set_get ( - client->topology->description.servers, id); - sd->max_msg_size = max_msg_size; - BSON_ASSERT (max_msg_size == - mongoc_cluster_get_max_msg_size (&client->cluster)); - - mongoc_client_destroy (client); - - /* multi-threaded */ - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - - id = server_id_for_reads (&client->cluster); - node = (mongoc_cluster_node_t *) mongoc_set_get (client->cluster.nodes, id); - node->max_msg_size = max_msg_size; - BSON_ASSERT (max_msg_size == - mongoc_cluster_get_max_msg_size (&client->cluster)); - - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); -} - - -#define ASSERT_CURSOR_ERR() \ - do { \ - BSON_ASSERT (!future_get_bool (future)); \ - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); \ - ASSERT_ERROR_CONTAINS ( \ - error, \ - MONGOC_ERROR_STREAM, \ - MONGOC_ERROR_STREAM_SOCKET, \ - "Failed to read 4 bytes: socket error or timeout"); \ - } while (0) - - -#define START_QUERY(client_port_variable) \ - do { \ - cursor = mongoc_collection_find_with_opts ( \ - collection, tmp_bson ("{}"), NULL, NULL); \ - future = future_cursor_next (cursor, &doc); \ - request = mock_server_receives_query ( \ - server, "test.test", MONGOC_QUERY_SLAVE_OK, 0, 0, "{}", NULL); \ - client_port_variable = request_get_client_port (request); \ - } while (0) - - -#define CLEANUP_QUERY() \ - do { \ - request_destroy (request); \ - future_destroy (future); \ - mongoc_cursor_destroy (cursor); \ - } while (0) - - -/* test that we reconnect a cluster node after disconnect */ -static void -_test_cluster_node_disconnect (bool pooled) -{ - mock_server_t *server; - const int32_t socket_timeout_ms = 100; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - const bson_t *doc; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - uint16_t client_port_0, client_port_1; - bson_error_t error; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - capture_logs (true); - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "socketTimeoutMS", socket_timeout_ms); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - } - - collection = mongoc_client_get_collection (client, "test", "test"); - - /* query 0 fails. set client_port_0 to the port used by the query. */ - START_QUERY (client_port_0); - - mock_server_resets (request); - ASSERT_CURSOR_ERR (); - CLEANUP_QUERY (); - - /* query 1 opens a new socket. set client_port_1 to the new port. */ - START_QUERY (client_port_1); - ASSERT_CMPINT (client_port_1, !=, client_port_0); - mock_server_replies_simple (request, "{'a': 1}"); - - /* success! */ - BSON_ASSERT (future_get_bool (future)); - - CLEANUP_QUERY (); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -static void -test_cluster_node_disconnect_single (void *ctx) -{ - _test_cluster_node_disconnect (false); -} - - -static void -test_cluster_node_disconnect_pooled (void *ctx) -{ - _test_cluster_node_disconnect (true); -} - - -static void -_test_cluster_command_timeout (bool pooled) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - future_t *future; - request_t *request; - uint16_t client_port; - mongoc_server_description_t *sd; - bson_t reply; - - capture_logs (true); - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "socketTimeoutMS", 200); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - } - - /* server doesn't respond in time */ - future = future_client_command_simple ( - client, "db", tmp_bson ("{'foo': 1}"), NULL, NULL, &error); - request = - mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, NULL); - client_port = request_get_client_port (request); - - ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to send \"foo\" command with database \"db\""); - - /* a network timeout does NOT invalidate the server description */ - sd = mongoc_topology_server_by_id (client->topology, 1, NULL); - BSON_ASSERT (sd->type != MONGOC_SERVER_UNKNOWN); - mongoc_server_description_destroy (sd); - - /* late response */ - mock_server_replies_simple (request, "{'ok': 1, 'bar': 1}"); - request_destroy (request); - future_destroy (future); - - future = future_client_command_simple ( - client, "db", tmp_bson ("{'baz': 1}"), NULL, &reply, &error); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'baz': 1}"); - ASSERT (request); - /* new socket */ - ASSERT_CMPUINT16 (client_port, !=, request_get_client_port (request)); - mock_server_replies_simple (request, "{'ok': 1, 'quux': 1}"); - ASSERT (future_get_bool (future)); - - /* got the proper response */ - ASSERT_HAS_FIELD (&reply, "quux"); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - bson_destroy (&reply); - request_destroy (request); - future_destroy (future); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -static void -test_cluster_command_timeout_single (void) -{ - _test_cluster_command_timeout (false); -} - - -static void -test_cluster_command_timeout_pooled (void) -{ - _test_cluster_command_timeout (true); -} - - -static void -_test_write_disconnect (void) -{ - mock_server_t *server; - char *ismaster_response; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - future_t *future; - request_t *request; - mongoc_topology_scanner_node_t *scanner_node; - mongoc_server_description_t *sd; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - server = mock_server_new (); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - /* - * establish connection with an "ismaster" and "ping" - */ - future = future_client_command_simple ( - client, "db", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - request = mock_server_receives_ismaster (server); - ismaster_response = bson_strdup_printf ("{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 2," - " 'maxWireVersion': 3}"); - - mock_server_replies_simple (request, ismaster_response); - request_destroy (request); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - - /* - * close the socket - */ - mock_server_hangs_up (request); - - /* - * next operation detects the hangup - */ - collection = mongoc_client_get_collection (client, "db", "collection"); - future_destroy (future); - future = future_collection_insert_one ( - collection, tmp_bson ("{'_id': 1}"), NULL, NULL, &error); - - ASSERT (!future_get_bool (future)); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_STREAM); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_STREAM_SOCKET); - - scanner_node = mongoc_topology_scanner_get_node (client->topology->scanner, - 1 /* server_id */); - ASSERT (scanner_node && !scanner_node->stream); - - /* a hangup DOES invalidate the server description */ - sd = mongoc_topology_server_by_id (client->topology, 1, NULL); - BSON_ASSERT (sd->type == MONGOC_SERVER_UNKNOWN); - mongoc_server_description_destroy (sd); - - mongoc_collection_destroy (collection); - request_destroy (request); - future_destroy (future); - bson_free (ismaster_response); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_write_command_disconnect (void *ctx) -{ - _test_write_disconnect (); -} - - -typedef struct { - int calls; - bson_t *cluster_time; - bson_t *command; -} cluster_time_test_t; - - -static void -test_cluster_time_cmd_started_cb (const mongoc_apm_command_started_t *event) -{ - const bson_t *cmd; - cluster_time_test_t *test; - bson_iter_t iter; - bson_t client_cluster_time; - - cmd = mongoc_apm_command_started_get_command (event); - if (!strcmp (_mongoc_get_command_name (cmd), "killCursors")) { - /* ignore killCursors */ - return; - } - - test = - (cluster_time_test_t *) mongoc_apm_command_started_get_context (event); - - test->calls++; - bson_destroy (test->command); - test->command = bson_copy (cmd); - - /* Only a MongoDB 3.6+ server reports $clusterTime. If we've received a - * $clusterTime, we send it to any server. In this case, we got a - * $clusterTime during the initial handshake. */ - if (test_framework_clustertime_supported ()) { - BSON_ASSERT (bson_iter_init_find (&iter, cmd, "$clusterTime")); - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - - if (test->calls == 2) { - /* previous call to cmd_succeeded_cb saved server's clusterTime */ - BSON_ASSERT (!bson_empty0 (test->cluster_time)); - bson_iter_bson (&iter, &client_cluster_time); - if (!bson_equal (test->cluster_time, &client_cluster_time)) { - fprintf (stderr, - "Unequal clusterTimes.\nServer sent %s\nClient sent %s\n", - bson_as_json (test->cluster_time, NULL), - bson_as_json (&client_cluster_time, NULL)); - - abort (); - } - - bson_destroy (&client_cluster_time); - } - } else { - BSON_ASSERT (!bson_has_field (event->command, "$clusterTime")); - } -} - - -static void -test_cluster_time_cmd_succeeded_cb (const mongoc_apm_command_succeeded_t *event) -{ - const bson_t *reply; - cluster_time_test_t *test; - bson_iter_t iter; - uint32_t len; - const uint8_t *data; - - reply = mongoc_apm_command_succeeded_get_reply (event); - test = - (cluster_time_test_t *) mongoc_apm_command_succeeded_get_context (event); - - /* Only a MongoDB 3.6+ server reports $clusterTime. Save it in "test". */ - if (test_framework_clustertime_supported ()) { - BSON_ASSERT (bson_iter_init_find (&iter, reply, "$clusterTime")); - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - bson_iter_document (&iter, &len, &data); - bson_destroy (test->cluster_time); - test->cluster_time = bson_new_from_data (data, len); - } -} - - -typedef bool (*command_fn_t) (mongoc_client_t *, bson_error_t *); - - -/* test $clusterTime handling according to the test instructions in the - * Driver Sessions Spec */ -static void -_test_cluster_time (bool pooled, command_fn_t command) -{ - mongoc_apm_callbacks_t *callbacks; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bool r; - bson_error_t error; - cluster_time_test_t cluster_time_test; - - cluster_time_test.calls = 0; - cluster_time_test.command = NULL; - cluster_time_test.cluster_time = NULL; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, - test_cluster_time_cmd_started_cb); - mongoc_apm_set_command_succeeded_cb (callbacks, - test_cluster_time_cmd_succeeded_cb); - - if (pooled) { - pool = test_framework_client_pool_new (); - mongoc_client_pool_set_apm_callbacks ( - pool, callbacks, &cluster_time_test); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - mongoc_client_set_apm_callbacks (client, callbacks, &cluster_time_test); - } - - r = command (client, &error); - ASSERT_OR_PRINT (r, error); - ASSERT_CMPINT (cluster_time_test.calls, ==, 1); - - /* repeat */ - r = command (client, &error); - ASSERT_OR_PRINT (r, error); - ASSERT_CMPINT (cluster_time_test.calls, ==, 2); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_apm_callbacks_destroy (callbacks); - bson_destroy (cluster_time_test.command); - bson_destroy (cluster_time_test.cluster_time); -} - - -static bool -command_simple (mongoc_client_t *client, bson_error_t *error) -{ - return mongoc_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, error); -} - - -static void -test_cluster_time_command_simple_single (void) -{ - _test_cluster_time (false, command_simple); -} - - -static void -test_cluster_time_command_simple_pooled (void) -{ - _test_cluster_time (true, command_simple); -} - - -/* test the deprecated mongoc_client_command function with $clusterTime */ -static bool -client_command (mongoc_client_t *client, bson_error_t *error) -{ - mongoc_cursor_t *cursor; - const bson_t *doc; - bool r; - - cursor = mongoc_client_command (client, - "test", - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{'ping': 1}"), - NULL, - NULL); - - mongoc_cursor_next (cursor, &doc); - r = !mongoc_cursor_error (cursor, error); - mongoc_cursor_destroy (cursor); - return r; -} - - -static void -test_cluster_time_command_single (void) -{ - _test_cluster_time (false, client_command); -} - - -static void -test_cluster_time_command_pooled (void) -{ - _test_cluster_time (true, client_command); -} - - -/* test modern mongoc_client_read_command_with_opts with $clusterTime */ -static bool -client_command_with_opts (mongoc_client_t *client, bson_error_t *error) -{ - /* any of the with_opts command functions should work */ - return mongoc_client_read_command_with_opts ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, error); -} - - -static void -test_cluster_time_command_with_opts_single (void) -{ - _test_cluster_time (false, client_command_with_opts); -} - - -static void -test_cluster_time_command_with_opts_pooled (void) -{ - _test_cluster_time (true, client_command_with_opts); -} - - -/* test aggregate with $clusterTime */ -static bool -aggregate (mongoc_client_t *client, bson_error_t *error) -{ - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bool r; - - collection = mongoc_client_get_collection (client, "test", "collection"); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson ("{}"), NULL, NULL); - - mongoc_cursor_next (cursor, &doc); - r = !mongoc_cursor_error (cursor, error); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - return r; -} - - -static void -test_cluster_time_aggregate_single (void) -{ - _test_cluster_time (false, aggregate); -} - - -static void -test_cluster_time_aggregate_pooled (void) -{ - _test_cluster_time (true, aggregate); -} - - -/* test queries with $clusterTime */ -static bool -cursor_next (mongoc_client_t *client, bson_error_t *error) -{ - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bool r; - - collection = get_test_collection (client, "test_cluster_time_cursor"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{'ping': 1}"), NULL, NULL); - - mongoc_cursor_next (cursor, &doc); - r = !mongoc_cursor_error (cursor, error); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - return r; -} - - -static void -test_cluster_time_cursor_single (void) -{ - _test_cluster_time (false, cursor_next); -} - - -static void -test_cluster_time_cursor_pooled (void) -{ - _test_cluster_time (true, cursor_next); -} - - -/* test inserts with $clusterTime */ -static bool -insert (mongoc_client_t *client, bson_error_t *error) -{ - mongoc_collection_t *collection; - bool r; - - collection = get_test_collection (client, "test_cluster_time_cursor"); - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), NULL, NULL, error); - - mongoc_collection_destroy (collection); - - return r; -} - - -static void -test_cluster_time_insert_single (void) -{ - _test_cluster_time (false, insert); -} - - -static void -test_cluster_time_insert_pooled (void) -{ - _test_cluster_time (true, insert); -} - - -static void -replies_with_cluster_time (request_t *request, - int t, - int i, - const char *docs_json) -{ - char *quotes_replaced; - bson_t doc; - bson_error_t error; - bool r; - - BSON_ASSERT (request); - - if (docs_json) { - quotes_replaced = single_quotes_to_double (docs_json); - r = bson_init_from_json (&doc, quotes_replaced, -1, &error); - bson_free (quotes_replaced); - } else { - r = bson_init_from_json (&doc, "{}", -1, &error); - } - - if (!r) { - MONGOC_WARNING ("%s", error.message); - return; - } - - BSON_APPEND_DOCUMENT ( - &doc, - "$clusterTime", - tmp_bson ("{'clusterTime': {'$timestamp': {'t': %d, 'i': %d}}, 'x': 'y'}", - t, - i)); - - mock_server_reply_multi ( - request, MONGOC_REPLY_NONE, &doc, 1, 0 /* cursor id */); - - bson_destroy (&doc); - request_destroy (request); -} - - -static request_t * -receives_with_cluster_time (mock_server_t *server, - uint32_t timestamp, - uint32_t increment, - bson_t *command) -{ - request_t *request; - const bson_t *doc; - bson_iter_t cluster_time; - uint32_t t; - uint32_t i; - - request = mock_server_receives_msg (server, 0, command); - BSON_ASSERT (request); - doc = request_get_doc (request, 0); - - BSON_ASSERT (bson_iter_init_find (&cluster_time, doc, "$clusterTime")); - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&cluster_time)); - BSON_ASSERT (bson_iter_recurse (&cluster_time, &cluster_time)); - BSON_ASSERT (bson_iter_find (&cluster_time, "clusterTime")); - BSON_ASSERT (BSON_ITER_HOLDS_TIMESTAMP (&cluster_time)); - bson_iter_timestamp (&cluster_time, &t, &i); - if (t != timestamp || i != increment) { - fprintf (stderr, - "Expected Timestamp(%d, %d), got Timestamp(%d, %d)\n", - timestamp, - increment, - t, - i); - abort (); - } - - return request; -} - - -static void -assert_ok (future_t *future, const bson_error_t *error) -{ - bool r = future_get_bool (future); - ASSERT_OR_PRINT (r, (*error)); - future_destroy (future); -} - - -static future_t * -future_ping (mongoc_client_t *client, bson_error_t *error) -{ - return future_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, error); -} - - -static void -_test_cluster_time_comparison (bool pooled) -{ - const char *ismaster = - "{'ok': 1.0, 'ismaster': true, 'msg': 'isdbgrid', 'maxWireVersion': 6}"; - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - future_t *future; - request_t *request; - bson_t *ping = tmp_bson ("{'ping': 1}"); - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - } - - future = future_ping (client, &error); - - /* timestamp is 1 */ - request = mock_server_receives_ismaster (server); - replies_with_cluster_time (request, 1, 1, ismaster); - - if (pooled) { - /* a pooled client handshakes its own connection */ - request = - mock_server_receives_msg (server, 0, tmp_bson ("{'ismaster': 1}")); - replies_with_cluster_time (request, 1, 1, ismaster); - } - - request = receives_with_cluster_time (server, 1, 1, ping); - - /* timestamp is 2, increment is 2 */ - replies_with_cluster_time (request, 2, 2, "{'ok': 1.0}"); - assert_ok (future, &error); - - future = future_ping (client, &error); - request = receives_with_cluster_time (server, 2, 2, ping); - - /* timestamp is 2, increment is only 1 */ - replies_with_cluster_time (request, 2, 1, "{'ok': 1.0}"); - assert_ok (future, &error); - - future = future_ping (client, &error); - - /* client doesn't update cluster time, since new value is less than old */ - request = receives_with_cluster_time (server, 2, 2, ping); - mock_server_replies_ok_and_destroys (request); - assert_ok (future, &error); - - if (pooled) { - /* wait for next heartbeat, it should contain newest cluster time */ - request = mock_server_receives_command (server, - "admin", - MONGOC_QUERY_SLAVE_OK, - "{'isMaster': 1, '$clusterTime': " - "{'clusterTime': {'$timestamp': " - "{'t': 2, 'i': 2}}}}"); - - replies_with_cluster_time (request, 2, 1, ismaster); - - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - /* trigger next heartbeat, it should contain newest cluster time */ - _mongoc_usleep (750 * 1000); /* 750 ms */ - future = future_ping (client, &error); - request = mock_server_receives_command (server, - "admin", - MONGOC_QUERY_SLAVE_OK, - "{'isMaster': 1, '$clusterTime': " - "{'clusterTime': {'$timestamp': " - "{'t': 2, 'i': 2}}}}"); - - replies_with_cluster_time (request, 2, 1, ismaster); - request = receives_with_cluster_time (server, 2, 2, ping); - mock_server_replies_ok_and_destroys (request); - assert_ok (future, &error); - - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -static void -test_cluster_time_comparison_single (void) -{ - _test_cluster_time_comparison (false); -} - - -static void -test_cluster_time_comparison_pooled (void) -{ - _test_cluster_time_comparison (true); -} - - -typedef future_t *(*run_command_fn_t) (mongoc_client_t *); -typedef void (*cleanup_fn_t) (future_t *); - - -typedef struct { - const char *errmsg; - bool is_not_master_err; -} test_error_msg_t; - - -test_error_msg_t errors[] = { - {"not master", true}, - {"not master or secondary", true}, - {"node is recovering", true}, - {"not master and slaveOk=false", true}, - {"replicatedToNum called but not master anymore", true}, - {"??? node is recovering ???", true}, - {"??? not master ???", true}, - {"foo", false}, - {0}}; - -/* a "not master" or "node is recovering" error marks server Unknown. - "not master" and "node is recovering" need only be substrings of the error - message. */ -static void -_test_not_master (bool pooled, - bool use_op_msg, - run_command_fn_t run_command, - cleanup_fn_t cleanup_fn) -{ - test_error_msg_t *test_error_msg; - mock_server_t *server; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - const char *cmd = "{'cmd': 1}"; - bson_error_t error; - future_t *future; - request_t *request; - mongoc_topology_description_t *td; - mongoc_server_description_t *sd; - char *reply; - - server = mock_server_with_autoismaster (use_op_msg ? 6 : 5); - mock_server_run (server); - - if (pooled) { - pool = mongoc_client_pool_new (mock_server_get_uri (server)); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - } - - td = &client->topology->description; - sd = (mongoc_server_description_t *) mongoc_set_get (td->servers, 1); - - for (test_error_msg = errors; test_error_msg->errmsg; test_error_msg++) { - /* - * successful command results in known server type - */ - future = future_client_command_simple ( - client, "test", tmp_bson (cmd), NULL, NULL, &error); - - request = mock_server_receives_request (server); - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - future_destroy (future); - - BSON_ASSERT (sd->type == MONGOC_SERVER_STANDALONE); - - /* - * command error marks server Unknown iff it's a "not master" error - */ - future = run_command (client); - request = mock_server_receives_request (server); - - reply = bson_strdup_printf ("{'ok': 0, 'errmsg': '%s'}", - test_error_msg->errmsg); - mock_server_replies_simple (request, reply); - BSON_ASSERT (!future_get_bool (future)); - - if (test_error_msg->is_not_master_err) { - BSON_ASSERT (sd->type == MONGOC_SERVER_UNKNOWN); - } else { - BSON_ASSERT (sd->type == MONGOC_SERVER_STANDALONE); - } - - bson_free (reply); - request_destroy (request); - cleanup_fn (future); - } - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mock_server_destroy (server); -} - - -static future_t * -future_command_simple (mongoc_client_t *client) -{ - return future_client_command_simple ( - client, "test", tmp_bson ("{'cmd': 1}"), NULL, NULL, NULL); -} - - -static void -function_command_simple_cleanup (future_t *future) -{ - future_destroy (future); -} - - -static void -test_not_master_single_op_query (void) -{ - _test_not_master ( - false, false, future_command_simple, function_command_simple_cleanup); -} - - -static void -test_not_master_pooled_op_query (void) -{ - _test_not_master ( - true, false, future_command_simple, function_command_simple_cleanup); -} - -static void -test_not_master_single_op_msg (void) -{ - _test_not_master ( - false, true, future_command_simple, function_command_simple_cleanup); -} - - -static void -test_not_master_pooled_op_msg (void) -{ - _test_not_master ( - true, true, future_command_simple, function_command_simple_cleanup); -} - - -/* parts must remain valid after future_command_private exits */ -mongoc_cmd_parts_t parts; - -static future_t * -future_command_private (mongoc_client_t *client) -{ - bson_error_t error; - mongoc_server_stream_t *server_stream; - - server_stream = - mongoc_cluster_stream_for_writes (&client->cluster, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - - mongoc_cmd_parts_init ( - &parts, client, "test", MONGOC_QUERY_NONE, tmp_bson ("{'cmd': 1}")); - - /* mongoc_cluster_run_command_parts will call mongoc_cmd_parts_cleanup */ - return future_cluster_run_command_parts ( - &client->cluster, server_stream, &parts, NULL, NULL); -} - - -static void -future_command_private_cleanup (future_t *future) -{ - mongoc_server_stream_t *server_stream = - future_value_get_mongoc_server_stream_ptr (future_get_param (future, 1)); - mongoc_server_stream_cleanup (server_stream); - future_destroy (future); -} - - -static void -test_not_master_auth_single_op_query (void) -{ - _test_not_master ( - false, false, future_command_private, future_command_private_cleanup); -} - - -static void -test_not_master_auth_pooled_op_query (void) -{ - _test_not_master ( - true, false, future_command_private, future_command_private_cleanup); -} - -static void -test_not_master_auth_single_op_msg (void) -{ - _test_not_master ( - false, true, future_command_private, future_command_private_cleanup); -} - - -static void -test_not_master_auth_pooled_op_msg (void) -{ - _test_not_master ( - true, true, future_command_private, future_command_private_cleanup); -} - - -typedef struct { - const char *name; - const char *q; - const char *e; - bool secondary; - bool cluster_time; -} dollar_query_test_t; - - -static bool -auto_ismaster (request_t *request, void *data) -{ - dollar_query_test_t *test; - const char *cluster_time = ""; - const char *server_type; - char *ismaster; - - if (!request->is_command || - strcasecmp (request->command_name, "ismaster") != 0) { - return false; - } - - test = (dollar_query_test_t *) data; - - if (test->cluster_time) { - cluster_time = - ", '$clusterTime': {'clusterTime': {'$timestamp': {'t': 1, 'i': 1}}}"; - } - - if (test->secondary) { - server_type = ", 'ismaster': false, 'secondary': true"; - } else { - server_type = ", 'ismaster': true, 'secondary': false"; - } - - ismaster = bson_strdup_printf ("{'ok': 1.0," - " 'minWireVersion': 0," - " 'maxWireVersion': %d," - " 'setName': 'rs' %s %s}", - WIRE_VERSION_OP_MSG, - server_type, - cluster_time); - - mock_server_replies_simple (request, ismaster); - - bson_free (ismaster); - request_destroy (request); - - return true; -} - - -static void -_test_dollar_query (void *ctx) -{ - dollar_query_test_t *test; - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_read_prefs_t *read_prefs; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - bson_error_t error; - - test = (dollar_query_test_t *) ctx; - - server = mock_server_new (); - mock_server_autoresponds (server, auto_ismaster, test, NULL); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - if (test->secondary) { - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - } else { - read_prefs = NULL; - } - - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson (test->q), - NULL, - read_prefs); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_msg (server, 0, tmp_bson (test->e)); - mock_server_replies_to_find ( - request, MONGOC_QUERY_NONE, 0, 0, "db.collection", "", true); - - BSON_ASSERT (!future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - future_destroy (future); - request_destroy (request); - mongoc_read_prefs_destroy (read_prefs); - mongoc_cursor_destroy (cursor); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -dollar_query_test_t tests[] = { - {"/Cluster/cluster_time/query/", - "{'a': 1}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " '$clusterTime': {'$exists': false}" - "}", - false, - false}, - {"/Cluster/cluster_time/query/cluster_time", - "{'a': 1}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " '$clusterTime': {'$exists': true}" - "}", - false, - true}, - {"/Cluster/cluster_time/query/secondary", - "{'a': 1}", - "{" - " 'find': 'collection', 'filter': {'a': 1}, " - " '$clusterTime': {'$exists': false}," - " '$readPreference': {'mode': 'secondary'}" - "}", - true, - false}, - {"/Cluster/cluster_time/query/cluster_time_secondary", - "{'a': 1}", - "{" - " 'find': 'collection', 'filter': {'a': 1}, " - " '$clusterTime': {'$exists': true}," - " '$readPreference': {'mode': 'secondary'}" - "}", - true, - true}, - {"/Cluster/cluster_time/dollar_query/from_user", - "{'$query': {'a': 1}}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " '$clusterTime': {'$exists': false}" - "}", - false, - false}, - {"/Cluster/cluster_time/dollar_query/from_user/cluster_time", - "{'$query': {'a': 1}}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " '$clusterTime': {'$exists': true}" - "}", - false, - true}, - {"/Cluster/cluster_time/dollar_query/from_user/secondary", - "{'$query': {'a': 1}}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " '$clusterTime': {'$exists': false}," - " '$readPreference': {'mode': 'secondary'}" - "}", - true, - false}, - {"/Cluster/cluster_time/dollar_query/from_user/cluster_time_secondary", - "{'$query': {'a': 1}}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " '$clusterTime': {'$exists': true}," - " '$readPreference': {'mode': 'secondary'}" - "}", - true, - true}, - {"/Cluster/cluster_time/dollar_orderby", - "{'$query': {'a': 1}, '$orderby': {'a': 1}}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " 'sort': {'a': 1}" - "}", - false, - false}, - {"/Cluster/cluster_time/dollar_orderby/secondary", - "{'$query': {'a': 1}, '$orderby': {'a': 1}}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " 'sort': {'a': 1}," - " '$clusterTime': {'$exists': false}," - " '$readPreference': {'mode': 'secondary'}" - "}", - true, - false}, - {"/Cluster/cluster_time/dollar_orderby/cluster_time", - "{'$query': {'a': 1}, '$orderby': {'a': 1}}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " 'sort': {'a': 1}," - " '$clusterTime': {'$exists': true}" - "}", - false, - true}, - {"/Cluster/cluster_time/dollar_orderby/cluster_time_secondary", - "{'$query': {'a': 1}, '$orderby': {'a': 1}}", - "{" - " 'find': 'collection', 'filter': {'a': 1}," - " 'sort': {'a': 1}," - " '$clusterTime': {'$exists': true}," - " '$readPreference': {'mode': 'secondary'}" - "}", - true, - true}, - {NULL}}; - -static void -_test_cluster_ismaster_fails (bool hangup) -{ - mock_server_t *mock_server; - mongoc_uri_t *uri; - mongoc_server_description_t *sd; - mongoc_client_pool_t *pool; - mongoc_client_t *client; - request_t *request; - future_t *future; - bson_error_t error; - int autoresponder_id; - - mock_server = mock_server_new (); - autoresponder_id = - mock_server_auto_ismaster (mock_server, "{ 'isMaster': 1.0 }"); - mock_server_run (mock_server); - uri = mongoc_uri_copy (mock_server_get_uri (mock_server)); - /* increase heartbeatFrequencyMS to prevent background server selection. */ - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 99999); - pool = mongoc_client_pool_new (uri); - mongoc_client_pool_set_error_api (pool, 2); - mongoc_uri_destroy (uri); - client = mongoc_client_pool_pop (pool); - /* do server selection to add this server to the topology. this does not add - * a cluster node for this server. */ - sd = mongoc_client_select_server (client, false, NULL, NULL); - BSON_ASSERT (sd); - mongoc_server_description_destroy (sd); - mock_server_remove_autoresponder (mock_server, autoresponder_id); - /* now create a cluster node by running a command. */ - future = future_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - /* the client adds a cluster node, creating a stream to the server, and then - * sends an ismaster request. */ - request = mock_server_receives_ismaster (mock_server); - /* CDRIVER-2576: the server replies with an error, so - * _mongoc_stream_run_ismaster returns NULL, which - * _mongoc_cluster_run_ismaster must check. */ - - if (hangup) { - capture_logs (true); /* suppress "failed to buffer" warning */ - mock_server_hangs_up (request); - BSON_ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "socket err"); - } else { - mock_server_replies_simple (request, "{'ok': 0, 'code': 123}"); - BSON_ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_SERVER, 123, "Unknown command error"); - } - - request_destroy (request); - future_destroy (future); - mock_server_destroy (mock_server); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); -} - -static void -test_cluster_ismaster_fails (void) -{ - _test_cluster_ismaster_fails (false); -} - - -static void -test_cluster_ismaster_hangup (void) -{ - _test_cluster_ismaster_fails (true); -} - -static void -_test_cluster_command_error (bool use_op_msg) -{ - mock_server_t *server; - mongoc_client_t *client; - bson_error_t err; - request_t *request; - future_t *future; - - if (use_op_msg) { - server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG); - } else { - server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG - 1); - } - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - future = future_client_command_simple (client, - "db", - tmp_bson ("{'ping': 1}"), - NULL /* opts */, - NULL /* read prefs */, - &err); - if (use_op_msg) { - request = mock_server_receives_msg ( - server, MONGOC_QUERY_NONE, tmp_bson ("{'ping': 1}")); - } else { - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - } - mock_server_hangs_up (request); - BSON_ASSERT (!future_get_bool (future)); - future_destroy (future); - request_destroy (request); - if (use_op_msg) { - /* _mongoc_buffer_append_from_stream, used by opmsg gives more detail. */ - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to send \"ping\" command with database " - "\"db\": Failed to read 4 bytes: socket error or " - "timeout"); - } else { - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "Failed to send \"ping\" command with database " - "\"db\": socket error or timeout"); - } - mock_server_destroy (server); - mongoc_client_destroy (client); -} - -static void -test_cluster_command_error_op_msg () -{ - _test_cluster_command_error (true); -} - -static void -test_cluster_command_error_op_query () -{ - _test_cluster_command_error (false); -} - -static void -test_advanced_cluster_time_not_sent_to_standalone (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_client_session_t *cs; - bson_t opts = BSON_INITIALIZER; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - bson_error_t error; - - server = mock_server_new (); - mock_server_auto_endsessions (server); - mock_server_auto_ismaster (server, - "{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 0," - " 'maxWireVersion': 6," - " 'logicalSessionTimeoutMinutes': 30}"); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - cs = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (cs, error); - - mongoc_client_session_advance_cluster_time ( - cs, tmp_bson ("{'clusterTime': {'$timestamp': {'t': 1, 'i': 1}}}")); - - ASSERT_OR_PRINT (mongoc_client_session_append (cs, &opts, &error), error); - - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), &opts, NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_msg ( - server, - 0, - tmp_bson ("{" - " 'find': 'collection', 'filter': {}," - " '$clusterTime': {'$exists': false}" - "}")); - mock_server_replies_to_find ( - request, MONGOC_QUERY_NONE, 0, 0, "db.collection", "", true); - - BSON_ASSERT (!future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_session_destroy (cs); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -void -test_cluster_install (TestSuite *suite) -{ - dollar_query_test_t *p = tests; - - while (p->name) { - TestSuite_AddFull (suite, - p->name, - _test_dollar_query, - NULL, - p, - TestSuite_CheckMockServerAllowed); - - p++; - } - - 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", - test_cluster_node_disconnect_single, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Cluster/disconnect/pooled", - test_cluster_node_disconnect_pooled, - NULL, - NULL, - test_framework_skip_if_slow); - 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", - 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/single", - test_cluster_time_command_single); - TestSuite_AddLive (suite, - "/Cluster/cluster_time/command/pooled", - test_cluster_time_command_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); - 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/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/insert/single", - test_cluster_time_insert_single); - TestSuite_AddLive (suite, - "/Cluster/cluster_time/insert/pooled", - test_cluster_time_insert_pooled); - TestSuite_AddMockServerTest (suite, - "/Cluster/cluster_time/comparison/single", - test_cluster_time_comparison_single, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Cluster/cluster_time/comparison/pooled", - test_cluster_time_comparison_pooled, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest ( - suite, - "/Cluster/cluster_time/advanced_not_sent_to_standalone", - test_advanced_cluster_time_not_sent_to_standalone, - test_framework_skip_if_no_crypto); - TestSuite_AddMockServerTest (suite, - "/Cluster/not_master/single/op_query", - test_not_master_single_op_query, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Cluster/not_master/pooled/op_query", - test_not_master_pooled_op_query, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Cluster/not_master/single/op_msg", - test_not_master_single_op_msg, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Cluster/not_master/pooled/op_msg", - test_not_master_pooled_op_msg, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Cluster/not_master_auth/single/op_query", - test_not_master_auth_single_op_query, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Cluster/not_master_auth/pooled/op_query", - test_not_master_auth_pooled_op_query, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Cluster/not_master_auth/single/op_msg", - test_not_master_auth_single_op_msg, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Cluster/not_master_auth/pooled/op_msg", - test_not_master_auth_pooled_op_msg, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest ( - suite, "/Cluster/ismaster_fails", test_cluster_ismaster_fails); - TestSuite_AddMockServerTest ( - suite, "/Cluster/ismaster_hangup", test_cluster_ismaster_hangup); - TestSuite_AddMockServerTest (suite, - "/Cluster/command_error/op_msg", - test_cluster_command_error_op_msg); - TestSuite_AddMockServerTest (suite, - "/Cluster/command_error/op_query", - test_cluster_command_error_op_query); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-collection-find-with-opts.c b/lib/mongoc/libmongoc/tests/test-mongoc-collection-find-with-opts.c deleted file mode 100644 index a0835e5eb2998155b10c489f654e2f9ff843e4e1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-collection-find-with-opts.c +++ /dev/null @@ -1,1042 +0,0 @@ -#include <mongoc/mongoc.h> -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-client-private.h" - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "test-libmongoc.h" -#include "mock_server/mock-rs.h" - - -typedef struct { - const char *filter; - bson_t *filter_bson; - const char *opts; - bson_t *opts_bson; - mongoc_read_prefs_t *read_prefs; - const char *expected_find_command; - const char *expected_op_query; - const char *expected_op_query_projection; - int32_t expected_n_return; - mongoc_query_flags_t expected_flags; - uint32_t expected_skip; -} test_collection_find_with_opts_t; - - -typedef request_t *(*check_request_fn_t) ( - mock_server_t *server, test_collection_find_with_opts_t *test_data); - - -/*-------------------------------------------------------------------------- - * - * _test_collection_op_query_or_find_command -- - * - * Start a mock server with @max_wire_version, connect a client, and - * execute a query with @test_data->filter and @test_data->opts. Use - * the @check_request_fn callback to verify the client formatted the - * query correctly, and @reply_json to respond to the client. - * - *-------------------------------------------------------------------------- - */ - -static void -_test_collection_op_query_or_find_command ( - test_collection_find_with_opts_t *test_data, - check_request_fn_t check_request_fn, - const char *reply_json, - int32_t max_wire_version) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - future_t *future; - request_t *request; - const bson_t *doc; - - server = mock_server_with_autoismaster (max_wire_version); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find_with_opts (collection, - test_data->filter_bson, - test_data->opts_bson, - test_data->read_prefs); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - future = future_cursor_next (cursor, &doc); - request = check_request_fn (server, test_data); - ASSERT (request); - mock_server_replies_simple (request, reply_json); - ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static request_t * -_check_op_query (mock_server_t *server, - test_collection_find_with_opts_t *test_data) -{ - mongoc_query_flags_t flags; - request_t *request; - const bson_t *doc; - bson_iter_t iter; - uint32_t len; - const uint8_t *data; - bson_t query; - - /* Server Selection Spec: all queries to standalone set slaveOk. */ - flags = test_data->expected_flags | MONGOC_QUERY_SLAVE_OK; - - request = - mock_server_receives_query (server, - "db.collection", - flags, - test_data->expected_skip, - test_data->expected_n_return, - test_data->expected_op_query, - test_data->expected_op_query_projection); - - ASSERT (request); - - /* check that nothing unexpected is in $query */ - if (bson_empty (test_data->filter_bson)) { - doc = request_get_doc (request, 0); - - if (bson_iter_init_find (&iter, doc, "$query")) { - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - bson_iter_document (&iter, &len, &data); - bson_init_static (&query, data, (size_t) len); - ASSERT (bson_empty (&query)); - } - } - - return request; -} - - -static void -_test_collection_op_query (test_collection_find_with_opts_t *test_data) -{ - _test_collection_op_query_or_find_command ( - test_data, _check_op_query, "{}", 3 /* wire version */); -} - - -static request_t * -_check_find_command (mock_server_t *server, - test_collection_find_with_opts_t *test_data) -{ - /* Server Selection Spec: all queries to standalone set slaveOk. - * - * Find, getMore And killCursors Commands Spec: "When sending a find command - * rather than a legacy OP_QUERY find only the slaveOk flag is honored". - */ - return mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, test_data->expected_find_command); -} - - -static void -_test_collection_find_command (test_collection_find_with_opts_t *test_data) - -{ - _test_collection_op_query_or_find_command (test_data, - _check_find_command, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{}]}}", - 4 /* max wire version */); -} - - -static void -_test_collection_find_with_opts (test_collection_find_with_opts_t *test_data) -{ - BSON_ASSERT (test_data->expected_find_command); - - test_data->filter_bson = tmp_bson (test_data->filter); - test_data->opts_bson = tmp_bson (test_data->opts); - - _test_collection_op_query (test_data); - _test_collection_find_command (test_data); -} - - -static void -test_dollar_or (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.filter = "{'$or': [{'_id': 1}]}"; - test_data.expected_op_query = " {'$or': [{'_id': 1}]}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'$or': [{'_id': 1}]}}"; - - _test_collection_find_with_opts (&test_data); -} - - -/* test '$or': [{'_id': 1}], 'snapshot': true - * we just use snapshot to prove that an option can be passed - * alongside '$or' - */ -static void -test_snapshot_dollar_or (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.filter = "{'$or': [{'_id': 1}]}"; - test_data.opts = "{'snapshot': true}"; - test_data.expected_op_query = - "{'$query': {'$or': [{'_id': 1}]}, '$snapshot': true}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'$or': [{'_id': 1}]}," - " 'snapshot': true}"; - - _test_collection_find_with_opts (&test_data); -} - - -/* test that we can query for a document by a key named "filter" */ -static void -test_key_named_filter (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.filter = "{'filter': 2}"; - test_data.expected_op_query = " {'filter': 2}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'filter': 2}}"; - _test_collection_find_with_opts (&test_data); -} - - -/* test 'filter': {'filter': {'i': 2}} */ -static void -test_op_query_subdoc_named_filter (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.filter = "{'filter': {'i': 2}}"; - test_data.expected_op_query = " {'filter': {'i': 2}}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'filter': {'i': 2}}}"; - _test_collection_find_with_opts (&test_data); -} - - -/* test 'filter': {'filter': {'i': 2}}, 'snapshot': true - * we just use snapshot to prove that an option can be passed - * alongside 'filter' - */ -static void -test_find_cmd_subdoc_named_filter_with_option (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.filter = "{'filter': {'i': 2}}"; - test_data.opts = "{'snapshot': true}"; - test_data.expected_op_query = - "{'$query': {'filter': {'i': 2}}, '$snapshot': true}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'filter': {'i': 2}}, " - " 'snapshot': true}"; - - _test_collection_find_with_opts (&test_data); -} - - -static void -test_newoption (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.filter = "{'_id': 1}"; - test_data.opts = "{'newOption': true}"; - test_data.expected_op_query = "{'$query': {'_id': 1}, '$newOption': true}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'_id': 1}, 'newOption': true}"; - - _test_collection_find_with_opts (&test_data); -} - - -static void -test_sort (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'sort': {'_id': -1}}"; - test_data.expected_op_query = "{'$query': {}, '$orderby': {'_id': -1}}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'sort': {'_id': -1}}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_fields (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'projection': {'_id': 0, 'b': 1}}"; - test_data.expected_op_query_projection = "{'_id': 0, 'b': 1}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'projection': {'_id': 0, 'b': 1}}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_slice (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'projection': {'array': {'$slice': 10}}}"; - test_data.expected_op_query_projection = "{'array': {'$slice': 10}}"; - test_data.expected_find_command = - "{'find': 'collection', " - " 'filter': {}," - " 'projection': {'array': {'$slice': 10}}}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_int_modifiers (void) -{ - const char *modifiers[] = { - "maxScan", "maxTimeMS", - }; - - const char *mod; - size_t i; - char *opts; - char *query; - char *find_command; - test_collection_find_with_opts_t test_data = {0}; - - for (i = 0; i < sizeof (modifiers) / sizeof (const char *); i++) { - mod = modifiers[i]; - opts = bson_strdup_printf ("{'%s': {'$numberLong': '9999'}}", mod); - query = bson_strdup_printf ("{'$query': {}," - " '$%s': {'$numberLong': '9999'}}", - mod); - - /* find command has same modifier, without the $-prefix */ - find_command = bson_strdup_printf ("{'find': 'collection', 'filter': {}," - " '%s': {'$numberLong': '9999'}}", - mod); - - test_data.opts = opts; - test_data.expected_op_query = query; - test_data.expected_find_command = find_command; - _test_collection_find_with_opts (&test_data); - - bson_free (opts); - bson_free (query); - bson_free (find_command); - } -} - - -static void -test_index_spec_modifiers (void) -{ - const char *modifiers[] = { - "hint", "min", "max", - }; - - const char *mod; - size_t i; - char *opts; - char *query; - char *find_command; - test_collection_find_with_opts_t test_data = {0}; - - for (i = 0; i < sizeof (modifiers) / sizeof (const char *); i++) { - mod = modifiers[i]; - opts = bson_strdup_printf ("{'%s': {'_id': 1}}", mod); - /* OP_QUERY modifiers use $-prefix: $hint, $min, $max */ - query = bson_strdup_printf ("{'$query': {}, '$%s': {'_id': 1}}", mod); - - /* find command options have no $-prefix: hint, min, max */ - find_command = bson_strdup_printf ( - "{'find': 'collection', 'filter': {}, '%s': {'_id': 1}}", mod); - - test_data.opts = opts; - test_data.expected_op_query = query; - test_data.expected_find_command = find_command; - _test_collection_find_with_opts (&test_data); - - bson_free (opts); - bson_free (query); - bson_free (find_command); - } -} - - -static void -test_comment (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'comment': 'COMMENT'}"; - test_data.expected_op_query = "{'$query': {}, '$comment': 'COMMENT'}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'comment': 'COMMENT'}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_snapshot (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'snapshot': true}"; - test_data.expected_op_query = "{'$query': {}, '$snapshot': true}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'snapshot': true}"; - _test_collection_find_with_opts (&test_data); -} - - -/* showRecordId becomes $showDiskLoc */ -static void -test_diskloc (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'showRecordId': true}"; - test_data.expected_op_query = "{'$query': {}, '$showDiskLoc': true}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'showRecordId': true}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_returnkey (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'returnKey': true}"; - test_data.expected_op_query = "{'$query': {}, '$returnKey': true}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'returnKey': true}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_skip (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.expected_skip = 1; - test_data.opts = "{'skip': {'$numberLong': '1'}}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'skip': {'$numberLong': '1'}}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_batch_size (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'batchSize': {'$numberLong': '2'}}"; - test_data.expected_n_return = 2; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'batchSize': {'$numberLong': '2'}}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_limit (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'limit': {'$numberLong': '2'}}"; - test_data.expected_n_return = 2; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'limit': {'$numberLong': '2'}}"; - _test_collection_find_with_opts (&test_data); -} - - -static void -test_singlebatch (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'limit': {'$numberLong': '2'}, 'singleBatch': true}"; - test_data.expected_n_return = -2; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, " - " 'singleBatch': true, 'limit': {'$numberLong': '2'}}"; - - _test_collection_find_with_opts (&test_data); -} - -static void -test_singlebatch_no_limit (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'singleBatch': true}"; - /* singleBatch doesn't affect OP_QUERY with limit 0, nToReturn is still 0 */ - test_data.expected_n_return = 0; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'singleBatch': true}"; - - _test_collection_find_with_opts (&test_data); -} - - -static void -test_unrecognized_dollar_option (void) -{ - test_collection_find_with_opts_t test_data = {0}; - - test_data.opts = "{'dumb': 1}"; - test_data.expected_op_query = "{'$query': {}, '$dumb': 1}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'dumb': 1}"; - - _test_collection_find_with_opts (&test_data); -} - - -static void -test_query_flags (void) -{ - int i; - char *opts; - char *find_cmd; - test_collection_find_with_opts_t test_data = {0}; - - typedef struct { - mongoc_query_flags_t flag; - const char *json_fragment; - } flag_and_name_t; - - /* slaveok is not supported as an option, exhaust is tested separately */ - flag_and_name_t flags_and_frags[] = { - {MONGOC_QUERY_TAILABLE_CURSOR, "'tailable': true"}, - {MONGOC_QUERY_OPLOG_REPLAY, "'oplogReplay': true"}, - {MONGOC_QUERY_NO_CURSOR_TIMEOUT, "'noCursorTimeout': true"}, - {MONGOC_QUERY_PARTIAL, "'allowPartialResults': true"}, - {MONGOC_QUERY_TAILABLE_CURSOR | MONGOC_QUERY_AWAIT_DATA, - "'tailable': true, 'awaitData': true"}, - }; - - for (i = 0; i < (sizeof flags_and_frags) / (sizeof (flag_and_name_t)); i++) { - opts = bson_strdup_printf ("{%s}", flags_and_frags[i].json_fragment); - find_cmd = bson_strdup_printf ("{'find': 'collection', 'filter': {}, %s}", - flags_and_frags[i].json_fragment); - - test_data.opts = opts; - test_data.expected_flags = flags_and_frags[i].flag; - test_data.expected_find_command = find_cmd; - - _test_collection_find_with_opts (&test_data); - - bson_free (find_cmd); - bson_free (opts); - } -} - - -static void -test_exhaust (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - request_t *request; - future_t *future; - const bson_t *doc; - bson_error_t error; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), tmp_bson ("{'exhaust': true}"), NULL); - - future = future_cursor_next (cursor, &doc); - - /* Find, getMore and killCursors commands spec: "The find command does not - * support the exhaust flag from OP_QUERY. Drivers that support exhaust MUST - * fallback to existing OP_QUERY wire protocol messages." - */ - request = mock_server_receives_request (server); - mock_server_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK | MONGOC_QUERY_EXHAUST, - 0, - 0, - "db.collection", - "{}", - false /* is_command */); - - ASSERT (future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_getmore_cmd_await (void) -{ - bson_t *opts; - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - - opts = tmp_bson ("{'tailable': true," - " 'awaitData': true," - " 'maxAwaitTimeMS': {'$numberLong': '9999'}}"); - - /* - * "find" command - */ - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), opts, NULL); - - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'collection'," - " 'filter': {}," - " 'maxTimeMS': {'$exists': false}," - " 'maxAwaitTimeMS': {'$exists': false}}"); - - ASSERT (request); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '123'}," - " 'ns': 'db.collection'," - " 'firstBatch': [{}]}}"); - - ASSERT (future_get_bool (future)); - request_destroy (request); - future_destroy (future); - - /* - * "getMore" command - */ - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'getMore': {'$numberLong': '123'}," - " 'collection': 'collection'," - " 'maxAwaitTimeMS': {'$exists': false}," - " 'maxTimeMS': {'$numberLong': '9999'}}"); - - ASSERT (request); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '0'}," - " 'ns': 'db.collection'," - " 'nextBatch': [{}]}}"); - - ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_find_w_server_id (void) -{ - mock_rs_t *rs; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *opts; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - - rs = mock_rs_with_autoismaster (WIRE_VERSION_MIN /* wire version */, - true /* has primary */, - 1 /* secondary */, - 0 /* arbiters */); - - mock_rs_run (rs); - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - /* use serverId instead of prefs to select the secondary */ - opts = tmp_bson ("{'serverId': 2}"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), opts, NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_rs_receives_query ( - rs, "db.collection", MONGOC_QUERY_SLAVE_OK, 0, 0, "{}", NULL); - - ASSERT (mock_rs_request_is_to_secondary (rs, request)); - mock_rs_replies_simple (request, "{}"); - ASSERT_OR_PRINT (future_get_bool (future), cursor->error); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_rs_destroy (rs); -} - - -static void -test_find_cmd_w_server_id (void) -{ - mock_rs_t *rs; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *opts; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - bson_error_t error; - - rs = mock_rs_with_autoismaster (WIRE_VERSION_READ_CONCERN, - true /* has primary */, - 1 /* secondary */, - 0 /* arbiters */); - - mock_rs_run (rs); - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - /* use serverId instead of prefs to select the secondary */ - opts = tmp_bson ("{'serverId': 2, 'readConcern': {'level': 'local'}}"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), opts, NULL); - - future = future_cursor_next (cursor, &doc); - - /* recognized that wire version is recent enough for readConcern */ - request = mock_rs_receives_command (rs, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'collection', " - " 'filter': {}," - " 'readConcern': {'level': 'local'}," - " 'serverId': {'$exists': false}}"); - - ASSERT (mock_rs_request_is_to_secondary (rs, request)); - mock_rs_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{}]}}"); - - ASSERT_OR_PRINT (future_get_bool (future), error); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_rs_destroy (rs); -} - - -static void -test_find_w_server_id_sharded (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *opts; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - opts = tmp_bson ("{'serverId': 1}"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), opts, NULL); - - future = future_cursor_next (cursor, &doc); - - /* does NOT set slave ok, since this is a sharded topology */ - request = mock_server_receives_query ( - server, "db.collection", MONGOC_QUERY_NONE, 0, 0, "{}", NULL); - - mock_server_replies_simple (request, "{}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_find_cmd_w_server_id_sharded (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *opts; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (WIRE_VERSION_READ_CONCERN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - opts = tmp_bson ("{'serverId': 1, 'readConcern': {'level': 'local'}}"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), opts, NULL); - - future = future_cursor_next (cursor, &doc); - - /* recognized that wire version is recent enough for readConcern */ - /* does NOT set slave ok, since this is a sharded topology */ - request = mock_server_receives_command (server, - "db", - MONGOC_QUERY_NONE, - "{'find': 'collection', " - " 'filter': {}," - " 'readConcern': {'level': 'local'}," - " 'serverId': {'$exists': false}}"); - - mock_rs_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{}]}}"); - - ASSERT_OR_PRINT (future_get_bool (future), error); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_server_id_option (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *q; - bson_error_t error; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - collection = mongoc_client_get_collection (client, "db", "collection"); - q = tmp_bson (NULL); - cursor = mongoc_collection_find_with_opts ( - collection, q, tmp_bson ("{'serverId': 'foo'}"), NULL); - - ASSERT_ERROR_CONTAINS (cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "must be an integer"); - - mongoc_cursor_destroy (cursor); - cursor = mongoc_collection_find_with_opts ( - collection, q, tmp_bson ("{'serverId': 0}"), NULL); - - ASSERT_ERROR_CONTAINS (cursor->error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "must be >= 1"); - - mongoc_cursor_destroy (cursor); - cursor = mongoc_collection_find_with_opts ( - collection, q, tmp_bson ("{'serverId': 1}"), NULL); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_find_with_opts_collation_error (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *q; - bson_t *opts; - const bson_t *doc; - bson_error_t error; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - collection = mongoc_client_get_collection (client, "db", "collection"); - q = tmp_bson (NULL); - opts = tmp_bson ("{'collation': {'locale': 'is'}}"); - cursor = mongoc_collection_find_with_opts (collection, q, opts, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - ASSERT (false); - } - - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -void -test_collection_find_with_opts_install (TestSuite *suite) -{ - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/dollar_or", test_dollar_or); - TestSuite_AddMockServerTest (suite, - "/Collection/find_with_opts/snapshot_dollar_or", - test_snapshot_dollar_or); - TestSuite_AddMockServerTest (suite, - "/Collection/find_with_opts/key_named_filter", - test_key_named_filter); - TestSuite_AddMockServerTest ( - suite, - "/Collection/find_with_opts/query/subdoc_named_filter", - test_op_query_subdoc_named_filter); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/newoption", test_newoption); - TestSuite_AddMockServerTest ( - suite, - "/Collection/find_with_opts/cmd/subdoc_named_filter", - test_find_cmd_subdoc_named_filter_with_option); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/orderby", test_sort); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/fields", test_fields); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/slice", test_slice); - TestSuite_AddMockServerTest (suite, - "/Collection/find_with_opts/modifiers/integer", - test_int_modifiers); - TestSuite_AddMockServerTest ( - suite, - "/Collection/find_with_opts/modifiers/index_spec", - test_index_spec_modifiers); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/comment", test_comment); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/modifiers/bool", test_snapshot); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/showdiskloc", test_diskloc); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/returnkey", test_returnkey); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/skip", test_skip); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/batch_size", test_batch_size); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/limit", test_limit); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/singlebatch", test_singlebatch); - TestSuite_AddMockServerTest ( - suite, - "/Collection/find_with_opts/singlebatch/no_limit", - test_singlebatch_no_limit); - TestSuite_AddMockServerTest ( - suite, - "/Collection/find_with_opts/unrecognized_dollar", - test_unrecognized_dollar_option); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/flags", test_query_flags); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/exhaust", test_exhaust); - TestSuite_AddMockServerTest (suite, - "/Collection/find_with_opts/await/getmore_cmd", - test_getmore_cmd_await); - TestSuite_AddMockServerTest ( - suite, "/Collection/find_with_opts/server_id", test_find_w_server_id); - TestSuite_AddMockServerTest (suite, - "/Collection/find_cmd_with_opts/server_id", - test_find_cmd_w_server_id); - TestSuite_AddMockServerTest (suite, - "/Collection/find_with_opts/server_id/sharded", - test_find_w_server_id_sharded); - TestSuite_AddMockServerTest ( - suite, - "/Collection/find_cmd_with_opts/server_id/sharded", - test_find_cmd_w_server_id_sharded); - TestSuite_AddLive (suite, - "/Collection/find_with_opts/server_id/option", - test_server_id_option); - TestSuite_AddFull (suite, - "/Collection/find_with_opts/collation/error", - test_find_with_opts_collation_error, - NULL, - NULL, - test_framework_skip_if_max_wire_version_more_than_4); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-collection-find.c b/lib/mongoc/libmongoc/tests/test-mongoc-collection-find.c deleted file mode 100644 index 592d260acda6c7399326f7fc1540562f2e821551..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-collection-find.c +++ /dev/null @@ -1,1259 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-cursor-private.h> -#include <mongoc/mongoc-client-private.h> - -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "test-conveniences.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" - - -typedef struct { - /* if do_live is true (the default), actually query the server using the - * appropriate wire protocol: either OP_QUERY or a "find" command */ - bool do_live; - int32_t max_wire_version; - const char *docs; - bson_t *docs_bson; - const char *query_input; - bson_t *query_bson; - const char *fields; - bson_t *fields_bson; - const char *expected_find_command; - const char *expected_op_query; - int32_t n_return; - const char *expected_result; - bson_t *expected_result_bson; - uint32_t skip; - int32_t limit; - uint32_t batch_size; - mongoc_query_flags_t flags; - mongoc_read_prefs_t *read_prefs; - const char *filename; - int lineno; - const char *funcname; - uint32_t n_results; -} test_collection_find_t; - - -#define TEST_COLLECTION_FIND_INIT \ - { \ - true, INT32_MAX \ - } - - -static void -_insert_test_docs (mongoc_collection_t *collection, const bson_t *docs) -{ - bson_iter_t iter; - uint32_t len; - const uint8_t *data; - bson_t doc; - bool r; - bson_error_t error; - - bson_iter_init (&iter, docs); - while (bson_iter_next (&iter)) { - bson_iter_document (&iter, &len, &data); - BSON_ASSERT (bson_init_static (&doc, data, len)); - r = mongoc_collection_insert_one (collection, &doc, NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - } -} - - -static void -_check_cursor (mongoc_cursor_t *cursor, test_collection_find_t *test_data) -{ - const bson_t *doc; - bson_t actual_result = BSON_INITIALIZER; - char str[16]; - const char *key; - uint32_t i = 0; - bson_error_t error; - - while (mongoc_cursor_next (cursor, &doc)) { - bson_uint32_to_string (i, &key, str, sizeof str); - bson_append_document (&actual_result, key, -1, doc); - i++; - } - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - if (i != test_data->n_results) { - fprintf (stderr, "expect %d results, got %d\n", test_data->n_results, i); - abort (); - } - - ASSERT (match_json (&actual_result, - false /* is_command */, - test_data->filename, - test_data->lineno, - test_data->funcname, - test_data->expected_result)); - - bson_destroy (&actual_result); -} - - -static void -_test_collection_find_live (test_collection_find_t *test_data) - -{ - mongoc_client_t *client; - mongoc_database_t *database; - char *collection_name; - mongoc_collection_t *collection; - char *drop_cmd; - bool r; - bson_error_t error; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - database = mongoc_client_get_database (client, "test"); - collection_name = gen_collection_name ("test"); - collection = mongoc_database_create_collection ( - database, - collection_name, - tmp_bson ("{'capped': true, 'size': 10000}"), - &error); - - ASSERT_OR_PRINT (collection, error); - - _insert_test_docs (collection, test_data->docs_bson); - - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - test_data->skip, - test_data->limit, - test_data->batch_size, - test_data->query_bson, - test_data->fields_bson, - test_data->read_prefs); - - _check_cursor (cursor, test_data); - - drop_cmd = bson_strdup_printf ("{'drop': '%s'}", collection_name); - r = mongoc_client_command_simple ( - client, "test", tmp_bson (drop_cmd), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - bson_free (drop_cmd); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - bson_free (collection_name); - mongoc_client_destroy (client); -} - - -typedef request_t *(*check_request_fn_t) (mock_server_t *server, - test_collection_find_t *test_data); - - -typedef void (*reply_fn_t) (request_t *request, - test_collection_find_t *test_data); - - -/*-------------------------------------------------------------------------- - * - * _test_collection_op_query_or_find_command -- - * - * Start a mock server with @max_wire_version, connect a client, and - * execute @test_data->query. Use the @check_request_fn callback to - * verify the client formatted the query correctly, and @reply_fn to - * response to the client. Check that the client cursor's results - * match @test_data->expected_result. - * - *-------------------------------------------------------------------------- - */ - -static void -_test_collection_op_query_or_find_command (test_collection_find_t *test_data, - check_request_fn_t check_request_fn, - reply_fn_t reply_fn, - int32_t max_wire_version) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - future_t *future; - request_t *request; - const bson_t *doc; - bool cursor_next_result; - bson_t actual_result = BSON_INITIALIZER; - char str[16]; - const char *key; - uint32_t i = 0; - - if (!TestSuite_CheckMockServerAllowed ()) { - bson_destroy (&actual_result); - return; - } - - server = mock_server_with_autoismaster (max_wire_version); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find (collection, - test_data->flags, - test_data->skip, - test_data->limit, - test_data->batch_size, - test_data->query_bson, - test_data->fields_bson, - test_data->read_prefs); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - future = future_cursor_next (cursor, &doc); - request = check_request_fn (server, test_data); - ASSERT (request); - reply_fn (request, test_data); - - cursor_next_result = future_get_bool (future); - /* did we expect at least one result? */ - ASSERT (cursor_next_result == (test_data->n_results > 0)); - BSON_ASSERT (!mongoc_cursor_error (cursor, NULL)); - - if (cursor_next_result) { - bson_append_document (&actual_result, "0", -1, doc); - i++; - - /* check remaining results */ - while (mongoc_cursor_next (cursor, &doc)) { - bson_uint32_to_string (i, &key, str, sizeof str); - bson_append_document (&actual_result, key, -1, doc); - i++; - } - - BSON_ASSERT (!mongoc_cursor_error (cursor, NULL)); - } - - if (i != test_data->n_results) { - fprintf ( - stderr, "Expected %d results, got %d\n", test_data->n_results, i); - abort (); - } - - ASSERT (match_json (&actual_result, - false /* is_command */, - test_data->filename, - test_data->lineno, - test_data->funcname, - test_data->expected_result)); - - bson_destroy (&actual_result); - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static request_t * -_check_op_query (mock_server_t *server, test_collection_find_t *test_data) -{ - mongoc_query_flags_t flags; - - flags = test_data->flags | MONGOC_QUERY_SLAVE_OK; - - return mock_server_receives_query (server, - "db.collection", - flags, - test_data->skip, - test_data->n_return, - test_data->expected_op_query, - test_data->fields); -} - - -static void -_reply_to_op_query (request_t *request, test_collection_find_t *test_data) -{ - bson_t *docs; - int i; - bson_iter_t iter; - uint32_t len; - const uint8_t *data; - - docs = bson_malloc (test_data->n_results * sizeof (bson_t)); - bson_iter_init (&iter, test_data->expected_result_bson); - - for (i = 0; i < test_data->n_results; i++) { - bson_iter_next (&iter); - bson_iter_document (&iter, &len, &data); - BSON_ASSERT (bson_init_static (&docs[i], data, len)); - } - - mock_server_reply_multi (request, - MONGOC_REPLY_NONE, - docs, - test_data->n_results, - 0 /* cursor_id */); - - bson_free (docs); -} - - -static void -_test_collection_op_query (test_collection_find_t *test_data) -{ - _test_collection_op_query_or_find_command ( - test_data, _check_op_query, _reply_to_op_query, 3 /* wire version */); -} - - -static request_t * -_check_find_command (mock_server_t *server, test_collection_find_t *test_data) -{ - /* Server Selection Spec: all queries to standalone set slaveOk. - * - * Find, getMore And killCursors Commands Spec: "When sending a find command - * rather than a legacy OP_QUERY find only the slaveOk flag is honored". - */ - return mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, test_data->expected_find_command); -} - - -static void -_reply_to_find_command (request_t *request, test_collection_find_t *test_data) -{ - const char *result_json; - char *reply_json; - - result_json = test_data->expected_result ? test_data->expected_result : "[]"; - - reply_json = bson_strdup_printf ("{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': %s}}", - result_json); - - mock_server_replies_simple (request, reply_json); - - bson_free (reply_json); -} - - -static void -_test_collection_find_command (test_collection_find_t *test_data) - -{ - _test_collection_op_query_or_find_command (test_data, - _check_find_command, - _reply_to_find_command, - 4 /* max wire version */); -} - - -static void -_test_collection_find (test_collection_find_t *test_data) -{ - if (test_data->query_input) { - BSON_ASSERT (test_data->expected_op_query); - } - - BSON_ASSERT (test_data->expected_find_command); - - test_data->docs_bson = tmp_bson (test_data->docs); - test_data->query_bson = tmp_bson (test_data->query_input); - test_data->fields_bson = - test_data->fields ? tmp_bson (test_data->fields) : NULL; - test_data->expected_result_bson = tmp_bson (test_data->expected_result); - test_data->n_results = bson_count_keys (test_data->expected_result_bson); - - if (test_data->do_live) { - int64_t max_version; - - test_framework_get_max_wire_version (&max_version); - if (test_data->max_wire_version >= max_version) { - _test_collection_find_live (test_data); - } - } - - _test_collection_op_query (test_data); - _test_collection_find_command (test_data); -} - - -static void -test_dollar_query (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}, {'_id': 2}]"; - test_data.query_input = "{'$query': {'_id': 1}}"; - test_data.expected_op_query = "{'_id': 1}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'_id': 1}}"; - test_data.expected_result = "[{'_id': 1}]"; - _test_collection_find (&test_data); -} - - -static void -test_dollar_or (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - - test_data.docs = "[{'_id': 1}, {'_id': 2}, {'_id': 3}]"; - test_data.query_input = "{'$or': [{'_id': 1}, {'_id': 3}]}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'$or': [{'_id': 1}, {'_id': 3}]}}"; - - test_data.expected_result = "[{'_id': 1}, {'_id': 3}]"; - _test_collection_find (&test_data); -} - - -static void -test_mixed_dollar_nondollar (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - - test_data.docs = "[{'a': 1}, {'a': 1, 'b': 2}, {'a': 2}]"; - test_data.query_input = "{'a': 1, '$or': [{'b': 1}, {'b': 2}]}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'a': 1, '$or': [{'b': 1}, {'b': 2}]}}"; - - test_data.expected_result = "[{'a': 1, 'b': 2}]"; - _test_collection_find (&test_data); -} - - -/* test that we can query for a document by a key named "filter" */ -static void -test_key_named_filter (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1, 'filter': 1}, {'_id': 2, 'filter': 2}]"; - test_data.query_input = "{'filter': 2}"; - test_data.expected_op_query = "{'filter': 2}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'filter': 2}}"; - test_data.expected_result = "[{'_id': 2, 'filter': 2}]"; - _test_collection_find (&test_data); -} - - -/* test that we can query for a document by a key named "filter" using $query */ -static void -test_key_named_filter_with_dollar_query (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1, 'filter': 1}, {'_id': 2, 'filter': 2}]"; - test_data.query_input = "{'$query': {'filter': 2}}"; - test_data.expected_op_query = "{'filter': 2}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'filter': 2}}"; - test_data.expected_result = "[{'_id': 2, 'filter': 2}]"; - _test_collection_find (&test_data); -} - - -/* test 'filter': {'i': 2} */ -static void -test_subdoc_named_filter (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = - "[{'_id': 1, 'filter': {'i': 1}}, {'_id': 2, 'filter': {'i': 2}}]"; - test_data.query_input = "{'filter': {'i': 2}}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'filter': {'i': 2}}}"; - test_data.expected_result = "[{'_id': 2, 'filter': {'i': 2}}]"; - - _test_collection_find (&test_data); -} - - -/* test '$query': {'filter': {'i': 2}} */ -static void -test_subdoc_named_filter_with_dollar_query (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = - "[{'_id': 1, 'filter': {'i': 1}}, {'_id': 2, 'filter': {'i': 2}}]"; - test_data.query_input = "{'$query': {'filter': {'i': 2}}}"; - test_data.expected_op_query = "{'filter': {'i': 2}}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'filter': {'i': 2}}}"; - test_data.expected_result = "[{'_id': 2, 'filter': {'i': 2}}]"; - _test_collection_find (&test_data); -} - - -/* test future-compatibility with a new server's find command options */ -static void -test_newoption (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.query_input = "{'$query': {'_id': 1}, '$newOption': true}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'_id': 1}, 'newOption': true}"; - - /* won't work today */ - test_data.do_live = false; - - _test_collection_find (&test_data); -} - - -static void -test_orderby (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}, {'_id': 2}]"; - test_data.query_input = "{'$query': {}, '$orderby': {'_id': -1}}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'sort': {'_id': -1}}"; - test_data.expected_result = "[{'_id': 2}, {'_id': 1}]"; - _test_collection_find (&test_data); -} - - -static void -test_fields (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1, 'a': 1, 'b': 2}]"; - test_data.fields = "{'_id': 0, 'b': 1}"; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'projection': {'_id': 0, 'b': 1}}"; - test_data.expected_result = "[{'b': 2}]"; - _test_collection_find (&test_data); -} - - -static void -_test_int_modifier (const char *mod) -{ - char *query; - char *find_command; - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - - test_data.expected_result = test_data.docs = "[{'_id': 1}]"; - - query = bson_strdup_printf ("{'$query': {}, '$%s': 9999}", mod); - - /* find command has same modifier, without the $-prefix */ - find_command = bson_strdup_printf ( - "{'find': 'collection', 'filter': {}, '%s': 9999}", mod); - - test_data.expected_op_query = test_data.query_input = query; - test_data.expected_find_command = find_command; - _test_collection_find (&test_data); - bson_free (query); - bson_free (find_command); -} - - -static void -test_maxscan (void *ctx) -{ - _test_int_modifier ("maxScan"); -} - - -static void -test_maxtimems (void) -{ - _test_int_modifier ("maxTimeMS"); -} - - -static void -test_comment (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}]"; - test_data.query_input = "{'$query': {}, '$comment': 'hi'}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'comment': 'hi'}"; - test_data.expected_result = "[{'_id': 1}]"; - _test_collection_find (&test_data); -} - - -static void -test_hint (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}]"; - test_data.query_input = "{'$query': {}, '$hint': { '_id': 1 }}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'hint': { '_id': 1 }}"; - test_data.expected_result = "[{'_id': 1}]"; - _test_collection_find (&test_data); -} - - -static void -test_max (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}]"; - /* MongoDB 4.2 requires that max/min also use hint */ - test_data.query_input = - "{'$query': {}, '$max': {'_id': 100}, '$hint': { '_id': 1 }}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, " - "'max': {'_id': 100}, 'hint': { '_id': 1 }}"; - test_data.expected_result = "[{'_id': 1}]"; - _test_collection_find (&test_data); -} - - -static void -test_min (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}]"; - /* MongoDB 4.2 requires that max/min also use hint */ - test_data.query_input = - "{'$query': {}, '$min': {'_id': 1}, '$hint': { '_id': 1 }}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = "{'find': 'collection', 'filter': {}, " - "'min': {'_id': 1}, 'hint': { '_id': 1 }}"; - test_data.expected_result = "[{'_id': 1}]"; - _test_collection_find (&test_data); -} - - -static void -test_snapshot (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - /* "snapshot" dropped in MongoDB 4.0, wire version 7 */ - test_data.max_wire_version = 6; - test_data.docs = "[{'_id': 1}]"; - test_data.query_input = "{'$query': {}, '$snapshot': true}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'snapshot': true}"; - test_data.expected_result = "[{'_id': 1}]"; - _test_collection_find (&test_data); -} - - -/* $showDiskLoc becomes showRecordId */ -static void -test_diskloc (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}]"; - test_data.query_input = "{'$query': {}, '$showDiskLoc': true}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'showRecordId': true}"; - test_data.expected_result = "[{'_id': 1}]"; - _test_collection_find (&test_data); -} - - -static void -test_returnkey (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}]"; - test_data.query_input = "{'$query': {}, '$returnKey': true}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'returnKey': true}"; - test_data.expected_result = "[{}]"; - _test_collection_find (&test_data); -} - - -static void -test_skip (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}, {'_id': 2}]"; - test_data.skip = 1; - test_data.query_input = "{'$query': {}, '$orderby': {'_id': 1}}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = "{'find': 'collection', 'filter': {}, " - "'sort': {'_id': 1}, 'skip': " - "{'$numberLong': '1'}}"; - test_data.expected_result = "[{'_id': 2}]"; - _test_collection_find (&test_data); -} - - -static void -test_batch_size (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}]"; - test_data.batch_size = 2; - test_data.n_return = 2; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {}, 'batchSize': {'$numberLong': '2'}}"; - test_data.expected_result = "[{'_id': 1}]"; - _test_collection_find (&test_data); -} - - -static void -test_limit (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}, {'_id': 2}, {'_id': 3}]"; - test_data.limit = 2; - test_data.query_input = "{'$query': {}, '$orderby': {'_id': 1}}"; - test_data.expected_op_query = test_data.query_input; - test_data.n_return = 2; - test_data.expected_find_command = "{'find': 'collection', 'filter': {}, " - "'sort': {'_id': 1}, 'limit': " - "{'$numberLong': '2'}}"; - test_data.expected_result = "[{'_id': 1}, {'_id': 2}]"; - _test_collection_find (&test_data); -} - - -static void -test_negative_limit (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - test_data.docs = "[{'_id': 1}, {'_id': 2}, {'_id': 3}]"; - test_data.limit = -2; - test_data.query_input = "{'$query': {}, '$orderby': {'_id': 1}}"; - test_data.expected_op_query = test_data.query_input; - test_data.n_return = -2; - test_data.expected_find_command = "{'find': 'collection', 'filter': {}, " - "'sort': {'_id': 1}, 'singleBatch': true, " - "'limit': {'$numberLong': '2'}}"; - test_data.expected_result = "[{'_id': 1}, {'_id': 2}]"; - _test_collection_find (&test_data); -} - - -static void -test_unrecognized_dollar_option (void) -{ - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - - test_data.query_input = "{'$query': {'a': 1}, '$dumb': 1}"; - test_data.expected_op_query = test_data.query_input; - test_data.expected_find_command = - "{'find': 'collection', 'filter': {'a': 1}, 'dumb': 1}"; - - test_data.do_live = false; - _test_collection_find (&test_data); -} - - -static void -test_query_flags (void) -{ - int i; - char *find_cmd; - test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT; - - typedef struct { - mongoc_query_flags_t flag; - const char *json_fragment; - } flag_and_name_t; - - /* slaveok is not supported as an option, exhaust is tested separately */ - flag_and_name_t flags_and_frags[] = { - {MONGOC_QUERY_TAILABLE_CURSOR, "'tailable': true"}, - {MONGOC_QUERY_OPLOG_REPLAY, "'oplogReplay': true"}, - {MONGOC_QUERY_NO_CURSOR_TIMEOUT, "'noCursorTimeout': true"}, - {MONGOC_QUERY_PARTIAL, "'allowPartialResults': true"}, - {MONGOC_QUERY_TAILABLE_CURSOR | MONGOC_QUERY_AWAIT_DATA, - "'tailable': true, 'awaitData': true"}, - }; - - test_data.expected_result = test_data.docs = "[{'_id': 1}]"; - - for (i = 0; i < (sizeof flags_and_frags) / (sizeof (flag_and_name_t)); i++) { - find_cmd = bson_strdup_printf ("{'find': 'collection', 'filter': {}, %s}", - flags_and_frags[i].json_fragment); - - test_data.flags = flags_and_frags[i].flag; - test_data.expected_find_command = find_cmd; - - _test_collection_find (&test_data); - - bson_free (find_cmd); - } -} - - -static void -test_exhaust (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - request_t *request; - future_t *future; - const bson_t *doc; - bson_error_t error; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, tmp_bson (NULL), NULL, NULL); - - future = future_cursor_next (cursor, &doc); - - /* Find, getMore and killCursors commands spec: "The find command does not - * support the exhaust flag from OP_QUERY. Drivers that support exhaust MUST - * fallback to existing OP_QUERY wire protocol messages." - */ - request = mock_server_receives_request (server); - mock_server_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK | MONGOC_QUERY_EXHAUST, - 0, - 0, - "db.collection", - "{}", - false /* is_command */); - - ASSERT (future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_getmore_batch_size (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - uint32_t batch_sizes[] = {0, 1, 2}; - size_t i; - char *batch_size_json; - bson_error_t error; - - server = mock_server_with_autoismaster (4); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - for (i = 0; i < sizeof (batch_sizes) / sizeof (uint32_t); i++) { - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0, - 0, - batch_sizes[i], - tmp_bson ("{}"), - NULL, - NULL); - - future = future_cursor_next (cursor, &doc); - - if (batch_sizes[i]) { - batch_size_json = - bson_strdup_printf ("{'$numberLong': '%u'}", batch_sizes[i]); - } else { - batch_size_json = bson_strdup ("{'$exists': false}"); - } - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'collection', 'filter': {}, 'batchSize': %s}", - batch_size_json); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': []}}"); - - /* no result */ - ASSERT (!future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - future_destroy (future); - request_destroy (request); - bson_free (batch_size_json); - mongoc_cursor_destroy (cursor); - } - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_getmore_invalid_reply (void *ctx) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - bson_error_t error; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - server = mock_server_with_autoismaster (4); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, tmp_bson ("{}"), NULL, NULL); - - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'collection', 'filter': {}}"); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '123'}," - " 'ns': 'db.collection'," - " 'firstBatch': [{}]}}"); - - ASSERT (future_get_bool (future)); - - future_destroy (future); - request_destroy (request); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'getMore': {'$numberLong': '123'}, 'collection': 'collection'}"); - - /* missing "cursor" */ - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (!future_get_bool (future)); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_PROTOCOL); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_PROTOCOL_INVALID_REPLY); - ASSERT_CONTAINS (error.message, "getMore"); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_getmore_await (void) -{ - typedef struct { - mongoc_query_flags_t flags; - bool expect_await; - } await_test_t; - - await_test_t await_tests[] = { - {MONGOC_QUERY_NONE, false}, - {MONGOC_QUERY_TAILABLE_CURSOR, false}, - {MONGOC_QUERY_AWAIT_DATA, false}, - {MONGOC_QUERY_TAILABLE_CURSOR | MONGOC_QUERY_AWAIT_DATA, true}, - }; - - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - size_t i; - char *max_time_json; - - server = mock_server_with_autoismaster (4); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - for (i = 3; i < sizeof (await_tests) / sizeof (await_test_t); i++) { - cursor = mongoc_collection_find (collection, - await_tests[i].flags, - 0, - 0, - 0, - tmp_bson ("{}"), - NULL, - NULL); - - ASSERT (mongoc_cursor_more (cursor)); - - ASSERT_CMPINT (0, ==, mongoc_cursor_get_max_await_time_ms (cursor)); - mongoc_cursor_set_max_await_time_ms (cursor, 123); - future = future_cursor_next (cursor, &doc); - - /* only the slave ok bit is still in the query header */ - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'collection'," - " 'maxTimeMS': {'$exists': false}," - " 'maxAwaitTimeMS': {'$exists': false}}"); - - /* reply with cursor id 1 */ - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 1," - " 'ns': 'db.collection'," - " 'firstBatch': [{}]}}"); - - /* no result or error */ - ASSERT (future_get_bool (future)); - ASSERT (mongoc_cursor_more (cursor)); - - future_destroy (future); - request_destroy (request); - - future = future_cursor_next (cursor, &doc); - - if (await_tests[i].expect_await) { - max_time_json = "123"; - } else { - max_time_json = "{'$exists': false}"; - } - - /* only the slave ok bit is still in the query header */ - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'getMore': {'$numberLong': '1'}," - " 'collection': 'collection'," - " 'maxAwaitTimeMS': {'$exists': false}," - " 'maxTimeMS': %s}", - max_time_json); - - BSON_ASSERT (request); - /* reply with cursor id 0 */ - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'nextBatch': []}}"); - - /* no result or error */ - ASSERT (!future_get_bool (future)); - ASSERT (!mongoc_cursor_error (cursor, NULL)); - ASSERT (!mongoc_cursor_more (cursor)); - ASSERT (!doc); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - } - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -_test_tailable_timeout (bool pooled) -{ - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_database_t *database; - char *collection_name; - mongoc_collection_t *collection; - bool r; - bson_error_t error; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t reply; - - capture_logs (true); - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - database = mongoc_client_get_database (client, "test"); - collection_name = gen_collection_name ("test"); - - collection = mongoc_database_get_collection (database, collection_name); - mongoc_collection_drop (collection, NULL); - mongoc_collection_destroy (collection); - - collection = mongoc_database_create_collection ( - database, - collection_name, - tmp_bson ("{'capped': true, 'size': 10000}"), - &error); - - ASSERT_OR_PRINT (collection, error); - - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - - client->cluster.sockettimeoutms = 100; - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_TAILABLE_CURSOR | - MONGOC_QUERY_AWAIT_DATA, - 0, - 0, - 0, - tmp_bson ("{'a': 1}"), - NULL, - NULL); - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - - client->cluster.sockettimeoutms = 30 * 1000 * 1000; - r = mongoc_client_command_simple ( - client, "test", tmp_bson ("{'buildinfo': 1}"), NULL, &reply, &error); - - ASSERT_OR_PRINT (r, error); - ASSERT_HAS_FIELD (&reply, "version"); - - bson_destroy (&reply); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - bson_free (collection_name); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - - -static void -test_tailable_timeout_single (void) -{ - _test_tailable_timeout (false); -} - - -#ifndef MONGOC_ENABLE_SSL_SECURE_TRANSPORT -static void -test_tailable_timeout_pooled (void) -{ - _test_tailable_timeout (true); -} -#endif - - -void -test_collection_find_install (TestSuite *suite) -{ - TestSuite_AddLive ( - suite, "/Collection/find/dollar_query", test_dollar_query); - TestSuite_AddLive (suite, "/Collection/find/dollar_or", test_dollar_or); - TestSuite_AddLive (suite, - "/Collection/find/mixed_dollar_nondollar", - test_mixed_dollar_nondollar); - TestSuite_AddLive ( - suite, "/Collection/find/key_named_filter", test_key_named_filter); - TestSuite_AddLive (suite, - "/Collection/find/key_named_filter/$query", - test_key_named_filter_with_dollar_query); - TestSuite_AddLive ( - suite, "/Collection/find/subdoc_named_filter", test_subdoc_named_filter); - TestSuite_AddLive (suite, - "/Collection/find/subdoc_named_filter/$query", - test_subdoc_named_filter_with_dollar_query); - TestSuite_AddLive (suite, "/Collection/find/newoption", test_newoption); - TestSuite_AddLive (suite, "/Collection/find/orderby", test_orderby); - TestSuite_AddLive (suite, "/Collection/find/fields", test_fields); - TestSuite_AddFull (suite, - "/Collection/find/modifiers/maxscan", - test_maxscan, - NULL, - NULL, - test_framework_skip_if_max_wire_version_more_than_6); - TestSuite_AddLive ( - suite, "/Collection/find/modifiers/maxtimems", test_maxtimems); - TestSuite_AddLive (suite, "/Collection/find/comment", test_comment); - TestSuite_AddLive (suite, "/Collection/find/hint", test_hint); - TestSuite_AddLive (suite, "/Collection/find/max", test_max); - TestSuite_AddLive (suite, "/Collection/find/min", test_min); - TestSuite_AddLive (suite, "/Collection/find/modifiers/bool", test_snapshot); - TestSuite_AddLive (suite, "/Collection/find/showdiskloc", test_diskloc); - TestSuite_AddLive (suite, "/Collection/find/returnkey", test_returnkey); - TestSuite_AddLive (suite, "/Collection/find/skip", test_skip); - TestSuite_AddLive (suite, "/Collection/find/batch_size", test_batch_size); - TestSuite_AddLive (suite, "/Collection/find/limit", test_limit); - TestSuite_AddLive ( - suite, "/Collection/find/negative_limit", test_negative_limit); - TestSuite_Add ( - suite, "/Collection/find/unrecognized", test_unrecognized_dollar_option); - TestSuite_AddLive (suite, "/Collection/find/flags", test_query_flags); - TestSuite_AddMockServerTest ( - suite, "/Collection/find/exhaust", test_exhaust); - TestSuite_AddMockServerTest ( - suite, "/Collection/getmore/batch_size", test_getmore_batch_size); - TestSuite_AddFull (suite, - "/Collection/getmore/invalid_reply", - test_getmore_invalid_reply, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest ( - suite, "/Collection/getmore/await", test_getmore_await); - TestSuite_AddLive (suite, - "/Collection/tailable/timeout/single", - test_tailable_timeout_single); -#ifndef MONGOC_ENABLE_SSL_SECURE_TRANSPORT -#ifndef MONGOC_ENABLE_SSL_SECURE_CHANNEL - TestSuite_AddLive (suite, - "/Collection/tailable/timeout/pooled", - test_tailable_timeout_pooled); -#endif -#endif -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-collection.c b/lib/mongoc/libmongoc/tests/test-mongoc-collection.c deleted file mode 100644 index fb2ff370c7c6711af52ad269ce87a45a759686b8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-collection.c +++ /dev/null @@ -1,6422 +0,0 @@ -#include <bson/bcon.h> -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-client-private.h> -#include <mongoc/mongoc-cursor-private.h> -#include <mongoc/mongoc-collection-private.h> -#include <mongoc/mongoc-write-concern-private.h> -#include <mongoc/mongoc-read-concern-private.h> -#include <mongoc/mongoc-util-private.h> - -#include "TestSuite.h" - -#include "test-libmongoc.h" -#include "test-conveniences.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" -#include "mock_server/mock-rs.h" - - -BEGIN_IGNORE_DEPRECATIONS - - -static void -test_aggregate_w_write_concern (void *ctx) -{ - mongoc_cursor_t *cursor; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_write_concern_t *good_wc; - mongoc_write_concern_t *bad_wc; - bson_t *pipeline; - bson_t *opts = NULL; - char *json; - const bson_t *doc; - bson_error_t error; - - /* set up */ - good_wc = mongoc_write_concern_new (); - bad_wc = mongoc_write_concern_new (); - opts = bson_new (); - - client = test_framework_client_new (); - BSON_ASSERT (client); - ASSERT (mongoc_client_set_error_api (client, 2)); - - collection = mongoc_client_get_collection (client, "test", "test"); - - /* pipeline that writes to collection */ - json = bson_strdup_printf ("[{'$out': '%s'}]", collection->collection); - pipeline = tmp_bson (json); - - /* collection aggregate with valid writeConcern: no error */ - mongoc_write_concern_set_w (good_wc, 1); - bson_reinit (opts); - mongoc_write_concern_append (good_wc, opts); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, opts, NULL); - ASSERT (cursor); - mongoc_cursor_next (cursor, &doc); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - mongoc_cursor_destroy (cursor); - - /* writeConcern that will not pass mongoc_write_concern_is_valid */ - bad_wc->wtimeout = -10; - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, opts, NULL); - ASSERT (cursor); - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT_ERROR_CONTAINS (cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - bad_wc->wtimeout = 0; - - mongoc_write_concern_destroy (good_wc); - mongoc_write_concern_destroy (bad_wc); - mongoc_collection_destroy (collection); - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); - bson_destroy (opts); - bson_free (json); -} - -static void -test_aggregate_inherit_collection (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - mongoc_collection_t *collection; - const bson_t *doc; - request_t *request; - future_t *future; - bson_t *pipeline; - bson_t opts = BSON_INITIALIZER; - mongoc_read_concern_t *rc2; - mongoc_read_concern_t *rc; - mongoc_write_concern_t *wc2; - mongoc_write_concern_t *wc; - - server = mock_server_with_autoismaster (WIRE_VERSION_MAX_STALENESS); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - - pipeline = BCON_NEW ( - "pipeline", "[", "{", "$out", BCON_UTF8 ("collection2"), "}", "]"); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_read_concern_append (rc, &opts); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_write_concern_append (wc, &opts); - - /* Uses the opts */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_SLAVE_OK, pipeline, &opts, NULL); - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - " { 'aggregate' : 'collection'," - " 'pipeline' : [ { '$out' : 'collection2' } ]," - " 'cursor' : { }," - " 'readConcern' : { 'level' : 'majority' }," - " 'writeConcern' : { 'w' : 2 } }"); - - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (!future_get_bool (future)); - - /* Set collection level defaults */ - wc2 = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc2, 3); - mongoc_collection_set_write_concern (collection, wc2); - rc2 = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc2, MONGOC_READ_CONCERN_LEVEL_LOCAL); - mongoc_collection_set_read_concern (collection, rc2); - - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - - /* Inherits from collection */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_SLAVE_OK, pipeline, NULL, NULL); - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - " { 'aggregate' : 'collection'," - " 'pipeline' : [ { '$out' : 'collection2' } ]," - " 'cursor' : { }," - " 'readConcern' : { 'level' : 'local' }," - " 'writeConcern' : { 'w' : 3 } }"); - - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (!future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - - /* Uses the opts, not default collection level */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_SLAVE_OK, pipeline, &opts, NULL); - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - " { 'aggregate' : 'collection'," - " 'pipeline' : [ { '$out' : 'collection2' } ]," - " 'cursor' : { }," - " 'readConcern' : { 'level' : 'majority' }," - " 'writeConcern' : { 'w' : 2 } }"); - - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (!future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - - /* Doesn't inherit write concern when not using $out */ - bson_destroy (pipeline); - pipeline = BCON_NEW ( - "pipeline", "[", "{", "$in", BCON_UTF8 ("collection2"), "}", "]"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_SLAVE_OK, pipeline, NULL, NULL); - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - " { 'aggregate' : 'collection'," - " 'pipeline' : [ { '$in' : 'collection2' } ]," - " 'cursor' : { }," - " 'readConcern' : { 'level' : 'local' }," - " 'writeConcern' : { '$exists' : false } }"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT (!future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - - bson_destroy (&opts); - bson_destroy (pipeline); - mongoc_read_concern_destroy (rc); - mongoc_read_concern_destroy (rc2); - mongoc_write_concern_destroy (wc); - mongoc_write_concern_destroy (wc2); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -_batch_size_test (bson_t *pipeline, - bson_t *batch_size, - bool use_batch_size, - int size) -{ - mock_server_t *mock_server; - mongoc_client_t *client; - mongoc_collection_t *coll; - future_t *future; - request_t *request; - mongoc_cursor_t *cursor; - const bson_t *doc; - - mock_server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_run (mock_server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (mock_server)); - coll = mongoc_client_get_collection (client, "db", "coll"); - - cursor = mongoc_collection_aggregate ( - coll, MONGOC_QUERY_NONE, pipeline, batch_size, NULL); - future = future_cursor_next (cursor, &doc); - - if (use_batch_size) { - request = mock_server_receives_msg ( - mock_server, - 0, - tmp_bson ("{ 'cursor' : { 'batchSize' : %d } }", size)); - } else { - request = mock_server_receives_msg ( - mock_server, - 0, - tmp_bson ("{ 'cursor' : { 'batchSize' : { '$exists': false } } }")); - } - - mock_server_replies_simple (request, "{'ok': 1}"); - - request_destroy (request); - future_wait (future); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (mock_server); -} - -static void -test_aggregate_with_batch_size () -{ - bson_t *pipeline_dollar_out; - bson_t *pipeline_dollar_merge; - bson_t *pipeline_no_terminal_key; - bson_t *batch_size_zero; - bson_t *batch_size_one; - - pipeline_dollar_out = tmp_bson ("{ 'pipeline': [ { '$out' : 'coll2' } ] }"); - pipeline_dollar_merge = - tmp_bson ("{ 'pipeline': [ { '$merge' : 'coll2' } ] }"); - pipeline_no_terminal_key = tmp_bson ("{ 'pipeline': [ ] }"); - - batch_size_one = tmp_bson (" { 'batchSize': 1 } "); - batch_size_zero = tmp_bson (" { 'batchSize': 0 } "); - - /* Case 1: - Test that with a terminal key and batchSize > 0, - we use the batchSize */ - _batch_size_test (pipeline_dollar_out, batch_size_one, true, 1); - _batch_size_test (pipeline_dollar_merge, batch_size_one, true, 1); - - /* Case 2: - Test that with terminal key and batchSize == 0, - we don't use the batchSize */ - _batch_size_test (pipeline_dollar_out, batch_size_zero, false, 0); - _batch_size_test (pipeline_dollar_merge, batch_size_zero, false, 0); - - /* Case 3: - Test that without a terminal key and batchSize > 0, - we use the batchSize */ - _batch_size_test (pipeline_no_terminal_key, batch_size_one, true, 1); - - /* Case 4: - Test that without $out and batchSize == 0, - we use the batchSize */ - _batch_size_test (pipeline_no_terminal_key, batch_size_zero, true, 0); -} - -static void -test_read_prefs_is_valid (void *ctx) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - bson_t *pipeline; - mongoc_read_prefs_t *read_prefs; - bson_t reply; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_aggregate"); - ASSERT (collection); - - pipeline = BCON_NEW ("pipeline", - "[", - "{", - "$match", - "{", - "hello", - BCON_UTF8 ("world"), - "}", - "}", - "]"); - - /* if read prefs is not valid */ - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - ASSERT (read_prefs); - mongoc_read_prefs_set_tags (read_prefs, - tmp_bson ("[{'does-not-exist': 'x'}]")); - - /* mongoc_collection_aggregate */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, read_prefs); - ASSERT (cursor); - ASSERT (mongoc_cursor_error (cursor, &error)); - mongoc_cursor_destroy (cursor); - - /* mongoc_collection_command */ - cursor = mongoc_collection_command (collection, - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{}"), - NULL, - read_prefs); - ASSERT (cursor); - ASSERT (mongoc_cursor_error (cursor, &error)); - mongoc_cursor_destroy (cursor); - - /* mongoc_collection_command_simple */ - ASSERT (!mongoc_collection_command_simple ( - collection, tmp_bson ("{'ping': 1}"), read_prefs, &reply, &error)); - bson_destroy (&reply); - - /* mongoc_collection_count_with_opts */ - ASSERT (mongoc_collection_count_with_opts (collection, - MONGOC_QUERY_NONE, - tmp_bson ("{}"), - 0, - 0, - NULL, - read_prefs, - &error) == -1); - - /* mongoc_collection_find */ - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{}"), - NULL, - read_prefs); - - ASSERT (cursor); - ASSERT (mongoc_cursor_error (cursor, &error)); - mongoc_cursor_destroy (cursor); - - /* mongoc_collection_find_with_opts */ - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), NULL, read_prefs); - - ASSERT (cursor); - ASSERT (mongoc_cursor_error (cursor, &error)); - mongoc_cursor_destroy (cursor); - - /* if read prefs is valid */ - mongoc_read_prefs_destroy (read_prefs); - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - ASSERT (read_prefs); - - /* mongoc_collection_aggregate */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, read_prefs); - ASSERT (cursor); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - mongoc_cursor_destroy (cursor); - - /* mongoc_collection_command */ - cursor = mongoc_collection_command (collection, - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{}"), - NULL, - read_prefs); - ASSERT (cursor); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - mongoc_cursor_destroy (cursor); - - /* mongoc_collection_command_simple */ - ASSERT_OR_PRINT ( - mongoc_collection_command_simple ( - collection, tmp_bson ("{'ping': 1}"), read_prefs, &reply, &error), - error); - bson_destroy (&reply); - /* mongoc_collection_count_with_opts */ - ASSERT_OR_PRINT (mongoc_collection_count_with_opts (collection, - MONGOC_QUERY_NONE, - tmp_bson ("{}"), - 0, - 0, - NULL, - read_prefs, - &error) != -1, - error); - - /* mongoc_collection_find */ - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{}"), - NULL, - read_prefs); - - ASSERT (cursor); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - mongoc_cursor_destroy (cursor); - - /* mongoc_collection_find_with_opts */ - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), NULL, read_prefs); - - ASSERT (cursor); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - mongoc_cursor_destroy (cursor); - - mongoc_read_prefs_destroy (read_prefs); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - bson_destroy (pipeline); -} - -static void -test_copy (void) -{ - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_collection_t *copy; - mongoc_client_t *client; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_insert"); - ASSERT (collection); - - copy = mongoc_collection_copy (collection); - ASSERT (copy); - ASSERT (copy->client == collection->client); - ASSERT (strcmp (copy->ns, collection->ns) == 0); - - mongoc_collection_destroy (copy); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - - -static void -test_insert (void) -{ - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_context_t *context; - bson_error_t error; - bool r; - bson_oid_t oid; - unsigned i; - bson_t b; - - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_insert"); - ASSERT (collection); - - /* don't care if ns not found. */ - (void) mongoc_collection_drop (collection, &error); - - context = bson_context_new (BSON_CONTEXT_NONE); - ASSERT (context); - - for (i = 0; i < 10; i++) { - bson_init (&b); - bson_oid_init (&oid, context); - bson_append_oid (&b, "_id", 3, &oid); - bson_append_utf8 (&b, "hello", 5, "/world", 6); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, &b, NULL, NULL, &error), - error); - - bson_destroy (&b); - } - - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{'$hello': 1}"), NULL, NULL, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document"); - - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{'a.b': 1}"), NULL, NULL, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document"); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - bson_context_destroy (context); - mongoc_client_destroy (client); -} - - -static void -test_insert_null (void) -{ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - bson_t reply; - const bson_t *out; - bool ret; - bson_t doc; - bson_t filter = BSON_INITIALIZER; - bson_iter_t iter; - uint32_t len; - - client = test_framework_client_new (); - ASSERT (client); - - collection = - mongoc_client_get_collection (client, "test", "test_null_insert"); - ASSERT (collection); - - (void) mongoc_collection_drop (collection, &error); - - bson_init (&doc); - bson_append_utf8 (&doc, "hello", 5, "wor\0ld", 6); - ret = mongoc_collection_insert_one (collection, &doc, NULL, NULL, &error); - ASSERT_OR_PRINT (ret, error); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - mongoc_bulk_operation_insert (bulk, &doc); - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (ret, error); - ASSERT_MATCH (&reply, - "{'nInserted': 1," - " 'nMatched': 0," - " 'nModified': 0," - " 'nRemoved': 0," - " 'nUpserted': 0," - " 'writeErrors': []}"); - bson_destroy (&doc); - bson_destroy (&reply); - - cursor = mongoc_collection_find_with_opts (collection, &filter, NULL, NULL); - ASSERT (mongoc_cursor_next (cursor, &out)); - ASSERT (bson_iter_init_find (&iter, out, "hello")); - ASSERT (!memcmp (bson_iter_utf8 (&iter, &len), "wor\0ld", 6)); - ASSERT_CMPINT (len, ==, 6); - - ASSERT (mongoc_cursor_next (cursor, &out)); - ASSERT (bson_iter_init_find (&iter, out, "hello")); - ASSERT (!memcmp (bson_iter_utf8 (&iter, &len), "wor\0ld", 6)); - ASSERT_CMPINT (len, ==, 6); - - mongoc_cursor_destroy (cursor); - mongoc_bulk_operation_destroy (bulk); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - mongoc_bulk_operation_remove_one (bulk, &doc); - ret = mongoc_bulk_operation_update_one_with_opts ( - bulk, &doc, tmp_bson ("{'$set': {'x': 1}}"), NULL, &error); - ASSERT_OR_PRINT (ret, error); - ret = mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (ret, error); - - ASSERT_MATCH (&reply, - "{'nInserted': 0," - " 'nMatched': 1," - " 'nModified': 1," - " 'nRemoved': 1," - " 'nUpserted': 0," - " 'writeErrors': []}"); - - bson_destroy (&filter); - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_insert_oversize (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t doc = BSON_INITIALIZER; - bool r; - bson_error_t error; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_insert_oversize"); - - /* two huge strings make the doc too large */ - BSON_ASSERT (bson_append_utf8 ( - &doc, "x", 1, huge_string (client), (int) huge_string_length (client))); - - BSON_ASSERT (bson_append_utf8 ( - &doc, "y", 1, huge_string (client), (int) huge_string_length (client))); - - - r = mongoc_collection_insert_one (collection, &doc, NULL, NULL, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "too large"); - - bson_destroy (&doc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_insert_many (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - bson_context_t *context; - bson_error_t error; - bool r; - bson_oid_t oid; - unsigned i; - bson_t q; - bson_t b[10]; - bson_t *bptr[10]; - bson_t reply; - int64_t count; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_insert_many"); - ASSERT (collection); - - (void) mongoc_collection_drop (collection, &error); - - context = bson_context_new (BSON_CONTEXT_NONE); - ASSERT (context); - - bson_init (&q); - bson_append_int32 (&q, "n", -1, 0); - - for (i = 0; i < 10; i++) { - bson_init (&b[i]); - bson_oid_init (&oid, context); - bson_append_oid (&b[i], "_id", -1, &oid); - bson_append_int32 (&b[i], "n", -1, i % 2); - bptr[i] = &b[i]; - } - - ASSERT_OR_PRINT ( - mongoc_collection_insert_many ( - collection, (const bson_t **) bptr, 10, NULL, &reply, &error), - error); - - ASSERT_CMPINT32 (bson_lookup_int32 (&reply, "insertedCount"), ==, 10); - bson_destroy (&reply); - count = mongoc_collection_count_documents ( - collection, &q, NULL, NULL, NULL, &error); - ASSERT (count == 5); - - for (i = 8; i < 10; i++) { - bson_destroy (&b[i]); - bson_init (&b[i]); - bson_oid_init (&oid, context); - bson_append_oid (&b[i], "_id", -1, &oid); - bson_append_int32 (&b[i], "n", -1, i % 2); - bptr[i] = &b[i]; - } - - r = mongoc_collection_insert_many ( - collection, (const bson_t **) bptr, 10, NULL, &reply, &error); - - ASSERT (!r); - ASSERT (error.code == 11000); - ASSERT_CMPINT32 (bson_lookup_int32 (&reply, "insertedCount"), ==, 0); - bson_destroy (&reply); - - count = mongoc_collection_count_documents ( - collection, &q, NULL, NULL, NULL, &error); - ASSERT (count == 5); - - r = mongoc_collection_insert_many (collection, - (const bson_t **) bptr, - 10, - tmp_bson ("{'ordered': false}"), - &reply, - &error); - ASSERT (!r); - ASSERT (error.code == 11000); - ASSERT_CMPINT32 (bson_lookup_int32 (&reply, "insertedCount"), ==, 2); - bson_destroy (&reply); - - count = mongoc_collection_count_documents ( - collection, &q, NULL, NULL, NULL, &error); - ASSERT (count == 6); - - /* test validate */ - for (i = 0; i < 10; i++) { - bson_destroy (&b[i]); - bson_init (&b[i]); - BSON_APPEND_INT32 (&b[i], "$invalid_dollar_prefixed_name", i); - bptr[i] = &b[i]; - } - r = mongoc_collection_insert_many (collection, - (const bson_t **) bptr, - 10, - tmp_bson ("{'ordered': false}"), - NULL, - &error); - ASSERT (!r); - ASSERT (error.domain == MONGOC_ERROR_COMMAND); - ASSERT (error.code == MONGOC_ERROR_COMMAND_INVALID_ARG); - - for (i = 0; i < 10; i++) { - bson_destroy (&b[i]); - bson_init (&b[i]); - BSON_APPEND_INT32 (&b[i], "a.b", i); - bptr[i] = &b[i]; - } - - r = mongoc_collection_insert_many ( - collection, (const bson_t **) bptr, 10, NULL, NULL, &error); - ASSERT (!r); - ASSERT (error.domain == MONGOC_ERROR_COMMAND); - ASSERT (error.code == MONGOC_ERROR_COMMAND_INVALID_ARG); - - bson_destroy (&q); - for (i = 0; i < 10; i++) { - bson_destroy (&b[i]); - } - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - bson_context_destroy (context); - mongoc_client_destroy (client); -} - - -static void -test_insert_bulk_empty (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - bson_error_t error; - bson_t *bptr = NULL; - - client = test_framework_client_new (); - database = get_test_database (client); - collection = get_test_collection (client, "test_insert_bulk_empty"); - - BEGIN_IGNORE_DEPRECATIONS; - ASSERT (!mongoc_collection_insert_bulk (collection, - MONGOC_INSERT_NONE, - (const bson_t **) &bptr, - 0, - NULL, - &error)); - END_IGNORE_DEPRECATIONS; - - ASSERT_CMPINT (MONGOC_ERROR_COLLECTION, ==, error.domain); - ASSERT_CMPINT (MONGOC_ERROR_COLLECTION_INSERT_FAILED, ==, error.code); - ASSERT_CONTAINS (error.message, "empty insert"); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - - -static void -auto_ismaster (mock_server_t *server, - int32_t max_wire_version, - int32_t max_message_size, - int32_t max_bson_size, - int32_t max_batch_size) -{ - char *response = bson_strdup_printf ("{'ismaster': true, " - " 'maxWireVersion': %d," - " 'maxBsonObjectSize': %d," - " 'maxMessageSizeBytes': %d," - " 'maxWriteBatchSize': %d }", - max_wire_version, - max_bson_size, - max_message_size, - max_batch_size); - - BSON_ASSERT (max_wire_version > 0); - mock_server_auto_ismaster (server, response); - - bson_free (response); -} - - -char * -make_string (size_t len) -{ - char *s = (char *) bson_malloc (len); - - BSON_ASSERT (len > 0); - memset (s, 'a', len - 1); - s[len - 1] = '\0'; - - return s; -} - - -bson_t * -make_document (size_t bytes) -{ - bson_t *bson; - bson_oid_t oid; - char *s; - size_t string_len; - - bson_oid_init (&oid, NULL); - bson = bson_new (); - BSON_APPEND_OID (bson, "_id", &oid); - - /* make the document exactly n bytes by appending a string. a string has - * 7 bytes overhead (1 for type code, 2 for key, 4 for length prefix), so - * make the string (n_bytes - current_length - 7) bytes long. */ - ASSERT_CMPUINT ((unsigned int) bytes, >=, bson->len + 7); - string_len = bytes - bson->len - 7; - s = make_string (string_len); - BSON_APPEND_UTF8 (bson, "s", s); - bson_free (s); - ASSERT_CMPUINT ((unsigned int) bytes, ==, bson->len); - - return bson; -} - - -void -make_bulk_insert (bson_t **bsons, int n, size_t bytes) -{ - int i; - - for (i = 0; i < n; i++) { - bsons[i] = make_document (bytes); - } -} - - -static void -destroy_all (bson_t **ptr, int n) -{ - int i; - - for (i = 0; i < n; i++) { - bson_destroy (ptr[i]); - } -} - - -/* verify an insert command's "documents" array has keys "0", "1", "2", ... */ -static void -verify_keys (uint32_t n_documents, const bson_t *insert_command) -{ - bson_iter_t iter; - uint32_t len; - const uint8_t *data; - bson_t document; - char str[16]; - const char *key; - uint32_t i; - - ASSERT (bson_iter_init_find (&iter, insert_command, "documents")); - bson_iter_array (&iter, &len, &data); - ASSERT (bson_init_static (&document, data, len)); - - for (i = 0; i < n_documents; i++) { - bson_uint32_to_string (i, &key, str, sizeof str); - ASSERT (bson_has_field (&document, key)); - } -} - - -/* CDRIVER-845: "insert" command must have array keys "0", "1", "2", ... */ -static void -test_insert_command_keys (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - uint32_t i; - bson_t *doc; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "test", "test"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - for (i = 0; i < 3; i++) { - doc = BCON_NEW ("_id", BCON_INT32 (i)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - } - - future = future_bulk_operation_execute (bulk, &reply, &error); - request = mock_server_receives_command ( - server, "test", MONGOC_QUERY_NONE, "{'insert': 'test'}"); - - verify_keys (3, request_get_doc (request, 0)); - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT_OR_PRINT (future_get_uint32_t (future), error); - - bson_destroy (&reply); - future_destroy (future); - request_destroy (request); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_save (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - bson_context_t *context; - bson_error_t error; - bson_oid_t oid; - unsigned i; - bson_t b; - bool r; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_save"); - ASSERT (collection); - - /* don't care if ns not found. */ - (void) mongoc_collection_drop (collection, &error); - - context = bson_context_new (BSON_CONTEXT_NONE); - ASSERT (context); - - BEGIN_IGNORE_DEPRECATIONS; - - for (i = 0; i < 10; i++) { - bson_init (&b); - bson_oid_init (&oid, context); - bson_append_oid (&b, "_id", 3, &oid); - bson_append_utf8 (&b, "hello", 5, "/world", 5); - ASSERT_OR_PRINT (mongoc_collection_save (collection, &b, NULL, &error), - error); - bson_destroy (&b); - } - - r = mongoc_collection_save ( - collection, tmp_bson ("{'$hello': 1}"), NULL, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document"); - - r = mongoc_collection_save ( - collection, tmp_bson ("{'a.b': 1}"), NULL, &error); - - END_IGNORE_DEPRECATIONS; - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document"); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - bson_context_destroy (context); - mongoc_client_destroy (client); -} - - -static void -test_regex (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_write_concern_t *wr; - bson_t opts = BSON_INITIALIZER; - mongoc_client_t *client; - bson_error_t error; - int64_t count; - bson_t q = BSON_INITIALIZER; - bson_t *doc; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_regex"); - ASSERT (collection); - - wr = mongoc_write_concern_new (); - mongoc_write_concern_set_journal (wr, true); - mongoc_write_concern_append (wr, &opts); - - doc = BCON_NEW ("hello", "/world"); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, doc, &opts, NULL, &error), - error); - - BSON_APPEND_REGEX (&q, "hello", "^/wo", "i"); - - count = mongoc_collection_count_documents ( - collection, &q, NULL, NULL, NULL, &error); - - ASSERT (count > 0); - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&opts); - mongoc_write_concern_destroy (wr); - bson_destroy (&q); - bson_destroy (doc); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - - -static void -test_decimal128 (void *ctx) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_write_concern_t *wr; - bson_t opts = BSON_INITIALIZER; - mongoc_client_t *client; - bson_error_t error = {0}; - int64_t count; - bson_t query = BSON_INITIALIZER; - bson_t *doc; - const bson_t *dec; - bson_iter_t dec_iter; - mongoc_cursor_t *cursor; - bool r; - bson_decimal128_t decimal128; - bson_decimal128_t read_decimal; - - bson_decimal128_from_string ("-123456789.101112E-120", &decimal128); - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_decimal128"); - ASSERT (collection); - - wr = mongoc_write_concern_new (); - mongoc_write_concern_set_journal (wr, true); - mongoc_write_concern_append (wr, &opts); - - doc = BCON_NEW ("the_decimal", BCON_DECIMAL128 (&decimal128)); - r = mongoc_collection_insert_one (collection, doc, &opts, NULL, &error); - if (!r) { - MONGOC_WARNING ("test_decimal128: %s\n", error.message); - } - ASSERT (r); - - count = mongoc_collection_count_documents ( - collection, &query, NULL, NULL, NULL, &error); - ASSERT (count > 0); - - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, NULL, NULL); - ASSERT (mongoc_cursor_next (cursor, &dec)); - - ASSERT (bson_iter_init (&dec_iter, dec)); - - ASSERT (bson_iter_find (&dec_iter, "the_decimal")); - ASSERT (BSON_ITER_HOLDS_DECIMAL128 (&dec_iter)); - bson_iter_decimal128 (&dec_iter, &read_decimal); - - ASSERT (read_decimal.high == decimal128.high && - read_decimal.low == decimal128.low); - - bson_destroy (doc); - bson_destroy (&query); - bson_destroy (&opts); - mongoc_write_concern_destroy (wr); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - - -static void -test_update (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - bson_context_t *context; - bson_error_t error; - bool r; - bson_oid_t oid; - unsigned i; - bson_t b; - bson_t q; - bson_t u; - bson_t set; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_update"); - ASSERT (collection); - - context = bson_context_new (BSON_CONTEXT_NONE); - ASSERT (context); - - for (i = 0; i < 10; i++) { - bson_init (&b); - bson_oid_init (&oid, context); - bson_append_oid (&b, "_id", 3, &oid); - bson_append_utf8 (&b, "utf8", 4, "utf8 string", 11); - bson_append_int32 (&b, "int32", 5, 1234); - bson_append_int64 (&b, "int64", 5, 12345678); - bson_append_bool (&b, "bool", 4, 1); - - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, &b, NULL, NULL, &error), - error); - - bson_init (&q); - bson_append_oid (&q, "_id", 3, &oid); - - bson_init (&u); - bson_append_document_begin (&u, "$set", 4, &set); - bson_append_utf8 (&set, "utf8", 4, "updated", 7); - bson_append_document_end (&u, &set); - - ASSERT_OR_PRINT (mongoc_collection_update ( - collection, MONGOC_UPDATE_NONE, &q, &u, NULL, &error), - error); - - bson_destroy (&b); - bson_destroy (&q); - bson_destroy (&u); - } - - bson_init (&q); - bson_init (&u); - BSON_APPEND_INT32 (&u, "abcd", 1); - BSON_APPEND_INT32 (&u, "$hi", 1); - r = mongoc_collection_update ( - collection, MONGOC_UPDATE_NONE, &q, &u, NULL, &error); - ASSERT (!r); - ASSERT (error.domain == MONGOC_ERROR_COMMAND); - ASSERT (error.code == MONGOC_ERROR_COMMAND_INVALID_ARG); - bson_destroy (&q); - bson_destroy (&u); - - bson_init (&q); - bson_init (&u); - BSON_APPEND_INT32 (&u, "a.b.c.d", 1); - r = mongoc_collection_update ( - collection, MONGOC_UPDATE_NONE, &q, &u, NULL, &error); - ASSERT (!r); - ASSERT (error.domain == MONGOC_ERROR_COMMAND); - ASSERT (error.code == MONGOC_ERROR_COMMAND_INVALID_ARG); - bson_destroy (&q); - bson_destroy (&u); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - bson_context_destroy (context); - mongoc_client_destroy (client); -} - -static void -test_update_pipeline (void *ctx) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - bson_error_t error; - bson_t *b; - bson_t *pipeline; - bson_t *replacement; - bool res; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_update_pipeline"); - ASSERT (collection); - - b = tmp_bson ("{'nums': {'x': 1, 'y': 2}}"); - res = mongoc_collection_insert_one (collection, b, NULL, NULL, &error); - ASSERT_OR_PRINT (res, error); - - /* format: array document with incrementing keys - (i.e. {"0": value, "1": value, "2": value}) */ - pipeline = tmp_bson ("{'0': {'$replaceRoot': {'newRoot': '$nums'}}," - " '1': {'$addFields': {'z': 3}}}"); - res = mongoc_collection_update_one ( - collection, b, pipeline, NULL, NULL, &error); - ASSERT_OR_PRINT (res, error); - - res = mongoc_collection_insert_one (collection, b, NULL, NULL, &error); - ASSERT_OR_PRINT (res, error); - - /* ensure that arrays sent to mongoc_collection_replace_one are not - treated as pipelines */ - replacement = tmp_bson ("{'0': 0, '1': 1}"); - res = mongoc_collection_replace_one ( - collection, b, replacement, NULL, NULL, &error); - ASSERT_OR_PRINT (res, error); - - /* ensure that pipeline updates sent to mongoc_collection_replace_one - receive a client-side error */ - res = mongoc_collection_replace_one ( - collection, b, pipeline, NULL, NULL, &error); - ASSERT (!res); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid argument for replace"); - - /* ensure that a pipeline with an empty document is considered invalid */ - pipeline = tmp_bson ("{ '0': {} }"); - res = mongoc_collection_update_one ( - collection, b, pipeline, NULL, NULL, &error); - ASSERT (!res); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid key"); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_update_oversize (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - size_t huger_sz = 20 * 1024 * 1024; - char *huger; - bson_t huge = BSON_INITIALIZER; - bson_t empty = BSON_INITIALIZER; - bson_t huge_update = BSON_INITIALIZER; - bson_t child; - bool r; - bson_error_t error; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_update_oversize"); - - /* first test oversized selector. two huge strings make the doc too large */ - BSON_ASSERT (bson_append_utf8 ( - &huge, "x", 1, huge_string (client), (int) huge_string_length (client))); - - BSON_ASSERT (bson_append_utf8 ( - &huge, "y", 1, huge_string (client), (int) huge_string_length (client))); - - r = mongoc_collection_update ( - collection, MONGOC_UPDATE_NONE, &huge, &empty, NULL, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "too large"); - - /* test oversized update operator */ - huger = bson_malloc (huger_sz + 1); - memset (huger, 'a', huger_sz); - huger[huger_sz] = '\0'; - BSON_ASSERT (BSON_APPEND_DOCUMENT_BEGIN (&huge_update, "$set", &child)); - BSON_ASSERT (bson_append_utf8 (&child, "x", 1, huger, (int) huger_sz)); - BSON_ASSERT (bson_append_document_end (&huge_update, &child)); - - r = mongoc_collection_update ( - collection, MONGOC_UPDATE_NONE, &empty, &huge_update, NULL, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "too large"); - - bson_free (huger); - bson_destroy (&huge); - bson_destroy (&empty); - bson_destroy (&huge_update); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_remove (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - bson_context_t *context; - bson_error_t error; - bool r; - bson_oid_t oid; - bson_t b; - int i; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_remove"); - ASSERT (collection); - - context = bson_context_new (BSON_CONTEXT_NONE); - ASSERT (context); - - for (i = 0; i < 100; i++) { - bson_init (&b); - bson_oid_init (&oid, context); - bson_append_oid (&b, "_id", 3, &oid); - bson_append_utf8 (&b, "hello", 5, "world", 5); - r = mongoc_collection_insert_one (collection, &b, NULL, NULL, &error); - if (!r) { - MONGOC_WARNING ("%s\n", error.message); - } - ASSERT (r); - bson_destroy (&b); - - bson_init (&b); - bson_append_oid (&b, "_id", 3, &oid); - r = mongoc_collection_delete_many (collection, &b, NULL, NULL, &error); - if (!r) { - MONGOC_WARNING ("%s\n", error.message); - } - ASSERT (r); - bson_destroy (&b); - } - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - bson_context_destroy (context); - mongoc_client_destroy (client); -} - - -static void -test_remove_oversize (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t doc = BSON_INITIALIZER; - bool r; - bson_error_t error; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_remove_oversize"); - - /* two huge strings make the doc too large */ - BSON_ASSERT (bson_append_utf8 ( - &doc, "x", 1, huge_string (client), (int) huge_string_length (client))); - - BSON_ASSERT (bson_append_utf8 ( - &doc, "y", 1, huge_string (client), (int) huge_string_length (client))); - - r = mongoc_collection_delete_many (collection, &doc, NULL, NULL, &error); - ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "too large"); - - bson_destroy (&doc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_insert_w0 (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_insert_w0"); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_append (wc, &opts); - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), &opts, NULL, &error); - ASSERT_OR_PRINT (r, error); - ASSERT (mongoc_collection_get_last_error (collection) == NULL); - - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_update_w0 (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_write_concern_t *wc; - bson_error_t error; - - bool r; - client = test_framework_client_new (); - collection = get_test_collection (client, "test_update_w0"); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - r = mongoc_collection_update (collection, - MONGOC_UPDATE_NONE, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'x': 1}}"), - wc, - &error); - ASSERT_OR_PRINT (r, error); - ASSERT (bson_empty (mongoc_collection_get_last_error (collection))); - - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_remove_w0 (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - bson_t reply; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_remove_w0"); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_append (wc, &opts); - r = mongoc_collection_delete_many ( - collection, tmp_bson ("{}"), &opts, &reply, &error); - ASSERT_OR_PRINT (r, error); - ASSERT (bson_empty (&reply)); - - bson_destroy (&reply); - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_insert_twice_w0 (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_insert_twice_w0"); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_append (wc, &opts); - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{'_id': 1}"), &opts, NULL, &error); - ASSERT_OR_PRINT (r, error); - ASSERT (mongoc_collection_get_last_error (collection) == NULL); - - /* Insert same document for the second time, but we should not get - * an error since we don't wait for a server response */ - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{'_id': 1}"), &opts, NULL, &error); - ASSERT_OR_PRINT (r, error); - ASSERT (mongoc_collection_get_last_error (collection) == NULL); - - bson_destroy (&opts); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_index (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_index_opt_t opt; - bson_error_t error; - bson_t keys; - bson_t *opts = NULL; - mongoc_write_concern_t *bad_wc; - mongoc_write_concern_t *good_wc; - bool wire_version_5; - bool r; - - mongoc_index_opt_init (&opt); - opts = bson_new (); - - client = test_framework_client_new (); - ASSERT (client); - mongoc_client_set_error_api (client, 2); - - bad_wc = mongoc_write_concern_new (); - good_wc = mongoc_write_concern_new (); - - wire_version_5 = test_framework_max_wire_version_at_least (5); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_index"); - ASSERT (collection); - - bson_init (&keys); - bson_append_int32 (&keys, "hello", -1, 1); - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), error); - - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), error); - - ASSERT_OR_PRINT ( - mongoc_collection_drop_index (collection, "hello_1", &error), error); - - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), error); - - if (wire_version_5) { - /* invalid writeConcern */ - bad_wc->wtimeout = -10; - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - ASSERT (!mongoc_collection_drop_index_with_opts ( - collection, "hello_1", opts, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - bad_wc->wtimeout = 0; - error.code = 0; - error.domain = 0; - - /* valid writeConcern on all configs*/ - mongoc_write_concern_set_w (good_wc, 1); - bson_reinit (opts); - mongoc_write_concern_append (good_wc, opts); - ASSERT_OR_PRINT (mongoc_collection_drop_index_with_opts ( - collection, "hello_1", opts, &error), - error); - ASSERT (!error.code); - ASSERT (!error.domain); - - /* writeConcern that results in writeConcernError */ - mongoc_write_concern_set_w (bad_wc, 99); - - if (!test_framework_is_mongos ()) { /* skip if sharded */ - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), - error); - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - r = mongoc_collection_drop_index_with_opts ( - collection, "hello_1", opts, &error); - ASSERT (!r); - - if (test_framework_is_replset ()) { /* replica set */ - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:"); - } else { /* standalone */ - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CMPINT (error.code, ==, 2); - } - } - } /* wire_version_5 */ - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&keys); - bson_destroy (opts); - mongoc_write_concern_destroy (bad_wc); - mongoc_write_concern_destroy (good_wc); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_index_w_write_concern () -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_index_opt_t opt; - mongoc_write_concern_t *good_wc; - mongoc_write_concern_t *bad_wc; - bson_error_t error; - bson_t keys; - bson_t reply; - bson_t *opts = NULL; - bool result; - bool wire_version_5; - bool is_replicaset = test_framework_is_replset (); - bool is_mongos = test_framework_is_mongos (); - - mongoc_index_opt_init (&opt); - opts = bson_new (); - - client = test_framework_client_new (); - ASSERT (client); - - good_wc = mongoc_write_concern_new (); - bad_wc = mongoc_write_concern_new (); - - mongoc_client_set_error_api (client, 2); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_index"); - ASSERT (collection); - - wire_version_5 = test_framework_max_wire_version_at_least (5); - - bson_init (&keys); - bson_append_int32 (&keys, "hello", -1, 1); - - /* writeConcern that will not pass validation */ - bad_wc->wtimeout = -10; - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - ASSERT (!mongoc_collection_create_index_with_opts ( - collection, &keys, &opt, opts, &reply, &error)); - bson_destroy (&reply); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - bad_wc->wtimeout = 0; - error.code = 0; - error.domain = 0; - - /* valid writeConcern on all server configs */ - mongoc_write_concern_set_w (good_wc, 1); - bson_reinit (opts); - mongoc_write_concern_append (good_wc, opts); - result = mongoc_collection_create_index_with_opts ( - collection, &keys, &opt, opts, &reply, &error); - ASSERT_OR_PRINT (result, error); - ASSERT (!error.code); - - /* Be sure the reply is valid */ - ASSERT (bson_validate (&reply, 0, NULL)); - result = mongoc_collection_drop_index (collection, "hello_1", &error); - ASSERT_OR_PRINT (result, error); - ASSERT (!bson_empty (&reply)); - bson_destroy (&reply); - - /* writeConcern that will result in writeConcernError */ - mongoc_write_concern_set_w (bad_wc, 99); - - ASSERT (!error.code); - - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - /* skip this part of the test if sharded cluster */ - if (!is_mongos) { - if (wire_version_5) { - ASSERT (!mongoc_collection_create_index_with_opts ( - collection, &keys, &opt, opts, &reply, &error)); - if (is_replicaset) { /* replica set */ - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:"); - } else { /* standalone */ - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CMPINT (error.code, ==, 2); - } - } else { /* if wire version <= 4, no error */ - result = mongoc_collection_create_index_with_opts ( - collection, &keys, &opt, opts, &reply, &error); - ASSERT_OR_PRINT (result, error); - ASSERT (!error.code); - ASSERT (!error.domain); - } - - ASSERT (!bson_empty (&reply)); - bson_destroy (&reply); - } - - /* Make sure it doesn't crash with a NULL reply or writeConcern */ - result = mongoc_collection_create_index_with_opts ( - collection, &keys, &opt, NULL, NULL, &error); - ASSERT_OR_PRINT (result, error); - - ASSERT_OR_PRINT ( - mongoc_collection_drop_index (collection, "hello_1", &error), error); - - /* Now attempt to create an invalid index which the server will reject */ - bson_reinit (&keys); - - /* Try to create an index like {abc: "hallo thar"} (won't work, - should really be something like {abc: 1}) - - This fails both on legacy and modern versions of the server - */ - BSON_APPEND_UTF8 (&keys, "abc", "hallo thar"); - result = mongoc_collection_create_index_with_opts ( - collection, &keys, &opt, NULL, &reply, &error); - bson_destroy (&reply); - - ASSERT (!result); - ASSERT (strlen (error.message) > 0); - memset (&error, 0, sizeof (error)); - - /* Try again but with reply NULL. Shouldn't crash */ - result = mongoc_collection_create_index_with_opts ( - collection, &keys, &opt, NULL, NULL, &error); - ASSERT (!result); - ASSERT (strlen (error.message) > 0); - - bson_destroy (&keys); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - mongoc_write_concern_destroy (bad_wc); - mongoc_write_concern_destroy (good_wc); - bson_destroy (opts); -} - -static void -test_index_compound (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_index_opt_t opt; - bson_error_t error; - bson_t keys; - - mongoc_index_opt_init (&opt); - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_index_compound"); - ASSERT (collection); - - bson_init (&keys); - bson_append_int32 (&keys, "hello", -1, 1); - bson_append_int32 (&keys, "world", -1, -1); - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), error); - - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), error); - - ASSERT_OR_PRINT ( - mongoc_collection_drop_index (collection, "hello_1_world_-1", &error), - error); - - bson_destroy (&keys); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_index_geo (void) -{ - mongoc_server_description_t *description; - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_index_opt_t opt; - mongoc_index_opt_geo_t geo_opt; - bson_error_t error; - bool r; - bson_t keys; - uint32_t id; - - mongoc_index_opt_init (&opt); - mongoc_index_opt_geo_init (&geo_opt); - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_geo_index"); - ASSERT (collection); - - /* Create a basic 2d index */ - bson_init (&keys); - BSON_APPEND_UTF8 (&keys, "location", "2d"); - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), error); - - ASSERT_OR_PRINT ( - mongoc_collection_drop_index (collection, "location_2d", &error), error); - - /* Create a 2d index with bells and whistles */ - bson_destroy (&keys); - bson_init (&keys); - BSON_APPEND_UTF8 (&keys, "location", "2d"); - - geo_opt.twod_location_min = -123; - geo_opt.twod_location_max = +123; - geo_opt.twod_bits_precision = 30; - opt.geo_options = &geo_opt; - - /* TODO this hack is needed for single-threaded tests */ - id = client->topology->description.servers->items[0].id; - description = mongoc_topology_server_by_id (client->topology, id, &error); - ASSERT_OR_PRINT (description, error); - - if (description->max_wire_version > 0) { - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), - error); - - ASSERT_OR_PRINT ( - mongoc_collection_drop_index (collection, "location_2d", &error), - error); - } - - /* Create a Haystack index */ - bson_destroy (&keys); - bson_init (&keys); - BSON_APPEND_UTF8 (&keys, "location", "geoHaystack"); - BSON_APPEND_INT32 (&keys, "category", 1); - - mongoc_index_opt_geo_init (&geo_opt); - geo_opt.haystack_bucket_size = 5; - - opt.geo_options = &geo_opt; - - if (description->max_wire_version > 0) { - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), - error); - - r = mongoc_collection_drop_index ( - collection, "location_geoHaystack_category_1", &error); - ASSERT_OR_PRINT (r, error); - } - - bson_destroy (&keys); - mongoc_server_description_destroy (description); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static char * -storage_engine (mongoc_client_t *client) -{ - bson_iter_t iter; - bson_error_t error; - bson_t cmd = BSON_INITIALIZER; - bson_t reply; - - /* NOTE: this default will change eventually */ - char *engine = bson_strdup ("mmapv1"); - - BSON_APPEND_INT32 (&cmd, "getCmdLineOpts", 1); - ASSERT_OR_PRINT (mongoc_client_command_simple ( - client, "admin", &cmd, NULL, &reply, &error), - error); - - if (bson_iter_init_find (&iter, &reply, "parsed.storage.engine")) { - engine = bson_strdup (bson_iter_utf8 (&iter, NULL)); - } - - bson_destroy (&reply); - bson_destroy (&cmd); - - return engine; -} - -static void -test_index_storage (void) -{ - mongoc_collection_t *collection = NULL; - mongoc_database_t *database = NULL; - mongoc_client_t *client = NULL; - mongoc_index_opt_t opt; - mongoc_index_opt_wt_t wt_opt; - bson_error_t error; - bson_t keys; - char *engine = NULL; - - client = test_framework_client_new (); - ASSERT (client); - - /* Skip unless we are on WT */ - engine = storage_engine (client); - if (strcmp ("wiredTiger", engine) != 0) { - goto cleanup; - } - - mongoc_index_opt_init (&opt); - mongoc_index_opt_wt_init (&wt_opt); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_storage_index"); - ASSERT (collection); - - /* Create a simple index */ - bson_init (&keys); - bson_append_int32 (&keys, "hello", -1, 1); - - /* Add storage option to the index */ - wt_opt.base.type = MONGOC_INDEX_STORAGE_OPT_WIREDTIGER; - wt_opt.config_str = "block_compressor=zlib"; - - opt.storage_options = (mongoc_index_opt_storage_t *) &wt_opt; - - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &keys, &opt, &error), error); - -cleanup: - if (engine) - bson_free (engine); - if (collection) - mongoc_collection_destroy (collection); - if (database) - mongoc_database_destroy (database); - if (client) - mongoc_client_destroy (client); -} - -static void -test_count (void) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - int64_t count; - bson_t b; - - client = test_framework_client_new (); - ASSERT (client); - - collection = mongoc_client_get_collection (client, "test", "test"); - ASSERT (collection); - - bson_init (&b); - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - - if (count == -1) { - MONGOC_WARNING ("%s\n", error.message); - } - ASSERT (count != -1); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_count_read_pref (void) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_read_prefs_t *prefs; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - mongoc_collection_set_read_prefs (collection, prefs); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, NULL, 0, 0, NULL, &error); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'count': 'collection'}," - " '$readPreference': {'mode': 'secondary'}}"); - - mock_server_replies_simple (request, "{'ok': 1, 'n': 1}"); - ASSERT_OR_PRINT (1 == future_get_int64_t (future), error); - - request_destroy (request); - future_destroy (future); - mongoc_read_prefs_destroy (prefs); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_count_read_concern (void) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_read_concern_t *rc; - mock_server_t *server; - request_t *request; - bson_error_t error; - future_t *future; - int64_t count; - bson_t b; - - /* wire protocol version 4 */ - server = mock_server_with_autoismaster (WIRE_VERSION_READ_CONCERN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT (client); - - collection = mongoc_client_get_collection (client, "test", "test"); - ASSERT (collection); - - bson_init (&b); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - request = - mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{ 'count' : 'test', 'query' : { } }"); - - mock_server_replies_simple (request, "{ 'n' : 42, 'ok' : 1 } "); - count = future_get_int64_t (future); - ASSERT_OR_PRINT (count == 42, error); - request_destroy (request); - future_destroy (future); - - /* readConcern: { level: majority } */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_collection_set_read_concern (collection, rc); - - bson_init (&b); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - request = mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{ 'count' : 'test', 'query' : { " - "}, 'readConcern': {'level': " - "'majority'}}"); - - mock_server_replies_simple (request, "{ 'n' : 43, 'ok' : 1 } "); - count = future_get_int64_t (future); - ASSERT_OR_PRINT (count == 43, error); - mongoc_read_concern_destroy (rc); - request_destroy (request); - future_destroy (future); - - /* readConcern: { level: local } */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_LOCAL); - mongoc_collection_set_read_concern (collection, rc); - - bson_init (&b); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{ 'count' : 'test', 'query' : { }, 'readConcern': {'level': 'local'}}"); - - mock_server_replies_simple (request, "{ 'n' : 44, 'ok' : 1 } "); - count = future_get_int64_t (future); - ASSERT_OR_PRINT (count == 44, error); - mongoc_read_concern_destroy (rc); - request_destroy (request); - future_destroy (future); - - /* readConcern: { level: futureCompatible } */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, "futureCompatible"); - mongoc_collection_set_read_concern (collection, rc); - - bson_init (&b); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - request = mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{ 'count' : 'test', 'query' : { " - "}, 'readConcern': {'level': " - "'futureCompatible'}}"); - - mock_server_replies_simple (request, "{ 'n' : 45, 'ok' : 1 } "); - count = future_get_int64_t (future); - ASSERT_OR_PRINT (count == 45, error); - mongoc_read_concern_destroy (rc); - request_destroy (request); - future_destroy (future); - - /* Setting readConcern to NULL should not send readConcern */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, NULL); - mongoc_collection_set_read_concern (collection, rc); - - bson_init (&b); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - request = mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{ 'count' : 'test', 'query' : { " - "}, 'readConcern': { '$exists': " - "false }}"); - - mock_server_replies_simple (request, "{ 'n' : 46, 'ok' : 1 } "); - count = future_get_int64_t (future); - ASSERT_OR_PRINT (count == 46, error); - mongoc_read_concern_destroy (rc); - request_destroy (request); - future_destroy (future); - - /* Fresh read_concern should not send readConcern */ - rc = mongoc_read_concern_new (); - mongoc_collection_set_read_concern (collection, rc); - - bson_init (&b); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - request = mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{ 'count' : 'test', 'query' : { " - "}, 'readConcern': { '$exists': " - "false }}"); - - mock_server_replies_simple (request, "{ 'n' : 47, 'ok' : 1 } "); - count = future_get_int64_t (future); - ASSERT_OR_PRINT (count == 47, error); - - mongoc_read_concern_destroy (rc); - request_destroy (request); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -_test_count_read_concern_live (bool supports_read_concern) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_read_concern_t *rc; - bson_error_t error; - int64_t count; - bson_t b; - - - client = test_framework_client_new (); - ASSERT (client); - - collection = mongoc_client_get_collection (client, "test", "test"); - ASSERT (collection); - - /* don't care if ns not found. */ - (void) mongoc_collection_drop (collection, &error); - - bson_init (&b); - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - ASSERT_OR_PRINT (count == 0, error); - - /* Setting readConcern to NULL should not send readConcern */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, NULL); - mongoc_collection_set_read_concern (collection, rc); - - bson_init (&b); - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - ASSERT_OR_PRINT (count == 0, error); - mongoc_read_concern_destroy (rc); - - /* readConcern: { level: local } should raise error pre 3.2 */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_LOCAL); - mongoc_collection_set_read_concern (collection, rc); - - bson_init (&b); - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - if (supports_read_concern) { - ASSERT_OR_PRINT (count == 0, error); - } else { - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support readConcern") - } - mongoc_read_concern_destroy (rc); - - /* readConcern: { level: majority } should raise error pre 3.2 */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_collection_set_read_concern (collection, rc); - - bson_init (&b); - count = mongoc_collection_count ( - collection, MONGOC_QUERY_NONE, &b, 0, 0, NULL, &error); - bson_destroy (&b); - if (supports_read_concern) { - ASSERT_OR_PRINT (count == 0, error); - } else { - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support readConcern") - } - mongoc_read_concern_destroy (rc); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -int -skip_unless_server_has_decimal128 (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - if (test_framework_get_server_version () >= - test_framework_str_to_version ("3.3.5")) { - return 1; - } - return 0; -} - -int -mongod_supports_majority_read_concern (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return test_framework_getenv_bool ("MONGOC_ENABLE_MAJORITY_READ_CONCERN"); -} - -static void -test_count_read_concern_live (void *context) -{ - if (test_framework_max_wire_version_at_least (WIRE_VERSION_READ_CONCERN)) { - _test_count_read_concern_live (true); - } else { - _test_count_read_concern_live (false); - } -} - - -static void -test_count_with_opts (void) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - future_t *future; - request_t *request; - bson_error_t error; - - /* use a mongos since we don't send SLAVE_OK to mongos by default */ - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - future = future_collection_count_with_opts (collection, - MONGOC_QUERY_SLAVE_OK, - NULL, - 0, - 0, - tmp_bson ("{'opt': 1}"), - NULL, - &error); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'count': 'collection', 'opt': 1}"); - - mock_server_replies_simple (request, "{'ok': 1, 'n': 1}"); - ASSERT_OR_PRINT (1 == future_get_int64_t (future), error); - - request_destroy (request); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_count_with_collation (int wire) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_server_with_autoismaster (wire); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - future = future_collection_count_with_opts ( - collection, - MONGOC_QUERY_SLAVE_OK, - NULL, - 0, - 0, - tmp_bson ("{'collation': {'locale': 'en'}}"), - NULL, - &error); - - if (wire == WIRE_VERSION_COLLATION) { - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'count': 'collection', 'collation': {'locale': 'en'}}"); - mock_server_replies_simple (request, "{'ok': 1, 'n': 1}"); - ASSERT_OR_PRINT (1 == future_get_int64_t (future), error); - request_destroy (request); - } else { - ASSERT (-1 == future_get_int64_t (future)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } - - - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_count_with_collation_ok (void) -{ - test_count_with_collation (WIRE_VERSION_COLLATION); -} - - -static void -test_count_with_collation_fail (void) -{ - test_count_with_collation (WIRE_VERSION_COLLATION - 1); -} - - -static void -test_count_documents (void) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - future_t *future; - request_t *request; - bson_error_t error; - bson_t reply; - const char *server_reply = "{'cursor': {'firstBatch': [{'n': 123}], '_id': " - "0, 'ns': 'db.coll'}, 'ok': 1}"; - - server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "coll"); - - future = - future_collection_count_documents (collection, - tmp_bson ("{'x': 1}"), - tmp_bson ("{'limit': 2, 'skip': 1}"), - NULL, - &reply, - &error); - - request = mock_server_receives_msg ( - server, - 0, - tmp_bson ("{'aggregate': 'coll', 'pipeline': [{'$match': " - "{'x': 1}}, {'$skip': 1}, {'$limit': 2}, {'$group': " - "{'n': {'$sum': 1}}}]}")); - mock_server_replies_simple (request, server_reply); - ASSERT_OR_PRINT (123 == future_get_int64_t (future), error); - ASSERT_MATCH (&reply, server_reply); - - bson_destroy (&reply); - request_destroy (request); - future_destroy (future); - - future = - future_collection_count_documents (collection, - tmp_bson ("{}"), - tmp_bson ("{'limit': 2, 'skip': 1}"), - NULL, - &reply, - &error); - - /* even with an empty filter, we still prepend $match */ - request = mock_server_receives_msg ( - server, - 0, - tmp_bson ("{'aggregate': 'coll', 'pipeline': [{'$match': {}}, {'$skip': " - "1}, {'$limit': 2}, {'$group': " - "{'n': {'$sum': 1}}}]}")); - mock_server_replies_simple (request, server_reply); - ASSERT_OR_PRINT (123 == future_get_int64_t (future), error); - ASSERT_MATCH (&reply, server_reply); - bson_destroy (&reply); - request_destroy (request); - future_destroy (future); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_count_documents_live (void) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - int64_t count; - - client = test_framework_client_new (); - ASSERT (client); - - collection = mongoc_client_get_collection (client, "test", "test"); - ASSERT (collection); - - count = mongoc_collection_count_documents ( - collection, tmp_bson ("{}"), NULL, NULL, NULL, &error); - - ASSERT_OR_PRINT (count != -1, error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_estimated_document_count (void) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - future_t *future; - request_t *request; - bson_error_t error; - bson_t reply; - const char *server_reply = "{'n': 123, 'ok': 1}"; - - server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "coll"); - - future = future_collection_estimated_document_count ( - collection, tmp_bson ("{'limit': 2, 'skip': 1}"), NULL, &reply, &error); - - request = mock_server_receives_msg ( - server, 0, tmp_bson ("{'count': 'coll', 'limit': 2, 'skip': 1}")); - mock_server_replies_simple (request, server_reply); - ASSERT_OR_PRINT (123 == future_get_int64_t (future), error); - ASSERT_MATCH (&reply, server_reply); - - bson_destroy (&reply); - request_destroy (request); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_estimated_document_count_live (void) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - int64_t count; - - client = test_framework_client_new (); - ASSERT (client); - - collection = mongoc_client_get_collection (client, "test", "test"); - ASSERT (collection); - - count = mongoc_collection_estimated_document_count ( - collection, NULL, NULL, NULL, &error); - - ASSERT (count != -1); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_drop (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_write_concern_t *good_wc; - mongoc_write_concern_t *bad_wc; - bool wire_version_5; - bool r; - bson_error_t error; - bson_t *doc; - bson_t *opts = NULL; - - opts = bson_new (); - client = test_framework_client_new (); - ASSERT (client); - mongoc_client_set_error_api (client, 2); - - bad_wc = mongoc_write_concern_new (); - good_wc = mongoc_write_concern_new (); - - wire_version_5 = test_framework_max_wire_version_at_least (5); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_drop"); - ASSERT (collection); - - doc = BCON_NEW ("hello", "world"); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, doc, NULL, NULL, &error), - error); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - if (wire_version_5) { - /* invalid writeConcern */ - bad_wc->wtimeout = -10; - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, doc, NULL, NULL, &error), - error); - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - ASSERT (!mongoc_collection_drop_with_opts (collection, opts, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - bad_wc->wtimeout = 0; - error.code = 0; - error.domain = 0; - - /* valid writeConcern */ - mongoc_write_concern_set_w (good_wc, 1); - bson_reinit (opts); - mongoc_write_concern_append (good_wc, opts); - ASSERT_OR_PRINT ( - mongoc_collection_drop_with_opts (collection, opts, &error), error); - ASSERT (!error.code); - ASSERT (!error.domain); - - /* writeConcern that results in writeConcernError */ - mongoc_write_concern_set_w (bad_wc, 99); - - if (!test_framework_is_mongos ()) { /* skip if sharded */ - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, doc, NULL, NULL, &error), - error); - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - r = mongoc_collection_drop_with_opts (collection, opts, &error); - ASSERT (!r); - if (test_framework_is_replset ()) { /* replica set */ - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:"); - } else { /* standalone */ - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CMPINT (error.code, ==, 2); - } - } - } /* wire_version_5 */ - - bson_destroy (doc); - bson_destroy (opts); - mongoc_write_concern_destroy (good_wc); - mongoc_write_concern_destroy (bad_wc); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - - -static void -test_aggregate_bypass (void *context) -{ - mongoc_collection_t *data_collection; - mongoc_collection_t *out_collection; - mongoc_bulk_operation_t *bulk; - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - bson_t *pipeline; - bson_t *options; - char *collname; - char *dbname; - bson_t reply; - bool r; - int i; - char *json; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - dbname = gen_collection_name ("dbtest"); - collname = gen_collection_name ("data"); - database = mongoc_client_get_database (client, dbname); - data_collection = mongoc_database_get_collection (database, collname); - bson_free (collname); - - collname = gen_collection_name ("bypass"); - options = tmp_bson ( - "{'validator': {'number': {'$gte': 5}}, 'validationAction': 'error'}"); - out_collection = - mongoc_database_create_collection (database, collname, options, &error); - ASSERT_OR_PRINT (out_collection, error); - - bson_free (dbname); - bson_free (collname); - - /* Generate some example data */ - bulk = - mongoc_collection_create_bulk_operation_with_opts (data_collection, NULL); - - for (i = 0; i < 3; i++) { - bson_t *document; - json = bson_strdup_printf ("{'number': 3, 'high': %d }", i); - document = tmp_bson (json); - - mongoc_bulk_operation_insert (bulk, document); - - bson_free (json); - } - - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - ASSERT_OR_PRINT (r, error); - mongoc_bulk_operation_destroy (bulk); - - json = bson_strdup_printf ("[{'$out': '%s'}]", out_collection->collection); - pipeline = tmp_bson (json); - - cursor = mongoc_collection_aggregate ( - data_collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - ASSERT (cursor); - r = mongoc_cursor_next (cursor, &doc); - ASSERT (!r); - ASSERT (mongoc_cursor_error (cursor, &error)); - mongoc_cursor_destroy (cursor); - - options = tmp_bson ("{'bypassDocumentValidation': true}"); - cursor = mongoc_collection_aggregate ( - data_collection, MONGOC_QUERY_NONE, pipeline, options, NULL); - ASSERT (cursor); - ASSERT (!mongoc_cursor_error (cursor, &error)); - - ASSERT_OR_PRINT (mongoc_collection_drop (data_collection, &error), error); - ASSERT_OR_PRINT (mongoc_collection_drop (out_collection, &error), error); - - bson_destroy (&reply); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (data_collection); - mongoc_collection_destroy (out_collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - bson_free (json); -} - - -static void -test_aggregate (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - bool did_alternate = false; - bool r; - bson_t opts; - bson_t *pipeline; - bson_t *broken_pipeline; - bson_t *b; - bson_iter_t iter; - int i, j; - - client = test_framework_client_new (); - ASSERT (client); - - database = get_test_database (client); - ASSERT (database); - - collection = get_test_collection (client, "test_aggregate"); - ASSERT (collection); - - pipeline = BCON_NEW ("pipeline", - "[", - "{", - "$match", - "{", - "hello", - BCON_UTF8 ("world"), - "}", - "}", - "]"); - broken_pipeline = BCON_NEW ("pipeline", - "[", - "{", - "$asdf", - "{", - "foo", - BCON_UTF8 ("bar"), - "}", - "}", - "]"); - b = BCON_NEW ("hello", BCON_UTF8 ("world")); - - /* empty collection */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - ASSERT (cursor); - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - mongoc_cursor_destroy (cursor); - - /* empty collection */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - ASSERT (cursor); - - r = mongoc_cursor_next (cursor, &doc); - ASSERT (!r); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - mongoc_cursor_destroy (cursor); - - for (i = 0; i < 2; i++) { - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, b, NULL, NULL, &error), - error); - } - -again: - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, broken_pipeline, NULL, NULL); - ASSERT (cursor); - - r = mongoc_cursor_next (cursor, &doc); - ASSERT (!r); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT (error.code); - mongoc_cursor_destroy (cursor); - - for (i = 0; i < 2; i++) { - if (i % 2 == 0) { - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - ASSERT (cursor); - } else { - bson_init (&opts); - - BSON_APPEND_BOOL (&opts, "allowDiskUse", true); - - BSON_APPEND_INT32 (&opts, "batchSize", 10); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, &opts, NULL); - ASSERT (cursor); - - bson_destroy (&opts); - } - - for (j = 0; j < 2; j++) { - r = mongoc_cursor_next (cursor, &doc); - if (mongoc_cursor_error (cursor, &error)) { - fprintf ( - stderr, "[%d.%d] %s", error.domain, error.code, error.message); - - abort (); - } - - ASSERT (r); - ASSERT (doc); - - ASSERT (bson_iter_init_find (&iter, doc, "hello") && - BSON_ITER_HOLDS_UTF8 (&iter)); - } - - r = mongoc_cursor_next (cursor, &doc); - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "%s", error.message); - abort (); - } - - ASSERT (!r); - ASSERT (!doc); - - mongoc_cursor_destroy (cursor); - } - - if (!did_alternate) { - did_alternate = true; - bson_destroy (pipeline); - pipeline = BCON_NEW ( - "0", "{", "$match", "{", "hello", BCON_UTF8 ("world"), "}", "}"); - goto again; - } - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - bson_destroy (b); - bson_destroy (pipeline); - bson_destroy (broken_pipeline); -} - - -static void -test_aggregate_large (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_iter_t iter; - int32_t i; - uint32_t server_id; - mongoc_cursor_t *cursor; - bson_t *inserted_doc; - bson_error_t error; - bson_t *pipeline; - const bson_t *doc; - - client = test_framework_client_new (); - ASSERT (client); - - collection = get_test_collection (client, "test_aggregate_large"); - ASSERT (collection); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - /* ensure a few batches */ - inserted_doc = tmp_bson ("{'_id': 0}"); - - for (i = 0; i < 2000; i++) { - bson_iter_init_find (&iter, inserted_doc, "_id"); - bson_iter_overwrite_int32 (&iter, i); - mongoc_bulk_operation_insert (bulk, inserted_doc); - } - - server_id = mongoc_bulk_operation_execute (bulk, NULL, &error); - ASSERT_OR_PRINT (server_id > 0, error); - - pipeline = tmp_bson ("[{'$sort': {'_id': 1}}]"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - ASSERT (cursor); - - i = 0; - while (mongoc_cursor_next (cursor, &doc)) { - ASSERT (bson_iter_init_find (&iter, doc, "_id")); - ASSERT_CMPINT (i, ==, bson_iter_int32 (&iter)); - i++; - } - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - ASSERT_CMPINT (i, ==, 2000); - - mongoc_bulk_operation_destroy (bulk); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -typedef struct { - bool with_batch_size; - bool with_options; -} test_aggregate_context_t; - - -static const char * -options_json (test_aggregate_context_t *c) -{ - if (c->with_batch_size && c->with_options) { - return "{'foo': 1, 'batchSize': 11}"; - } else if (c->with_batch_size) { - return "{'batchSize': 11}"; - } else if (c->with_options) { - return "{'foo': 1}"; - } else { - return "{}"; - } -} - - -static void -test_aggregate_modern (void *data) -{ - test_aggregate_context_t *context = (test_aggregate_context_t *) data; - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - future_t *future; - request_t *request; - mongoc_cursor_t *cursor; - const bson_t *doc; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG - 1); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - cursor = mongoc_collection_aggregate (collection, - MONGOC_QUERY_NONE, - tmp_bson ("[{'a': 1}]"), - tmp_bson (options_json (context)), - NULL); - - ASSERT (cursor); - future = future_cursor_next (cursor, &doc); - - - /* "cursor" argument always sent if wire version >= 1 */ - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'aggregate': 'collection'," - " 'pipeline': [{'a': 1}]," - " 'cursor': %s %s}", - context->with_batch_size ? "{'batchSize': 11}" : "{'$empty': true}", - context->with_options ? ", 'foo': 1" : ""); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 42," - " 'ns': 'db.collection'," - " 'firstBatch': [{'_id': 123}]" - "}}"); - - ASSERT (future_get_bool (future)); - ASSERT_MATCH (doc, "{'_id': 123}"); - - request_destroy (request); - future_destroy (future); - - /* create a second batch to see if batch size is still 11 */ - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'getMore': 42," - "'collection': 'collection'," - "'batchSize': %s}", - context->with_batch_size ? "11" : "{'$exists': false}"); - - mock_server_replies_simple (request, - "{'ok': 1," - "'cursor': {" - "'id': 0," - "'ns': 'db.collection'," - "'nextBatch': [{'_id': 123}]" - "}}"); - - ASSERT (future_get_bool (future)); - ASSERT_MATCH (doc, "{'_id': 123}"); - - /* cursor is completed */ - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - - mongoc_cursor_destroy (cursor); - request_destroy (request); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_aggregate_w_server_id (void) -{ - mock_rs_t *rs; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *opts; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - - rs = mock_rs_with_autoismaster (WIRE_VERSION_MIN, - true /* has primary */, - 1 /* secondary */, - 0 /* arbiters */); - - mock_rs_run (rs); - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - /* use serverId instead of prefs to select the secondary */ - opts = tmp_bson ("{'serverId': 2}"); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson (NULL), opts, NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_rs_receives_command (rs, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'aggregate': 'collection'," - " 'cursor': {}," - " 'serverId': {'$exists': false}}"); - - ASSERT (mock_rs_request_is_to_secondary (rs, request)); - mock_rs_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'ns': 'db.collection'," - " 'firstBatch': [{}]}}"); - ASSERT_OR_PRINT (future_get_bool (future), cursor->error); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_rs_destroy (rs); -} - - -static void -test_aggregate_w_server_id_sharded (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_t *opts; - const bson_t *doc; - future_t *future; - request_t *request; - - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - opts = tmp_bson ("{'serverId': 1}"); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson (NULL), opts, NULL); - - future = future_cursor_next (cursor, &doc); - - /* does NOT set slave ok, since this is a sharded topology */ - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_NONE, - "{'aggregate': 'collection', 'serverId': {'$exists': false}}"); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'ns': 'db.collection'," - " 'firstBatch': [{}]}}"); - - ASSERT_OR_PRINT (future_get_bool (future), cursor->error); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_aggregate_server_id_option (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *q; - bson_error_t error; - mongoc_cursor_t *cursor; - const bson_t *doc; - - client = test_framework_client_new (); - collection = mongoc_client_get_collection (client, "db", "collection"); - q = tmp_bson (NULL); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, q, tmp_bson ("{'serverId': 'foo'}"), NULL); - - ASSERT_ERROR_CONTAINS (cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "must be an integer"); - - mongoc_cursor_destroy (cursor); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, q, tmp_bson ("{'serverId': 0}"), NULL); - - ASSERT_ERROR_CONTAINS (cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "must be >= 1"); - - mongoc_cursor_destroy (cursor); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, q, tmp_bson ("{'serverId': 1}"), NULL); - - mongoc_cursor_next (cursor, &doc); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_aggregate_is_sent_to_primary_w_dollar_out (void *ctx) -{ - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - bson_t *pipeline; - mongoc_collection_t *collection; - mongoc_read_prefs_t *read_prefs; - const bson_t *doc = NULL; - - capture_logs (true); - - client = test_framework_client_new (); - BSON_ASSERT (client); - - pipeline = tmp_bson ("{ 'pipeline': [ { '$out' : 'coll2' } ] }"); - collection = mongoc_client_get_collection (client, "test", "coll"); - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_SLAVE_OK, pipeline, NULL, read_prefs); - - ASSERT (cursor); - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (!mongoc_cursor_error (cursor, &error)); - - mongoc_cursor_destroy (cursor); - mongoc_read_prefs_destroy (read_prefs); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_SLAVE_OK, pipeline, NULL, read_prefs); - - ASSERT (cursor); - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (!mongoc_cursor_error (cursor, &error)); - - ASSERT_CAPTURED_LOG ("mongoc_collection_aggregate", - MONGOC_LOG_LEVEL_WARNING, - "Overriding read preference to primary."); - - capture_logs (false); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); - mongoc_collection_destroy (collection); - mongoc_read_prefs_destroy (read_prefs); -} - - -static void -test_validate (void *ctx) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_iter_t iter; - bson_error_t error; - bson_t doc = BSON_INITIALIZER; - bson_t opts = BSON_INITIALIZER; - bson_t reply; - bool r; - const uint32_t expected_err_domain = MONGOC_ERROR_BSON; - const uint32_t expected_err_code = MONGOC_ERROR_BSON_INVALID; - - client = test_framework_client_new (); - ASSERT (client); - - collection = get_test_collection (client, "test_validate"); - ASSERT (collection); - - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, &doc, NULL, NULL, &error), - error); - - BSON_APPEND_BOOL (&opts, "full", true); - - ASSERT_OR_PRINT ( - mongoc_collection_validate (collection, &opts, &reply, &error), error); - - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "valid")); - - bson_destroy (&reply); - - /* Make sure we don't segfault when reply is NULL */ - ASSERT_OR_PRINT ( - mongoc_collection_validate (collection, &opts, NULL, &error), error); - - bson_reinit (&opts); - BSON_APPEND_UTF8 (&opts, "full", "bad_value"); - - /* invalidate reply */ - reply.len = 0; - BSON_ASSERT (!bson_validate (&reply, BSON_VALIDATE_NONE, NULL)); - - r = mongoc_collection_validate (collection, &opts, &reply, &error); - BSON_ASSERT (!r); - BSON_ASSERT (error.domain == expected_err_domain); - BSON_ASSERT (error.code == expected_err_code); - - /* check that reply has been initialized */ - BSON_ASSERT (bson_validate (&reply, 0, NULL)); - - /* Make sure we don't segfault when reply is NULL */ - memset (&error, 0, sizeof (error)); - r = mongoc_collection_validate (collection, &opts, NULL, &error); - BSON_ASSERT (!r); - BSON_ASSERT (error.domain == expected_err_domain); - BSON_ASSERT (error.code == expected_err_code); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&reply); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&doc); - bson_destroy (&opts); -} - - -static void -test_rename (void) -{ - mongoc_client_t *client; - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_write_concern_t *bad_wc; - mongoc_write_concern_t *good_wc; - bool wire_version_5; - bool r; - bson_error_t error; - char *dbname; - bson_t doc = BSON_INITIALIZER; - bson_t *opts = NULL; - char **name; - char **names; - bool found; - - client = test_framework_client_new (); - ASSERT (client); - mongoc_client_set_error_api (client, 2); - opts = bson_new (); - - bad_wc = mongoc_write_concern_new (); - good_wc = mongoc_write_concern_new (); - - wire_version_5 = test_framework_max_wire_version_at_least (5); - - dbname = gen_collection_name ("dbtest"); - database = mongoc_client_get_database (client, dbname); - collection = mongoc_database_get_collection (database, "test_rename"); - - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, &doc, NULL, NULL, &error), - error); - - ASSERT_OR_PRINT (mongoc_collection_rename ( - collection, dbname, "test_rename.2", false, &error), - error); - - names = - mongoc_database_get_collection_names_with_opts (database, NULL, &error); - ASSERT_OR_PRINT (names, error); - found = false; - for (name = names; *name; ++name) { - if (!strcmp (*name, "test_rename.2")) { - found = true; - } - - bson_free (*name); - } - - ASSERT (found); - ASSERT_CMPSTR (mongoc_collection_get_name (collection), "test_rename.2"); - - if (wire_version_5) { - /* invalid writeConcern */ - bad_wc->wtimeout = -10; - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - ASSERT (!mongoc_collection_rename_with_opts ( - collection, dbname, "test_rename.3", false, opts, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - ASSERT_CMPSTR (mongoc_collection_get_name (collection), "test_rename.2"); - - bad_wc->wtimeout = 0; - error.code = 0; - error.domain = 0; - - /* valid writeConcern on all configs */ - mongoc_write_concern_set_w (good_wc, 1); - bson_reinit (opts); - mongoc_write_concern_append (good_wc, opts); - r = mongoc_collection_rename_with_opts ( - collection, dbname, "test_rename.3", false, opts, &error); - ASSERT_OR_PRINT (r, error); - ASSERT_CMPSTR (mongoc_collection_get_name (collection), "test_rename.3"); - - ASSERT (!error.code); - ASSERT (!error.domain); - - /* writeConcern that results in writeConcernError */ - mongoc_write_concern_set_w (bad_wc, 99); - - if (!test_framework_is_mongos ()) { - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - r = mongoc_collection_rename_with_opts ( - collection, dbname, "test_rename.4", false, opts, &error); - ASSERT (!r); - - /* check that collection name has not changed */ - ASSERT_CMPSTR (mongoc_collection_get_name (collection), - "test_rename.3"); - if (test_framework_is_replset ()) { /* replica set */ - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:"); - } else { /* standalone */ - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CMPINT (error.code, ==, 2); - } - } - } /* wire_version_5 */ - - ASSERT_OR_PRINT (mongoc_database_drop (database, &error), error); - - bson_free (names); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_write_concern_destroy (good_wc); - mongoc_write_concern_destroy (bad_wc); - mongoc_client_destroy (client); - bson_free (dbname); - bson_destroy (&doc); - bson_destroy (opts); -} - - -static void -test_stats (void) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - bson_iter_t iter; - bson_t stats; - bson_t doc = BSON_INITIALIZER; - - client = test_framework_client_new (); - ASSERT (client); - - collection = get_test_collection (client, "test_stats"); - ASSERT (collection); - - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, &doc, NULL, NULL, &error), - error); - - BEGIN_IGNORE_DEPRECATIONS - ASSERT_OR_PRINT (mongoc_collection_stats (collection, NULL, &stats, &error), - error); - END_IGNORE_DEPRECATIONS - - BSON_ASSERT (bson_iter_init_find (&iter, &stats, "ns")); - - BSON_ASSERT (bson_iter_init_find (&iter, &stats, "count")); - BSON_ASSERT (bson_iter_as_int64 (&iter) >= 1); - - bson_destroy (&stats); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&doc); -} - - -static void -test_stats_read_pref (void) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_read_prefs_t *prefs; - future_t *future; - request_t *request; - bson_error_t error; - bson_t stats; - - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_collection_set_read_prefs (collection, prefs); - future = future_collection_stats (collection, NULL, &stats, &error); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'collStats': 'collection'}," - " '$readPreference': {'mode': 'secondary'}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - - future_destroy (future); - bson_destroy (&stats); - mongoc_read_prefs_destroy (prefs); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_find_and_modify_write_concern (int wire_version) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - mock_server_t *server; - request_t *request; - future_t *future; - bson_error_t error; - bson_t *update; - bson_t doc = BSON_INITIALIZER; - bson_t reply; - mongoc_write_concern_t *write_concern; - - server = mock_server_new (); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT (client); - - collection = - mongoc_client_get_collection (client, "test", "test_find_and_modify"); - - auto_ismaster (server, - wire_version, /* max_wire_version */ - 48000000, /* max_message_size */ - 16777216, /* max_bson_size */ - 1000); /* max_write_batch_size */ - - BSON_APPEND_INT32 (&doc, "superduper", 77889); - - update = BCON_NEW ("$set", "{", "superduper", BCON_INT32 (1234), "}"); - - write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_w (write_concern, 42); - mongoc_collection_set_write_concern (collection, write_concern); - future = future_collection_find_and_modify ( - collection, &doc, NULL, update, NULL, false, false, true, &reply, &error); - - if (wire_version >= 4) { - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_NONE, - "{ 'findAndModify' : 'test_find_and_modify', " - "'query' : { 'superduper' : 77889 }," - "'update' : { '$set' : { 'superduper' : 1234 } }," - "'new' : true," - "'writeConcern' : { 'w' : 42 } }"); - } else { - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_NONE, - "{ 'findAndModify' : 'test_find_and_modify', " - "'query' : { 'superduper' : 77889 }," - "'update' : { '$set' : { 'superduper' : 1234 } }," - "'new' : true }"); - } - - mock_server_replies_simple (request, "{ 'value' : null, 'ok' : 1 }"); - ASSERT_OR_PRINT (future_get_bool (future), error); - - future_destroy (future); - - bson_destroy (&reply); - bson_destroy (update); - - request_destroy (request); - mongoc_write_concern_destroy (write_concern); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); - bson_destroy (&doc); -} - -static void -test_find_and_modify_write_concern_wire_32 (void) -{ - test_find_and_modify_write_concern (4); -} - -static void -test_find_and_modify_write_concern_wire_pre_32 (void) -{ - test_find_and_modify_write_concern (3); -} - -static void -test_find_and_modify (void) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - bson_iter_t iter; - bson_iter_t citer; - bson_t *update; - bson_t doc = BSON_INITIALIZER; - bson_t reply; - - client = test_framework_client_new (); - ASSERT (client); - - collection = get_test_collection (client, "test_find_and_modify"); - ASSERT (collection); - - BSON_APPEND_INT32 (&doc, "superduper", 77889); - - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, &doc, NULL, NULL, &error), - error); - - update = BCON_NEW ("$set", "{", "superduper", BCON_INT32 (1234), "}"); - - ASSERT_OR_PRINT (mongoc_collection_find_and_modify (collection, - &doc, - NULL, - update, - NULL, - false, - false, - true, - &reply, - &error), - error); - - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "value")); - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - BSON_ASSERT (bson_iter_recurse (&iter, &citer)); - BSON_ASSERT (bson_iter_find (&citer, "superduper")); - BSON_ASSERT (BSON_ITER_HOLDS_INT32 (&citer)); - BSON_ASSERT (bson_iter_int32 (&citer) == 1234); - - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "lastErrorObject")); - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - BSON_ASSERT (bson_iter_recurse (&iter, &citer)); - BSON_ASSERT (bson_iter_find (&citer, "updatedExisting")); - BSON_ASSERT (BSON_ITER_HOLDS_BOOL (&citer)); - BSON_ASSERT (bson_iter_bool (&citer)); - - bson_destroy (&reply); - bson_destroy (update); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&doc); -} - - -static void -test_large_return (void *ctx) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc = NULL; - bson_oid_t oid; - bson_t insert_doc = BSON_INITIALIZER; - bson_t query = BSON_INITIALIZER; - size_t len; - char *str; - bool r; - - client = test_framework_client_new (); - ASSERT (client); - - collection = get_test_collection (client, "test_large_return"); - ASSERT (collection); - - len = 1024 * 1024 * 4; - str = (char *) bson_malloc (len); - memset (str, (int) ' ', len); - str[len - 1] = '\0'; - - bson_oid_init (&oid, NULL); - BSON_APPEND_OID (&insert_doc, "_id", &oid); - BSON_APPEND_UTF8 (&insert_doc, "big", str); - - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - collection, &insert_doc, NULL, NULL, &error), - error); - - bson_destroy (&insert_doc); - - BSON_APPEND_OID (&query, "_id", &oid); - - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, NULL, NULL); - BSON_ASSERT (cursor); - bson_destroy (&query); - - ASSERT_CURSOR_NEXT (cursor, &doc); - BSON_ASSERT (doc); - - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (!r); - - mongoc_cursor_destroy (cursor); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_free (str); -} - - -static void -test_many_return (void) -{ - enum { N_BSONS = 5000 }; - - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc = NULL; - bson_oid_t oid; - bson_t query = BSON_INITIALIZER; - bson_t *docs[N_BSONS]; - bool r; - int i; - - client = test_framework_client_new (); - ASSERT (client); - - collection = get_test_collection (client, "test_many_return"); - ASSERT (collection); - - for (i = 0; i < N_BSONS; i++) { - docs[i] = bson_new (); - bson_oid_init (&oid, NULL); - BSON_APPEND_OID (docs[i], "_id", &oid); - } - - ASSERT_OR_PRINT (mongoc_collection_insert_many (collection, - (const bson_t **) docs, - (uint32_t) N_BSONS, - NULL, - NULL, - &error), - error); - - cursor = mongoc_collection_find_with_opts (collection, &query, NULL, NULL); - BSON_ASSERT (cursor); - BSON_ASSERT (mongoc_cursor_more (cursor)); - bson_destroy (&query); - - i = 0; - - while (mongoc_cursor_next (cursor, &doc)) { - BSON_ASSERT (doc); - i++; - BSON_ASSERT (mongoc_cursor_more (cursor)); - } - - BSON_ASSERT (i == N_BSONS); - - BSON_ASSERT (!mongoc_cursor_error (cursor, &error)); - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (!r); - BSON_ASSERT (!mongoc_cursor_more (cursor)); - /* mongoc_cursor_next after done is considered an error */ - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot advance a completed or failed cursor") - - mongoc_cursor_destroy (cursor); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - destroy_all (docs, N_BSONS); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static bool -insert_one (mongoc_collection_t *collection, - const bson_t *doc, - const bson_t *opts, - bson_error_t *error) -{ - return mongoc_collection_insert_one (collection, doc, opts, NULL, error); -} - - -static bool -insert_many (mongoc_collection_t *collection, - const bson_t *doc, - const bson_t *opts, - bson_error_t *error) -{ - return mongoc_collection_insert_many ( - collection, &doc, 1, opts, NULL, error); -} - - -typedef bool (*insert_fn_t) (mongoc_collection_t *, - const bson_t *, - const bson_t *, - bson_error_t *); - - -static void -_test_insert_validate (insert_fn_t insert_fn) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - collection = get_test_collection (client, "test_insert_validate"); - - BSON_ASSERT (!insert_fn (collection, tmp_bson ("{'$': 1}"), NULL, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document"); - - BSON_ASSERT (!insert_fn (collection, - tmp_bson ("{'$': 1}"), - tmp_bson ("{'validate': false}"), - &error)); - ASSERT_CMPUINT32 (error.domain, ==, (uint32_t) MONGOC_ERROR_SERVER); - - BSON_ASSERT (!insert_fn (collection, - tmp_bson ("{'$': 1}"), - tmp_bson ("{'validate': 'foo'}"), - &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid type for option \"validate\": \"UTF8\""); - - BSON_ASSERT (insert_fn ( - collection, tmp_bson ("{'a': 1}"), tmp_bson ("{'validate': 0}"), &error)); - - /* BSON_VALIDATE_DOT_KEYS */ - BSON_ASSERT (!insert_fn (collection, - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': 4}"), - &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document for insert: keys cannot contain \".\": \"a.a\""); - - /* BSON_VALIDATE_DOT_KEYS is set by default */ - BSON_ASSERT (!insert_fn ( - collection, tmp_bson ("{'a.a': 1}"), tmp_bson ("{}"), &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document for insert: keys cannot contain \".\": \"a.a\""); - - /* {validate: true} is still prohibited */ - BSON_ASSERT (!insert_fn (collection, - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': true}"), - &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid option \"validate\": true"); - - - BSON_ASSERT (insert_fn (collection, - tmp_bson ("{'a.a': 1}"), - tmp_bson ("{'validate': 0}"), - &error)); - - BSON_ASSERT (insert_fn (collection, - tmp_bson ("{'a': 1}"), - tmp_bson ("{'validate': 31}"), - &error)); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_insert_bulk_validate (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - const bson_t *docs[] = {tmp_bson ("{'a': 1}"), tmp_bson ("{'$': 2}")}; - - BEGIN_IGNORE_DEPRECATIONS - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - collection = get_test_collection (client, "test_insert_validate"); - - /* Invalid documents, validation. */ - BSON_ASSERT (!mongoc_collection_insert_bulk (collection, - MONGOC_INSERT_NONE, - docs, - 2, - NULL /* write concern */, - &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid document"); - - /* Invalid documents, no validation. */ - BSON_ASSERT (!mongoc_collection_insert_bulk ( - collection, - (mongoc_insert_flags_t) MONGOC_INSERT_NO_VALIDATE, - docs, - 2, - NULL /* write concern */, - &error)); - ASSERT_CMPUINT32 (error.domain, ==, (uint32_t) MONGOC_ERROR_SERVER); - - /* Valid document, validation. */ - ASSERT_OR_PRINT ( - mongoc_collection_insert_bulk (collection, - MONGOC_INSERT_NONE, - docs, - 1 /* don't include invalid second doc. */, - NULL /* write concern */, - &error), - error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - END_IGNORE_DEPRECATIONS -} - - -static void -test_insert_one_validate (void) -{ - _test_insert_validate (insert_one); -} - - -static void -test_insert_many_validate (void) -{ - _test_insert_validate (insert_many); -} - - -/* use a mock server to test the "limit" parameter */ -static void -test_find_limit (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "test", "test"); - - /* test mongoc_collection_find and mongoc_collection_find_with_opts */ - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0 /* skip */, - 2 /* limit */, - 0 /* batch_size */, - tmp_bson ("{}"), - NULL, - NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_query (server, - "test.test", - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 2 /* n_return */, - "{}", - NULL); - - mock_server_replies_simple (request, "{}"); - BSON_ASSERT (future_get_bool (future)); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - - cursor = mongoc_collection_find_with_opts ( - collection, - tmp_bson ("{}"), - tmp_bson ("{'limit': {'$numberLong': '2'}}"), - NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_query (server, - "test.test", - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 2 /* n_return */, - "{}", - NULL); - - mock_server_replies_simple (request, "{}"); - BSON_ASSERT (future_get_bool (future)); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -/* use a mock server to test the "batch_size" parameter */ -static void -test_find_batch_size (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "test", "test"); - - /* test mongoc_collection_find and mongoc_collection_find_with_opts */ - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0 /* skip */, - 0 /* limit */, - 2 /* batch_size */, - tmp_bson ("{}"), - NULL, - NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_query (server, - "test.test", - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 2 /* n_return */, - "{}", - NULL); - - mock_server_replies_simple (request, "{}"); - BSON_ASSERT (future_get_bool (future)); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - - cursor = mongoc_collection_find_with_opts ( - collection, - tmp_bson ("{}"), - tmp_bson ("{'batchSize': {'$numberLong': '2'}}"), - NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_query (server, - "test.test", - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 2 /* n_return */, - "{}", - NULL); - - mock_server_replies_simple (request, "{}"); - BSON_ASSERT (future_get_bool (future)); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_command_fq (void *context) -{ - mongoc_client_t *client; - mongoc_cursor_t *cursor; - const bson_t *doc = NULL; - bson_iter_t iter; - bson_t *cmd; - bool r; - - client = test_framework_client_new (); - ASSERT (client); - - cmd = tmp_bson ("{ 'dbstats': 1}"); - - cursor = mongoc_client_command (client, - "sometest.$cmd", - MONGOC_QUERY_SLAVE_OK, - 0, - -1, - 0, - cmd, - NULL, - NULL); - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (r); - - if (bson_iter_init_find (&iter, doc, "db") && BSON_ITER_HOLDS_UTF8 (&iter)) { - ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL), "sometest"); - } else { - fprintf (stderr, "dbstats didn't return 'db' key?"); - abort (); - } - - - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (!r); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); -} - -static void -test_get_index_info (void) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_index_opt_t opt1; - mongoc_index_opt_t opt2; - bson_error_t error = {0}; - mongoc_cursor_t *cursor; - const bson_t *indexinfo; - bson_t indexkey1; - bson_t indexkey2; - bson_t indexkey3; - bson_t indexkey4; - bson_t indexkey5; - bson_t dummy = BSON_INITIALIZER; - bson_iter_t idx_spec_iter; - bson_iter_t idx_spec_iter_copy; - bool r; - const char *cur_idx_name; - char *idx1_name = NULL; - char *idx2_name = NULL; - char *idx3_name = NULL; - char *idx4_name = NULL; - char *idx5_name = NULL; - const char *id_idx_name = "_id_"; - int num_idxs = 0; - - client = test_framework_client_new (); - ASSERT (client); - - collection = get_test_collection (client, "test_get_index_info"); - ASSERT (collection); - - /* - * Try it on a collection that doesn't exist. - */ - cursor = mongoc_collection_find_indexes_with_opts (collection, NULL); - - ASSERT (!mongoc_cursor_next (cursor, &indexinfo)); - ASSERT (!mongoc_cursor_error (cursor, &error)); - - mongoc_cursor_destroy (cursor); - - /* insert a dummy document so that the collection actually exists */ - r = mongoc_collection_insert_one (collection, &dummy, NULL, NULL, &error); - ASSERT (r); - - /* Try it on a collection with no secondary indexes. - * We should just get back the index on _id. - */ - cursor = mongoc_collection_find_indexes_with_opts (collection, NULL); - ASSERT (!mongoc_cursor_error (cursor, &error)); - - while (mongoc_cursor_next (cursor, &indexinfo)) { - if (bson_iter_init (&idx_spec_iter, indexinfo) && - bson_iter_find (&idx_spec_iter, "name") && - BSON_ITER_HOLDS_UTF8 (&idx_spec_iter) && - (cur_idx_name = bson_iter_utf8 (&idx_spec_iter, NULL))) { - BSON_ASSERT (0 == strcmp (cur_idx_name, id_idx_name)); - ++num_idxs; - } else { - BSON_ASSERT (false); - } - } - - BSON_ASSERT (1 == num_idxs); - - mongoc_cursor_destroy (cursor); - - num_idxs = 0; - indexinfo = NULL; - - bson_init (&indexkey1); - BSON_APPEND_INT32 (&indexkey1, "raspberry", 1); - idx1_name = mongoc_collection_keys_to_index_string (&indexkey1); - ASSERT (strcmp (idx1_name, "raspberry_1") == 0); - mongoc_index_opt_init (&opt1); - opt1.background = true; - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &indexkey1, &opt1, &error), - error); - bson_destroy (&indexkey1); - - bson_init (&indexkey2); - BSON_APPEND_INT32 (&indexkey2, "snozzberry", 1); - idx2_name = mongoc_collection_keys_to_index_string (&indexkey2); - ASSERT (strcmp (idx2_name, "snozzberry_1") == 0); - mongoc_index_opt_init (&opt2); - opt2.unique = true; - ASSERT_OR_PRINT ( - mongoc_collection_create_index (collection, &indexkey2, &opt2, &error), - error); - bson_destroy (&indexkey2); - - /* - * Now we try again after creating two indexes. - */ - cursor = mongoc_collection_find_indexes_with_opts (collection, NULL); - ASSERT (!mongoc_cursor_error (cursor, &error)); - - while (mongoc_cursor_next (cursor, &indexinfo)) { - if (bson_iter_init (&idx_spec_iter, indexinfo) && - bson_iter_find (&idx_spec_iter, "name") && - BSON_ITER_HOLDS_UTF8 (&idx_spec_iter) && - (cur_idx_name = bson_iter_utf8 (&idx_spec_iter, NULL))) { - if (0 == strcmp (cur_idx_name, idx1_name)) { - /* need to use the copy of the iter since idx_spec_iter may have - * gone - * past the key we want */ - ASSERT (bson_iter_init_find ( - &idx_spec_iter_copy, indexinfo, "background")); - ASSERT (BSON_ITER_HOLDS_BOOL (&idx_spec_iter_copy)); - ASSERT (bson_iter_bool (&idx_spec_iter_copy)); - } else if (0 == strcmp (cur_idx_name, idx2_name)) { - ASSERT ( - bson_iter_init_find (&idx_spec_iter_copy, indexinfo, "unique")); - ASSERT (BSON_ITER_HOLDS_BOOL (&idx_spec_iter_copy)); - ASSERT (bson_iter_bool (&idx_spec_iter_copy)); - } else { - ASSERT ((0 == strcmp (cur_idx_name, id_idx_name))); - } - - ++num_idxs; - } else { - BSON_ASSERT (false); - } - } - - BSON_ASSERT (3 == num_idxs); - - mongoc_cursor_destroy (cursor); - - /* - * Test that index strings are formed correctly when using an INT64 - * for direction. - */ - bson_init (&indexkey3); - BSON_APPEND_INT64 (&indexkey3, "blackberry", 1); - idx3_name = mongoc_collection_keys_to_index_string (&indexkey3); - ASSERT ((0 == strcmp (idx3_name, "blackberry_1"))); - bson_destroy (&indexkey3); - - bson_init (&indexkey4); - BSON_APPEND_INT64 (&indexkey4, "blueberry", -1); - idx4_name = mongoc_collection_keys_to_index_string (&indexkey4); - ASSERT ((0 == strcmp (idx4_name, "blueberry_-1"))); - bson_destroy (&indexkey4); - - /* - * Test that index string is NULL when an incorrect BSON type is - * used for direction. - */ - bson_init (&indexkey5); - BSON_APPEND_DOUBLE (&indexkey5, "strawberry", 1.0f); - idx5_name = mongoc_collection_keys_to_index_string (&indexkey5); - ASSERT ((idx5_name == NULL)); - bson_destroy (&indexkey5); - - bson_free (idx1_name); - bson_free (idx2_name); - bson_free (idx3_name); - bson_free (idx4_name); - bson_free (idx5_name); - - bson_destroy (&dummy); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_find_indexes_err (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - future_t *future; - request_t *request; - mongoc_cursor_t *cursor; - bson_error_t error; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - mongoc_client_set_error_api (client, 2); - collection = mongoc_client_get_collection (client, "db", "collection"); - - future = future_collection_find_indexes_with_opts (collection, NULL); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'listIndexes': 'collection'}"); - - mock_server_replies_simple (request, - "{'ok': 0, 'code': 1234567, 'errmsg': 'foo'}"); - cursor = future_get_mongoc_cursor_ptr (future); - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 1234567, "foo"); - - mongoc_cursor_destroy (cursor); - request_destroy (request); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_aggregate_install (TestSuite *suite) -{ - static test_aggregate_context_t test_aggregate_contexts[2][2]; - - int with_batch_size, with_options; - char *name; - test_aggregate_context_t *context; - - for (with_batch_size = 0; with_batch_size < 2; with_batch_size++) { - for (with_options = 0; with_options < 2; with_options++) { - context = &test_aggregate_contexts[with_batch_size][with_options]; - - context->with_batch_size = (bool) with_batch_size; - context->with_options = (bool) with_options; - - name = bson_strdup_printf ( - "/Collection/aggregate/%s/%s", - context->with_batch_size ? "batch_size" : "no_batch_size", - context->with_options ? "with_options" : "no_options"); - - TestSuite_AddWC ( - suite, name, test_aggregate_modern, NULL, (void *) context); - bson_free (name); - } - } -} - - -static void -test_find_read_concern (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_read_concern_t *rc; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - - server = mock_server_with_autoismaster (WIRE_VERSION_READ_CONCERN); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "test", "test"); - - /* No read_concern set - test find and find_with_opts */ - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 0 /* limit */, - 0 /* batch_size */, - tmp_bson ("{}"), - NULL, - NULL); - - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{'find' : 'test', 'filter' : { } }"); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'test.test'," - " 'firstBatch': [{'_id': 123}]}}"); - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - - /* readConcernLevel = local */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_LOCAL); - mongoc_collection_set_read_concern (collection, rc); - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 0 /* limit */, - 0 /* batch_size */, - tmp_bson ("{}"), - NULL, - NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{" - " 'find' : 'test'," - " 'filter' : { }," - " 'readConcern': {" - " 'level': 'local'" - " }" - "}"); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'test.test'," - " 'firstBatch': [{'_id': 123}]}}"); - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_read_concern_destroy (rc); - - /* readConcernLevel = random */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, "random"); - mongoc_collection_set_read_concern (collection, rc); - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 0 /* limit */, - 0 /* batch_size */, - tmp_bson ("{}"), - NULL, - NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{" - " 'find' : 'test'," - " 'filter' : { }," - " 'readConcern': {" - " 'level': 'random'" - " }" - "}"); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'test.test'," - " 'firstBatch': [{'_id': 123}]}}"); - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_read_concern_destroy (rc); - - /* empty readConcernLevel doesn't send anything */ - rc = mongoc_read_concern_new (); - mongoc_collection_set_read_concern (collection, rc); - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 0 /* limit */, - 0 /* batch_size */, - tmp_bson ("{}"), - NULL, - NULL); - - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{" - " 'find' : 'test'," - " 'filter' : { }," - " 'readConcern': { '$exists': false }" - "}"); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'test.test'," - " 'firstBatch': [{'_id': 123}]}}"); - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_read_concern_destroy (rc); - - /* readConcernLevel = NULL doesn't send anything */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, NULL); - mongoc_collection_set_read_concern (collection, rc); - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_SLAVE_OK, - 0 /* skip */, - 0 /* limit */, - 0 /* batch_size */, - tmp_bson ("{}"), - NULL, - NULL); - - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{" - " 'find' : 'test'," - " 'filter' : { }," - " 'readConcern': { '$exists': false }" - "}"); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'test.test'," - " 'firstBatch': [{'_id': 123}]}}"); - ASSERT (future_get_bool (future)); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_read_concern_destroy (rc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_getmore_read_concern_live (void *ctx) -{ - mongoc_client_t *client; - mongoc_read_concern_t *rc; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *insert_doc; - mongoc_cursor_t *cursor; - mongoc_write_concern_t *wc; - const bson_t *doc; - bson_error_t error; - int i = 0; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_read_concern"); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_LOCAL); - mongoc_collection_set_read_concern (collection, rc); - - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_MAJORITY); - mongoc_collection_set_write_concern (collection, wc); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - insert_doc = tmp_bson ("{'a': 1}"); - - for (i = 5000; i > 0; i--) { - mongoc_bulk_operation_insert_with_opts (bulk, insert_doc, NULL, NULL); - } - - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, NULL, &error), error); - mongoc_bulk_operation_destroy (bulk); - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), NULL, NULL); - - while (mongoc_cursor_next (cursor, &doc)) { - i++; - } - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - ASSERT_CMPINT (i, ==, 5000); - mongoc_cursor_destroy (cursor); - - mongoc_read_concern_destroy (rc); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_aggregate_secondary (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_read_prefs_t *pref; - bson_error_t error; - mongoc_cursor_t *cursor; - const bson_t *doc; - - client = test_framework_client_new (); - collection = get_test_collection (client, "aggregate_secondary"); - pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson ("[]"), NULL, pref); - - ASSERT (cursor); - mongoc_cursor_next (cursor, &doc); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - if (test_framework_is_replset ()) { - ASSERT (test_framework_server_is_secondary ( - client, mongoc_cursor_get_hint (cursor))); - } - - mongoc_read_prefs_destroy (pref); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_aggregate_secondary_sharded (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_read_prefs_t *pref; - bson_error_t error; - mongoc_cursor_t *cursor; - future_t *future; - request_t *request; - const bson_t *doc; - - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson ("[]"), NULL, pref); - - ASSERT (cursor); - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'aggregate': 'collection', 'pipeline': []}," - " '$readPreference': {'mode': 'secondary'}}"); - - mock_server_replies_simple (request, - "{ 'ok':1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': []}}"); - - ASSERT (!future_get_bool (future)); /* cursor_next returns false */ - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_read_prefs_destroy (pref); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_aggregate_read_concern (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_read_concern_t *rc; - future_t *future; - request_t *request; - mongoc_cursor_t *cursor; - const bson_t *doc; - - server = mock_server_with_autoismaster (WIRE_VERSION_READ_CONCERN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - /* No readConcern */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson ("[{'a': 1}]"), NULL, NULL); - - ASSERT (cursor); - future = future_cursor_next (cursor, &doc); - - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{" - " 'aggregate' : 'collection'," - " 'pipeline' : [{" - " 'a' : 1" - " }]," - " 'cursor' : { }," - " 'readConcern': { '$exists': false }" - "}"); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{'_id': 123}]" - "}}"); - - ASSERT (future_get_bool (future)); - ASSERT_MATCH (doc, "{'_id': 123}"); - - /* cursor is completed */ - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - mongoc_cursor_destroy (cursor); - request_destroy (request); - future_destroy (future); - - /* readConcern: majority */ - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_collection_set_read_concern (collection, rc); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson ("[{'a': 1}]"), NULL, NULL); - - ASSERT (cursor); - future = future_cursor_next (cursor, &doc); - - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{" - " 'aggregate' : 'collection'," - " 'pipeline' : [{" - " 'a' : 1" - " }]," - " 'cursor' : { }," - " 'readConcern': { 'level': 'majority'}" - "}"); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{'_id': 123}]" - "}}"); - - ASSERT (future_get_bool (future)); - ASSERT_MATCH (doc, "{'_id': 123}"); - - /* cursor is completed */ - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - mongoc_cursor_destroy (cursor); - request_destroy (request); - future_destroy (future); - - mongoc_read_concern_destroy (rc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_aggregate_with_collation (int wire) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - future_t *future; - request_t *request; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - - server = mock_server_with_autoismaster (wire); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - cursor = - mongoc_collection_aggregate (collection, - MONGOC_QUERY_NONE, - tmp_bson ("[{'a': 1}]"), - tmp_bson ("{'collation': {'locale': 'en'}}"), - NULL); - - future = future_cursor_next (cursor, &doc); - - if (wire == WIRE_VERSION_COLLATION) { - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'aggregate': 'collection'," - " 'pipeline': [{'a': 1}]," - " 'collation': {'locale': 'en'}}"); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{'_id': 123}]" - "}}"); - ASSERT (future_get_bool (future)); - ASSERT_MATCH (doc, "{'_id': 123}"); - /* cursor is completed */ - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - request_destroy (request); - } else { - ASSERT (!future_get_bool (future)); - mongoc_cursor_next (cursor, &doc); - - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } - - mongoc_cursor_destroy (cursor); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_aggregate_with_collation_fail (void) -{ - test_aggregate_with_collation (WIRE_VERSION_COLLATION - 1); -} - -static void -test_aggregate_with_collation_ok (void) -{ - test_aggregate_with_collation (WIRE_VERSION_COLLATION); -} - - -static void -test_index_with_collation (int wire) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - request_t *request; - bson_error_t error; - bson_t *collation; - bson_t keys; - mongoc_index_opt_t opt; - bson_t reply; - future_t *future; - - /* wire protocol version 0 */ - server = mock_server_with_autoismaster (wire); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - bson_init (&keys); - bson_append_int32 (&keys, "hello", -1, 1); - mongoc_index_opt_init (&opt); - collation = - BCON_NEW ("locale", BCON_UTF8 ("en"), "strength", BCON_INT32 (2)); - opt.collation = collation; - - future = future_collection_create_index_with_opts ( - collection, &keys, &opt, NULL, &reply, &error); - - if (wire == WIRE_VERSION_COLLATION) { - request = mock_server_receives_command ( - server, - "db", - 0, - "{ 'createIndexes' : 'collection'," - " 'indexes' : [" - " {" - " 'key' : {" - " 'hello' : 1" - " }," - " 'name' : 'hello_1'," - " 'collation': {'locale': 'en', 'strength': 2 }" - " }" - " ]" - "}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT (future_get_bool (future)); - request_destroy (request); - } else { - ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } - - bson_destroy (&reply); - bson_destroy (collation); - bson_destroy (&keys); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_index_with_collation_fail (void) -{ - test_index_with_collation (WIRE_VERSION_COLLATION - 1); -} - -static void -test_index_with_collation_ok (void) -{ - test_index_with_collation (WIRE_VERSION_COLLATION); -} - -static void -test_insert_duplicate_key (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_insert_duplicate_key"); - mongoc_collection_insert_one ( - collection, tmp_bson ("{'_id': 1}"), NULL, NULL, NULL); - - ASSERT (!mongoc_collection_insert_one ( - collection, tmp_bson ("{'_id': 1}"), NULL, NULL, &error)); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COLLECTION); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_DUPLICATE_KEY); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_create_index_fail (void *context) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bool r; - bson_t reply; - bson_error_t error; - - client = - mongoc_client_new ("mongodb://example.doesntexist/?connectTimeoutMS=10"); - collection = mongoc_client_get_collection (client, "test", "test"); - r = mongoc_collection_create_index_with_opts ( - collection, tmp_bson ("{'a': 1}"), NULL, NULL, &reply, &error); - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "No suitable servers"); - - /* reply was initialized */ - ASSERT (bson_empty (&reply)); - - bson_destroy (&reply); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -/* Tests that documents in `coll` found with `selector` all match `match` */ -static void -_test_docs_in_coll_matches (mongoc_collection_t *coll, - bson_t *selector, - const char *match, - uint32_t expected_count) -{ - const bson_t *next_doc; - mongoc_cursor_t *cursor = - mongoc_collection_find_with_opts (coll, selector, NULL, NULL); - while (expected_count > 0) { - ASSERT (mongoc_cursor_next (cursor, &next_doc)); - if (match) { - ASSERT_MATCH (next_doc, match); - } - --expected_count; - } - ASSERT_CMPINT (expected_count, ==, 0); - mongoc_cursor_destroy (cursor); -} - -static void -_test_no_docs_match (mongoc_collection_t *coll, const char *selector) -{ - bson_error_t error; - int64_t ret; - - ret = mongoc_collection_count_documents ( - coll, tmp_bson (selector), NULL, NULL, NULL, &error); - ASSERT_OR_PRINT (ret != -1, error); - ASSERT_CMPINT64 (ret, ==, (int64_t) 0); -} - -typedef struct { - const char *command_under_test; - int commands_tested; - const char *expected_command; -} test_crud_ctx_t; - -/* Tests that commands match the `expected_command` in the update ctx */ -void -_test_crud_command_start (const mongoc_apm_command_started_t *event) -{ - const bson_t *cmd = mongoc_apm_command_started_get_command (event); - const char *cmd_name = mongoc_apm_command_started_get_command_name (event); - - test_crud_ctx_t *ctx = - (test_crud_ctx_t *) mongoc_apm_command_started_get_context (event); - - if (!strcmp (cmd_name, ctx->command_under_test)) { - ctx->commands_tested++; - ASSERT_MATCH (cmd, ctx->expected_command); - assert_no_duplicate_keys (cmd); - } -} - -static void -test_insert_one (void) -{ - bson_error_t err = {0}; - bson_t reply; - bson_t opts_with_wc = BSON_INITIALIZER; - bool ret; - mongoc_client_t *client = test_framework_client_new (); - mongoc_database_t *db = get_test_database (client); - mongoc_collection_t *coll = mongoc_database_get_collection (db, "coll"); - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - mongoc_write_concern_t *wc2 = mongoc_write_concern_new (); - test_crud_ctx_t ctx; - mongoc_apm_callbacks_t *callbacks = mongoc_apm_callbacks_new (); - - ctx.command_under_test = "insert"; - ctx.commands_tested = 0; - - /* Give wc and wc2 different j values so we can distinguish them but make - * sure they have w:1 so the writes are committed when we check results */ - mongoc_write_concern_set_w (wc, 1); - mongoc_write_concern_set_journal (wc, false); - mongoc_write_concern_set_w (wc2, 1); - mongoc_write_concern_set_journal (wc2, true); - - mongoc_collection_set_write_concern (coll, wc); - mongoc_apm_set_command_started_cb (callbacks, _test_crud_command_start); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - mongoc_collection_drop (coll, NULL); - - /* Test a simple insert with bypassDocumentValidation */ - ctx.expected_command = "{'insert': 'coll', 'bypassDocumentValidation': " - "true, 'writeConcern': {'w': 1, 'j': false}}"; - ret = mongoc_collection_insert_one ( - coll, - tmp_bson ("{'_id': 1}"), - tmp_bson ("{'bypassDocumentValidation': true}"), - &reply, - &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, "{'insertedCount': 1}"); - bson_destroy (&reply); - _test_docs_in_coll_matches (coll, tmp_bson ("{'_id': 1}"), NULL, 1); - - /* Test maxTimeMS */ - ctx.expected_command = "{'insert': 'coll', 'maxTimeMS': 9999, " - " 'writeConcern': {'w': 1, 'j': false}}"; - ret = mongoc_collection_insert_one (coll, - tmp_bson ("{'_id': 2}"), - tmp_bson ("{'maxTimeMS': 9999}"), - &reply, - &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, "{'insertedCount': 1}"); - bson_destroy (&reply); - _test_docs_in_coll_matches (coll, tmp_bson ("{'_id': 2}"), NULL, 1); - - /* Test passing write concern through the options */ - mongoc_write_concern_append (wc2, &opts_with_wc); - ctx.expected_command = - "{'insert': 'coll', 'writeConcern': {'w': 1, 'j': true}}"; - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 3}"), &opts_with_wc, &reply, &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, "{'insertedCount': 1}"); - bson_destroy (&reply); - _test_docs_in_coll_matches (coll, tmp_bson ("{'_id':3}"), NULL, 1); - - /* Test passing NULL for opts, reply, and error */ - ctx.expected_command = - "{'insert': 'coll', 'writeConcern': {'w': 1, 'j': false}}"; - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 4}"), NULL, NULL, NULL); - ASSERT (ret); - _test_docs_in_coll_matches (coll, tmp_bson ("{'_id': 4}"), NULL, 1); - - /* Duplicate key error */ - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 4}"), NULL, &reply, &err); - ASSERT (!ret); - ASSERT_CMPUINT32 (err.domain, ==, (uint32_t) MONGOC_ERROR_COLLECTION); - ASSERT_MATCH (&reply, - "{'insertedCount': 0," - " 'writeErrors': [" - " {'index': 0, 'code': 11000, 'errmsg': {'$exists': true}}" - "]}"); - bson_destroy (&reply); - ASSERT_CMPINT (ctx.commands_tested, ==, 5); - - if (test_framework_is_replset ()) { - /* Write concern error */ - ctx.expected_command = "{'insert': 'coll'," - " 'writeConcern': {'w': 99, 'wtimeout': 100}}"; - ret = mongoc_collection_insert_one ( - coll, - tmp_bson ("{}"), - tmp_bson ("{'writeConcern': {'w': 99, 'wtimeout': 100}}"), - &reply, - &err); - ASSERT (!ret); - ASSERT_CMPUINT32 (err.domain, ==, (uint32_t) MONGOC_ERROR_WRITE_CONCERN); - ASSERT_MATCH (&reply, - "{'insertedCount': 1," - " 'writeErrors': {'$exists': false}," - " 'writeConcernErrors': {'$exists': true}" - "}"); - bson_destroy (&reply); - } - - bson_destroy (&opts_with_wc); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_write_concern_destroy (wc); - mongoc_write_concern_destroy (wc2); - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -typedef bool (*update_fn_t) (mongoc_collection_t *, - const bson_t *, - const bson_t *, - const bson_t *, - bson_t *, - bson_error_t *); - -/* Tests `update_one`, `update_many`, and `replace_one` */ -static void -_test_update_and_replace (bool is_replace, bool is_multi) -{ - update_fn_t fn = NULL; - bson_t *update = NULL; - bson_error_t err = {0}; - bson_t reply; - bson_t opts_with_wc = BSON_INITIALIZER; - bson_t opts_with_wc2 = BSON_INITIALIZER; - bool ret = false; - mongoc_client_t *client = test_framework_client_new (); - mongoc_database_t *db = get_test_database (client); - mongoc_collection_t *coll = mongoc_database_get_collection (db, "coll"); - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - mongoc_write_concern_t *wc2 = mongoc_write_concern_new (); - test_crud_ctx_t ctx; - mongoc_apm_callbacks_t *callbacks = mongoc_apm_callbacks_new (); - - ctx.command_under_test = "update"; - ctx.commands_tested = 0; - - /* Give wc and wc2 different j values so we can distinguish them but make - * sure they have w:1 so the writes are committed when we check results */ - mongoc_write_concern_set_w (wc, 1); - mongoc_write_concern_set_journal (wc, false); - mongoc_write_concern_append (wc, &opts_with_wc); - mongoc_collection_set_write_concern (coll, wc); - - mongoc_write_concern_set_w (wc2, 1); - mongoc_write_concern_set_journal (wc2, true); - mongoc_write_concern_append (wc2, &opts_with_wc2); - - mongoc_apm_set_command_started_cb (callbacks, _test_crud_command_start); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - mongoc_collection_drop (coll, NULL); - - /* Test `replace_one`, `update_one` or `update_many` based on args */ - if (is_replace) { - ASSERT (!is_multi); - fn = mongoc_collection_replace_one; - } else { - fn = is_multi ? mongoc_collection_update_many - : mongoc_collection_update_one; - } - - /* Test a simple update with bypassDocumentValidation */ - ctx.expected_command = "{'update': 'coll', 'bypassDocumentValidation': " - "true, 'writeConcern': {'w': 1, 'j': false}}"; - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 1}"), &opts_with_wc, NULL, &err); - ASSERT_OR_PRINT (ret, err); - update = - is_replace ? tmp_bson ("{'a': 1}") : tmp_bson ("{'$set': {'a': 1}}"); - ret = fn (coll, - tmp_bson ("{}"), - update, - tmp_bson ("{'bypassDocumentValidation': true}"), - &reply, - &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, - "{'modifiedCount': 1, 'matchedCount': 1, " - "'upsertedId': {'$exists': false}}"); - bson_destroy (&reply); - _test_docs_in_coll_matches (coll, tmp_bson ("{'_id':1}"), "{'a': 1}", 1); - - /* Test passing an upsert */ - ctx.expected_command = - "{'update': 'coll', 'writeConcern': {'w': 1, 'j': false}}"; - update = is_replace ? tmp_bson ("{'b': 'TEST'}") - : tmp_bson ("{'$set': {'b': 'TEST'}}"); - ret = fn (coll, - tmp_bson ("{'_id': 2}"), - update, - tmp_bson ("{'upsert': true}"), - &reply, - &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, - "{'modifiedCount': 0, 'matchedCount': 0, " - "'upsertedId': {'$exists': true}}"); - bson_destroy (&reply); - _test_docs_in_coll_matches ( - coll, tmp_bson ("{'_id':2}"), "{'b': 'TEST'}", 1); - - /* Test collation */ - if (test_framework_max_wire_version_at_least (WIRE_VERSION_COLLATION)) { - update = is_replace ? tmp_bson ("{'b': 'test'}") - : tmp_bson ("{'$set': {'b': 'test'}}"); - ret = fn (coll, - tmp_bson ("{'b': 'TEST'}"), - update, - tmp_bson ("{'collation': {'locale': 'en', 'strength': 2}}"), - &reply, - &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, - "{'modifiedCount': 1, 'matchedCount': 1, " - "'upsertedId': {'$exists': false}}"); - bson_destroy (&reply); - _test_docs_in_coll_matches ( - coll, tmp_bson ("{'_id':2}"), "{'b': 'test'}", 1); - } - - /* Test passing write concern through the options */ - ctx.expected_command = - "{'update': 'coll', 'writeConcern': {'w': 1, 'j': true}}"; - update = - is_replace ? tmp_bson ("{'b': 0}") : tmp_bson ("{'$set': {'b': 0}}"); - ret = - fn (coll, tmp_bson ("{'_id': 2}"), update, &opts_with_wc2, &reply, &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, - "{'modifiedCount': 1, 'matchedCount': 1, " - "'upsertedId': {'$exists': false}}"); - bson_destroy (&reply); - _test_docs_in_coll_matches (coll, tmp_bson ("{'_id':2}"), "{'b': 0}", 1); - - /* Test passing NULL for opts, reply, and error */ - ctx.expected_command = - "{'update': 'coll', 'writeConcern': {'w': 1, 'j': false}}"; - update = - is_replace ? tmp_bson ("{'b': 1}") : tmp_bson ("{'$set': {'b': 1}}"); - ret = fn (coll, tmp_bson ("{'_id': 2}"), update, NULL, NULL, NULL); - ASSERT (ret); - _test_docs_in_coll_matches (coll, tmp_bson ("{'_id' :2}"), "{'b': 1}", 1); - - /* Test multiple matching documents */ - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 3, 'a': 1}"), &opts_with_wc, NULL, &err); - ASSERT_OR_PRINT (ret, err); - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 4, 'a': 1}"), &opts_with_wc, NULL, &err); - ASSERT_OR_PRINT (ret, err); - update = - is_replace ? tmp_bson ("{'a': 2}") : tmp_bson ("{'$set': {'a': 2}}"); - ret = fn ( - coll, tmp_bson ("{'_id': {'$in': [3,4]}}"), update, NULL, &reply, &err); - ASSERT_OR_PRINT (ret, err); - if (is_multi) { - ASSERT_MATCH (&reply, - "{'modifiedCount': 2, 'matchedCount': 2, " - "'upsertedId': {'$exists': false}}"); - _test_docs_in_coll_matches ( - coll, tmp_bson ("{'_id': {'$in': [3,4]}}"), "{'a': 2}", 2); - } else { - ASSERT_MATCH (&reply, - "{'modifiedCount': 1, 'matchedCount': 1, " - "'upsertedId': {'$exists': false}}"); - /* omit testing collection since not sure which was updated */ - } - bson_destroy (&reply); - - ctx.expected_command = "{'update': 'coll'}"; - ret = fn (coll, tmp_bson ("{'$badOp': 1}"), update, NULL, &reply, &err); - ASSERT (!ret); - ASSERT_CMPUINT32 (err.domain, ==, (uint32_t) MONGOC_ERROR_COLLECTION); - ASSERT_MATCH (&reply, - "{'modifiedCount': 0," - " 'matchedCount': 0," - " 'writeErrors': [" - " {'index': 0, 'code': 2, 'errmsg': {'$exists': true}}" - "]}"); - bson_destroy (&reply); - - if (test_framework_is_replset ()) { - ret = fn (coll, - tmp_bson ("{'_id': 3}"), - is_replace ? tmp_bson ("{'a': 3}") - : tmp_bson ("{'$set': {'a': 3}}"), - tmp_bson ("{'writeConcern': {'w': 99, 'wtimeout': 100}}"), - &reply, - &err); - ASSERT (!ret); - ASSERT_CMPUINT32 (err.domain, ==, (uint32_t) MONGOC_ERROR_WRITE_CONCERN); - ASSERT_MATCH (&reply, - "{'modifiedCount': 1," - " 'matchedCount': 1," - " 'writeErrors': {'$exists': false}," - " 'writeConcernErrors': {'$exists': true}" - "}"); - bson_destroy (&reply); - } - - /* Test function specific behavior */ - if (is_replace) { - /* Test that replace really does replace */ - ret = - mongoc_collection_insert_one (coll, - tmp_bson ("{'_id': 5, 'a': 1, 'b': 2}"), - &opts_with_wc, - NULL, - &err); - ASSERT_OR_PRINT (ret, err); - ret = fn (coll, - tmp_bson ("{'_id': 5}"), - tmp_bson ("{'a': 2}"), - NULL, - &reply, - &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, - "{'modifiedCount': 1, 'matchedCount': 1, " - "'upsertedId': {'$exists': false}}"); - _test_docs_in_coll_matches ( - coll, tmp_bson ("{'_id': 5}"), "{'a': 2, 'b': {'$exists': false}}", 1); - bson_destroy (&reply); - - /* Test that a non-replace update fails. */ - ret = fn (coll, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'a': 1}}"), - NULL, - NULL, - &err); - ASSERT (!ret); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "invalid argument for replace"); - } else { - /* Test update_one and update_many with arrayFilters */ - ret = mongoc_collection_insert_one ( - coll, - tmp_bson ("{'_id': 6, 'a': [{'x':1},{'x':2}]}"), - &opts_with_wc, - NULL, - &err); - - ASSERT_OR_PRINT (ret, err); - - update = tmp_bson ("{'$set': {'a.$[i].x': 3}}"); - ret = fn (coll, - tmp_bson ("{'_id': 6}"), - update, - tmp_bson ("{'arrayFilters': [{'i.x': {'$gt': 1}}]}"), - &reply, - &err); - - if (test_framework_max_wire_version_at_least (6)) { - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, - "{'modifiedCount': 1, 'matchedCount': 1, " - "'upsertedId': {'$exists': false}}"); - _test_docs_in_coll_matches ( - coll, tmp_bson ("{'_id':6}"), "{'a': [{'x':1},{'x':3}]}", 1); - } else { - BSON_ASSERT (!ret); - ASSERT_ERROR_CONTAINS ( - err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support array filters"); - } - - bson_destroy (&reply); - - /* Test update that fails */ - ctx.expected_command = "{'update': 'coll'}"; - ret = - fn (coll, tmp_bson ("{}"), tmp_bson ("{'a': 1}"), NULL, &reply, &err); - ASSERT (!ret); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid key"); - ASSERT (bson_empty (&reply)); - bson_destroy (&reply); - } - - ASSERT_CMPINT (ctx.commands_tested, >, 0); - - mongoc_apm_callbacks_destroy (callbacks); - bson_destroy (&opts_with_wc); - bson_destroy (&opts_with_wc2); - mongoc_write_concern_destroy (wc); - mongoc_write_concern_destroy (wc2); - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -static void -test_update_and_replace (void) -{ - _test_update_and_replace (false /* is_replace */, false /* is_multi */); - _test_update_and_replace (true /* is_replace */, false /* is_multi */); - _test_update_and_replace (false /* is_replace */, true /* is_multi */); - /* Note, there is no multi replace */ -} - - -static void -test_array_filters_validate (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - collection = get_test_collection (client, "test_array_filters_validation"); - r = mongoc_collection_update_one (collection, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'x': 1}}"), - tmp_bson ("{'arrayFilters': 1}"), - NULL, - &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid field \"arrayFilters\" in opts, should contain array," - " not INT32"); - - r = mongoc_collection_update_one (collection, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'x': 1}}"), - tmp_bson ("{'arrayFilters': {}}"), - NULL, - &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid field \"arrayFilters\" in opts, should contain array," - " not DOCUMENT"); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -_test_update_validate (update_fn_t update_fn) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *selector; - bson_t *invalid_update, *valid_update; - const char *msg; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - collection = get_test_collection (client, "test_update_validate"); - selector = tmp_bson ("{}"); - - if (update_fn == mongoc_collection_replace_one) { - /* prohibited for replace */ - invalid_update = tmp_bson ("{'$set': {'x': 1}}"); - /* permitted for replace */ - valid_update = tmp_bson ("{'x': 1}"); - msg = "invalid argument for replace"; - } else { - /* prohibited for update */ - invalid_update = tmp_bson ("{'x': 1}"); - /* permitted for update */ - valid_update = tmp_bson ("{'$set': {'x': 1}}"); - msg = "only works with $ operators"; - } - - BSON_ASSERT ( - !update_fn (collection, selector, invalid_update, NULL, NULL, &error)); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, msg); - - r = update_fn (collection, - selector, - invalid_update, - tmp_bson ("{'validate': false}"), - NULL, - &error); - - /* server may or may not error */ - if (!r) { - ASSERT_CMPUINT32 (error.domain, ==, (uint32_t) MONGOC_ERROR_SERVER); - } - - BSON_ASSERT (!update_fn (collection, - selector, - invalid_update, - tmp_bson ("{'validate': 'foo'}"), - NULL, - &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid type for option \"validate\": \"UTF8\""); - - /* Set all validation flags */ - BSON_ASSERT (!update_fn (collection, - selector, - invalid_update, - tmp_bson ("{'validate': 31}"), - NULL, - &error)); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, msg); - - /* Check that validation passes for a valid update. */ - ASSERT_OR_PRINT ( - update_fn (collection, - selector, - valid_update, - tmp_bson ("{'validate': %d}", BSON_VALIDATE_UTF8), - NULL, - &error), - error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_replace_one_validate (void) -{ - _test_update_validate (mongoc_collection_replace_one); -} - - -static void -test_update_one_validate (void) -{ - _test_update_validate (mongoc_collection_update_one); -} - - -static void -test_update_many_validate (void) -{ - _test_update_validate (mongoc_collection_update_many); -} - - -typedef bool (*delete_fn_t) (mongoc_collection_t *, - const bson_t *, - const bson_t *, - bson_t *, - bson_error_t *); - -static void -_test_delete_one_or_many (bool is_multi) -{ - delete_fn_t fn = - is_multi ? mongoc_collection_delete_many : mongoc_collection_delete_one; - bson_error_t err = {0}; - bson_t reply; - bson_t opts_with_wc = BSON_INITIALIZER; - bool ret; - mongoc_client_t *client = test_framework_client_new (); - mongoc_database_t *db = get_test_database (client); - mongoc_collection_t *coll = mongoc_database_get_collection (db, "coll"); - mongoc_write_concern_t *wc = mongoc_write_concern_new (); - mongoc_write_concern_t *wc2 = mongoc_write_concern_new (); - test_crud_ctx_t ctx; - mongoc_apm_callbacks_t *callbacks = mongoc_apm_callbacks_new (); - int i; - - ctx.command_under_test = "delete"; - ctx.commands_tested = 0; - - /* Give wc and wc2 different j values so we can distinguish them but make - * sure they have w:1 so the writes are committed when we check results */ - mongoc_write_concern_set_w (wc, 1); - mongoc_write_concern_set_journal (wc, false); - mongoc_write_concern_set_w (wc2, 1); - mongoc_write_concern_set_journal (wc2, true); - - mongoc_collection_set_write_concern (coll, wc); - mongoc_apm_set_command_started_cb (callbacks, _test_crud_command_start); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - mongoc_collection_drop (coll, NULL); - - for (i = 0; i < 3; i++) { - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': %d}", i), NULL, NULL, &err); - ASSERT_OR_PRINT (ret, err); - } - - /* Test maxTimeMS */ - ctx.expected_command = "{'delete': 'coll', 'maxTimeMS': 9999, " - " 'writeConcern': {'w': 1, 'j': false}}"; - ret = fn (coll, - tmp_bson ("{'_id': 1}"), - tmp_bson ("{'maxTimeMS': 9999}"), - &reply, - &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, "{'deletedCount': 1}"); - bson_destroy (&reply); - _test_no_docs_match (coll, "{'_id': 1}"); - - /* Test passing write concern through the options */ - mongoc_write_concern_append (wc2, &opts_with_wc); - ctx.expected_command = - "{'delete': 'coll', 'writeConcern': {'w': 1, 'j': true}}"; - ret = fn (coll, tmp_bson ("{'_id': 2}"), &opts_with_wc, &reply, &err); - ASSERT_OR_PRINT (ret, err); - ASSERT_MATCH (&reply, "{'deletedCount': 1}"); - bson_destroy (&reply); - _test_no_docs_match (coll, "{'_id': 2}"); - - /* Test passing NULL for opts, reply, and error */ - ctx.expected_command = - "{'delete': 'coll', 'writeConcern': {'w': 1, 'j': false}}"; - ret = fn (coll, tmp_bson ("{'_id': 3}"), NULL, NULL, NULL); - ASSERT (ret); - _test_no_docs_match (coll, "{'_id': 3}"); - - /* Server error */ - ret = fn (coll, tmp_bson ("{'_id': {'$foo': 1}}"), NULL, &reply, &err); - ASSERT (!ret); - ASSERT_CMPUINT32 (err.domain, ==, (uint32_t) MONGOC_ERROR_COLLECTION); - ASSERT_MATCH (&reply, - "{'deletedCount': 0," - " 'writeErrors': [" - " {'index': 0," - " 'code': {'$exists': true}," - " 'errmsg': {'$exists': true}}" - "]}"); - bson_destroy (&reply); - ASSERT_CMPINT (ctx.commands_tested, ==, 4); - - if (test_framework_is_replset ()) { - /* Write concern error */ - ctx.expected_command = "{'delete': 'coll'," - " 'writeConcern': {'w': 99, 'wtimeout': 100}}"; - ret = fn (coll, - tmp_bson ("{}"), - tmp_bson ("{'writeConcern': {'w': 99, 'wtimeout': 100}}"), - &reply, - &err); - ASSERT (!ret); - ASSERT_CMPUINT32 (err.domain, ==, (uint32_t) MONGOC_ERROR_WRITE_CONCERN); - ASSERT_MATCH (&reply, - "{'deletedCount': 1," - " 'writeErrors': {'$exists': false}," - " 'writeConcernErrors': {'$exists': true}" - "}"); - bson_destroy (&reply); - ASSERT_CMPINT (ctx.commands_tested, ==, 5); - } - - /* Test deleting with collation. */ - ctx.expected_command = "{'delete': 'coll'}"; - if (test_framework_max_wire_version_at_least (WIRE_VERSION_COLLATION)) { - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 1, 'x': 11}"), NULL, NULL, &err); - ASSERT_OR_PRINT (ret, err); - - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 2, 'x': 'ping'}"), NULL, NULL, &err); - ASSERT_OR_PRINT (ret, err); - - ret = mongoc_collection_insert_one ( - coll, tmp_bson ("{'_id': 3, 'x': 'pINg'}"), NULL, NULL, &err); - ASSERT_OR_PRINT (ret, err); - - ret = fn (coll, - tmp_bson ("{'x': 'PING'}"), - tmp_bson ("{'collation': {'locale': 'en_US', 'strength': 2 }}"), - &reply, - &err); - - ASSERT_OR_PRINT (ret, err); - if (is_multi) { - ASSERT_MATCH (&reply, "{'deletedCount': 2}"); - } else { - ASSERT_MATCH (&reply, "{'deletedCount': 1}"); - } - bson_destroy (&reply); - - _test_no_docs_match (coll, "{'_id': 2}"); - } - - bson_destroy (&opts_with_wc); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_write_concern_destroy (wc); - mongoc_write_concern_destroy (wc2); - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -typedef future_t *(*future_delete_fn_t) (mongoc_collection_t *, - const bson_t *, - const bson_t *, - bson_t *, - bson_error_t *); - -static void -_test_delete_collation (int wire, bool is_multi) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - future_t *future; - request_t *request; - bson_error_t error; - future_delete_fn_t fn = - is_multi ? future_collection_delete_many : future_collection_delete_one; - char *expected_cmd; - - server = mock_server_with_autoismaster (wire); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - future = fn (collection, - tmp_bson ("{}"), - tmp_bson ("{'collation': {'locale': 'en'}}"), - NULL, - &error); - - expected_cmd = - bson_strdup_printf ("{'delete': 'collection', 'deletes': [{'q': {}, " - "'limit': %d, 'collation': {'locale': 'en'}}]}", - is_multi ? 0 : 1); - - if (wire == WIRE_VERSION_COLLATION) { - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, expected_cmd); - mock_server_replies_simple (request, "{'ok': 1, 'n': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - request_destroy (request); - } else { - ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } - - bson_free (expected_cmd); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_delete_one_or_many (void) -{ - _test_delete_one_or_many (true); - _test_delete_one_or_many (false); -} - -static void -test_delete_collation (void) -{ - _test_delete_collation (WIRE_VERSION_COLLATION, true); - _test_delete_collation (WIRE_VERSION_COLLATION - 1, true); - _test_delete_collation (WIRE_VERSION_COLLATION, false); - _test_delete_collation (WIRE_VERSION_COLLATION - 1, false); -} - -typedef future_t *(*future_update_fn_t) (mongoc_collection_t *, - const bson_t *, - const bson_t *, - const bson_t *, - bson_t *, - bson_error_t *); -static void -_test_update_or_replace_with_collation (int wire, - bool is_replace, - bool is_multi) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - future_t *future; - request_t *request; - bson_error_t error; - future_update_fn_t fn; - char *expected_cmd; - - if (is_replace) { - BSON_ASSERT (!is_multi); - fn = future_collection_replace_one; - } else { - fn = is_multi ? future_collection_update_many - : future_collection_update_one; - } - - server = mock_server_with_autoismaster (wire); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - future = fn (collection, - tmp_bson ("{}"), - tmp_bson ("{}"), - tmp_bson ("{'collation': {'locale': 'en'}}"), - NULL, - &error); - - expected_cmd = - bson_strdup_printf ("{'update': 'collection', 'updates': [{'q': {}, 'u': " - "{}, 'collation': {'locale': 'en'} %s }]}", - is_multi ? ", 'multi': true" : ""); - - if (wire >= WIRE_VERSION_COLLATION) { - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, expected_cmd); - mock_server_replies_simple (request, "{'ok': 1, 'n': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - request_destroy (request); - } else { - ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - } - - bson_free (expected_cmd); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_update_collation (void) -{ - _test_update_or_replace_with_collation ( - WIRE_VERSION_COLLATION, false, false); - _test_update_or_replace_with_collation (WIRE_VERSION_COLLATION, false, true); - _test_update_or_replace_with_collation (WIRE_VERSION_COLLATION, true, false); - - _test_update_or_replace_with_collation ( - WIRE_VERSION_COLLATION - 1, false, false); - _test_update_or_replace_with_collation ( - WIRE_VERSION_COLLATION - 1, false, true); - _test_update_or_replace_with_collation ( - WIRE_VERSION_COLLATION - 1, true, false); -} - - -static void -test_update_multi (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - unsigned i; - bson_t *bptr[10]; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_update_multi"); - - (void) mongoc_collection_drop (collection, &error); - - for (i = 0; i < 10; i++) { - bptr[i] = tmp_bson ("{'_id': %d, 'x': 1234}", i); - } - - ASSERT_OR_PRINT ( - mongoc_collection_insert_many ( - collection, (const bson_t **) bptr, 10, NULL, NULL, &error), - error); - - ASSERT_OR_PRINT (mongoc_collection_update (collection, - MONGOC_UPDATE_MULTI_UPDATE, - tmp_bson ("{'_id': {'$gte': 5}}"), - tmp_bson ("{'$inc': {'x': 1}}"), - NULL, - &error), - error); - - _test_docs_in_coll_matches ( - collection, tmp_bson ("{'_id': {'$lt': 5}, 'x': 1234}"), NULL, 5); - _test_docs_in_coll_matches ( - collection, tmp_bson ("{'_id': {'$gte': 5}, 'x': 1235}"), NULL, 5); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_update_upsert (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_update_upsert"); - - (void) mongoc_collection_drop (collection, &error); - - ASSERT_OR_PRINT ( - mongoc_collection_update (collection, - MONGOC_UPDATE_UPSERT, - tmp_bson ("{'_id': 1}"), - tmp_bson ("{'$set': {'x': 1234}}"), - NULL, - &error), - error); - - _test_docs_in_coll_matches ( - collection, tmp_bson ("{'_id': 1, 'x': 1234}"), NULL, 1); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_remove_multi (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - unsigned i; - bson_t *bptr[10]; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_remove_multi"); - - (void) mongoc_collection_drop (collection, &error); - - for (i = 0; i < 10; i++) { - bptr[i] = tmp_bson ("{'_id': %d, 'x': 1234}", i); - } - - ASSERT_OR_PRINT ( - mongoc_collection_insert_many ( - collection, (const bson_t **) bptr, 10, NULL, NULL, &error), - error); - - ASSERT_OR_PRINT (mongoc_collection_remove (collection, - MONGOC_REMOVE_NONE, - tmp_bson ("{'_id': {'$gte': 8}}"), - NULL, - &error), - error); - - /* mongoc_collection_delete is an alias of mongoc_collection_remove, although - * its flag type differs slightly */ - ASSERT_OR_PRINT (mongoc_collection_delete (collection, - MONGOC_DELETE_NONE, - tmp_bson ("{'_id': {'$lt': 2}}"), - NULL, - &error), - error); - - _test_docs_in_coll_matches (collection, tmp_bson ("{'x': 1234}"), NULL, 6); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -void -test_collection_install (TestSuite *suite) -{ - test_aggregate_install (suite); - - TestSuite_AddFull (suite, - "/Collection/aggregate/write_concern", - test_aggregate_w_write_concern, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_5); - TestSuite_AddFull (suite, - "/Collection/read_prefs_is_valid", - 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/insert_bulk_empty", test_insert_bulk_empty); - 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_AddMockServerTest ( - suite, "/Collection/insert/keys", test_insert_command_keys); - TestSuite_AddLive (suite, "/Collection/save", test_save); - TestSuite_AddLive (suite, "/Collection/insert/w0", test_insert_w0); - TestSuite_AddLive (suite, "/Collection/update/w0", test_update_w0); - TestSuite_AddLive (suite, "/Collection/remove/w0", test_remove_w0); - TestSuite_AddLive ( - suite, "/Collection/insert_twice/w0", test_insert_twice_w0); - TestSuite_AddLive (suite, "/Collection/index", test_index); - TestSuite_AddLive ( - suite, "/Collection/index_w_write_concern", test_index_w_write_concern); - TestSuite_AddMockServerTest (suite, - "/Collection/index/collation/wire4", - test_index_with_collation_fail); - TestSuite_AddMockServerTest ( - suite, "/Collection/index/collation/wire5", test_index_with_collation_ok); - TestSuite_AddLive (suite, "/Collection/index_compound", test_index_compound); - TestSuite_AddLive (suite, "/Collection/index_geo", test_index_geo); - 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_AddLive (suite, "/Collection/update", test_update); - TestSuite_AddFull (suite, - "/Collection/update_pipeline", - test_update_pipeline, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_8); - 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_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_AddLive (suite, "/Collection/count", test_count); - TestSuite_AddMockServerTest ( - suite, "/Collection/count_with_opts", test_count_with_opts); - TestSuite_AddMockServerTest ( - suite, "/Collection/count/read_pref", test_count_read_pref); - TestSuite_AddMockServerTest ( - suite, "/Collection/count/read_concern", test_count_read_concern); - TestSuite_AddMockServerTest (suite, - "/Collection/count/collation/wire4", - test_count_with_collation_fail); - TestSuite_AddMockServerTest ( - suite, "/Collection/count/collation/wire5", test_count_with_collation_ok); - TestSuite_AddFull (suite, - "/Collection/count/read_concern_live", - test_count_read_concern_live, - NULL, - NULL, - mongod_supports_majority_read_concern); - 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_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", - test_aggregate_bypass, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_4); - TestSuite_AddMockServerTest (suite, - "/Collection/aggregate/collation/wire4", - test_aggregate_with_collation_fail); - TestSuite_AddMockServerTest (suite, - "/Collection/aggregate/collation/wire5", - test_aggregate_with_collation_ok); - 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", - test_aggregate_server_id_option, - NULL, - NULL, - test_framework_skip_if_auth); - TestSuite_AddFull (suite, - "/Collection/validate", - test_validate, - NULL, - NULL, - test_framework_skip_if_slow_or_live); - TestSuite_AddLive (suite, "/Collection/rename", test_rename); - TestSuite_AddLive (suite, "/Collection/stats", test_stats); - TestSuite_AddMockServerTest ( - suite, "/Collection/stats/read_pref", test_stats_read_pref); - 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, - test_framework_skip_if_max_wire_version_less_than_4); - 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_wire_32); - TestSuite_AddMockServerTest ( - suite, - "/Collection/find_and_modify/write_concern_pre_32", - test_find_and_modify_write_concern_wire_pre_32); - TestSuite_AddFull (suite, - "/Collection/large_return", - 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); - TestSuite_AddMockServerTest (suite, "/Collection/limit", test_find_limit); - TestSuite_AddMockServerTest ( - suite, "/Collection/batch_size", test_find_batch_size); - TestSuite_AddFull (suite, - "/Collection/command_fully_qualified", - test_command_fq, - NULL, - NULL, - test_framework_skip_if_mongos); - 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_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); - TestSuite_AddLive ( - suite, "/Collection/replace_one_validate", test_replace_one_validate); - TestSuite_AddLive ( - suite, "/Collection/update_one_validate", test_update_one_validate); - TestSuite_AddLive ( - suite, "/Collection/update_many_validate", test_update_many_validate); - TestSuite_AddLive ( - suite, "/Collection/delete_one_or_many", test_delete_one_or_many); - TestSuite_AddMockServerTest ( - suite, "/Collection/delete/collation", test_delete_collation); - TestSuite_AddMockServerTest ( - suite, "/Collection/update/collation", test_update_collation); - TestSuite_AddMockServerTest ( - suite, "/Collection/count_documents", test_count_documents); - TestSuite_AddLive ( - suite, "/Collection/count_documents_live", test_count_documents_live); - TestSuite_AddMockServerTest (suite, - "/Collection/estimated_document_count", - test_estimated_document_count); - TestSuite_AddLive (suite, - "/Collection/estimated_document_count_live", - test_estimated_document_count_live); - TestSuite_AddLive ( - suite, "/Collection/insert_bulk_validate", test_insert_bulk_validate); - TestSuite_AddMockServerTest (suite, - "/Collection/aggregate_with_batch_size", - test_aggregate_with_batch_size); - TestSuite_AddFull (suite, - "/Collection/aggregate_is_sent_to_primary_w_dollar_out", - test_aggregate_is_sent_to_primary_w_dollar_out, - NULL, - NULL, - test_framework_skip_if_not_replset); -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-command-monitoring.c b/lib/mongoc/libmongoc/tests/test-mongoc-command-monitoring.c deleted file mode 100644 index 921188b48a6b2497ab7a5dccf9ee629576a25feb..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-command-monitoring.c +++ /dev/null @@ -1,1245 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-bulk-operation-private.h> -#include <mongoc/mongoc-collection-private.h> - -#include "json-test.h" -#include "test-libmongoc.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "json-test-operations.h" - - -const char * -first_key (const bson_t *bson) -{ - bson_iter_t iter; - - BSON_ASSERT (bson_iter_init (&iter, bson)); - if (!bson_iter_next (&iter)) { - return NULL; - } - - return bson_iter_key (&iter); -} - - -void -check_operation_ids (const bson_t *events) -{ - bson_iter_t iter; - int64_t first_operation_id = -1; - int64_t operation_id; - bson_t event; - - /* check op ids of events like {command_started_event: {operation_id: N}} */ - BSON_ASSERT (bson_iter_init (&iter, events)); - while (bson_iter_next (&iter)) { - bson_iter_bson (&iter, &event); - if (!strcmp (first_key (&event), "command_started_event")) { - operation_id = - bson_lookup_int64 (&event, "command_started_event.operation_id"); - - if (first_operation_id == -1) { - first_operation_id = operation_id; - } else if (operation_id != first_operation_id) { - MONGOC_ERROR ( - "%s sent wrong operation_id", - bson_lookup_utf8 (&event, "command_started_event.command_name")); - abort (); - } - } - } -} - - -static bool -command_monitoring_test_run_operation (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation) -{ - bson_t reply; - bool res; - - /* Command Monitoring tests don't use explicit session */ - res = - json_test_operation (ctx, test, operation, ctx->collection, NULL, &reply); - - bson_destroy (&reply); - - return res; -} - - -/* - *----------------------------------------------------------------------- - * - * test_command_monitoring_cb -- - * - * Runs the JSON tests included with the Command Monitoring spec. - * - *----------------------------------------------------------------------- - */ - -static void -test_command_monitoring_cb (bson_t *scenario) -{ - json_test_config_t config = JSON_TEST_CONFIG_INIT; - config.run_operation_cb = command_monitoring_test_run_operation; - config.scenario = scenario; - config.events_check_cb = check_operation_ids; - run_json_general_test (&config); - json_test_config_cleanup (&config); -} - - -/* - *----------------------------------------------------------------------- - * - * Runner for the JSON tests for command monitoring. - * - *----------------------------------------------------------------------- - */ -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - test_framework_resolve_path (JSON_DIR "/command_monitoring", resolved); - install_json_test_suite (suite, resolved, &test_command_monitoring_cb); -} - - -static void -test_get_error_failed_cb (const mongoc_apm_command_failed_t *event) -{ - bson_error_t *error; - - error = (bson_error_t *) mongoc_apm_command_failed_get_context (event); - mongoc_apm_command_failed_get_error (event, error); -} - - -static void -test_get_error (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_apm_callbacks_t *callbacks; - future_t *future; - request_t *request; - bson_error_t error = {0}; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_failed_cb (callbacks, test_get_error_failed_cb); - mongoc_client_set_apm_callbacks (client, callbacks, (void *) &error); - future = future_client_command_simple ( - client, "db", tmp_bson ("{'foo': 1}"), NULL, NULL, NULL); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'foo': 1}"); - mock_server_replies_simple (request, - "{'ok': 0, 'errmsg': 'foo', 'code': 42}"); - ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_QUERY, 42, "foo"); - - future_destroy (future); - request_destroy (request); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -insert_200_docs (mongoc_collection_t *collection) -{ - int i; - bson_t *doc; - bool r; - bson_error_t error; - - /* insert 200 docs so we have a couple batches */ - doc = tmp_bson (NULL); - for (i = 0; i < 200; i++) { - r = mongoc_collection_insert_one (collection, doc, NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - } -} - - -static void -increment (const mongoc_apm_command_started_t *event) -{ - int *i = (int *) mongoc_apm_command_started_get_context (event); - - ++(*i); -} - - -static mongoc_apm_callbacks_t * -increment_callbacks (void) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, increment); - - return callbacks; -} - - -static void -decrement (const mongoc_apm_command_started_t *event) -{ - int *i = (int *) mongoc_apm_command_started_get_context (event); - - --(*i); -} - - -static mongoc_apm_callbacks_t * -decrement_callbacks (void) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, decrement); - - return callbacks; -} - - -static void -test_change_callbacks (void) -{ - mongoc_apm_callbacks_t *inc_callbacks; - mongoc_apm_callbacks_t *dec_callbacks; - int incremented = 0; - int decremented = 0; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - mongoc_cursor_t *cursor; - const bson_t *b; - - inc_callbacks = increment_callbacks (); - dec_callbacks = decrement_callbacks (); - - client = test_framework_client_new (); - mongoc_client_set_apm_callbacks (client, inc_callbacks, &incremented); - - collection = get_test_collection (client, "test_change_callbacks"); - - insert_200_docs (collection); - ASSERT_CMPINT (incremented, ==, 200); - - mongoc_client_set_apm_callbacks (client, dec_callbacks, &decremented); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson (NULL), NULL, NULL); - - ASSERT (mongoc_cursor_next (cursor, &b)); - ASSERT_CMPINT (decremented, ==, -1); - - mongoc_client_set_apm_callbacks (client, inc_callbacks, &incremented); - while (mongoc_cursor_next (cursor, &b)) { - } - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - ASSERT_CMPINT (incremented, ==, 201); - - mongoc_collection_drop (collection, NULL); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_apm_callbacks_destroy (inc_callbacks); - mongoc_apm_callbacks_destroy (dec_callbacks); -} - - -static void -test_reset_callbacks (void) -{ - mongoc_apm_callbacks_t *inc_callbacks; - mongoc_apm_callbacks_t *dec_callbacks; - int incremented = 0; - int decremented = 0; - mongoc_client_t *client; - mongoc_collection_t *collection; - bool r; - bson_t *cmd; - bson_t cmd_reply; - bson_error_t error; - mongoc_server_description_t *sd; - mongoc_cursor_t *cursor; - const bson_t *b; - - inc_callbacks = increment_callbacks (); - dec_callbacks = decrement_callbacks (); - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_reset_apm_callbacks"); - - /* insert 200 docs so we have a couple batches */ - insert_200_docs (collection); - - mongoc_client_set_apm_callbacks (client, inc_callbacks, &incremented); - cmd = tmp_bson ("{'aggregate': '%s', 'pipeline': [], 'cursor': {}}", - collection->collection); - - sd = - mongoc_client_select_server (client, true /* for writes */, NULL, &error); - ASSERT_OR_PRINT (sd, error); - - r = mongoc_client_read_command_with_opts ( - client, - "test", - cmd, - NULL, - tmp_bson ("{'serverId': %d}", sd->id), - &cmd_reply, - &error); - - ASSERT_OR_PRINT (r, error); - ASSERT_CMPINT (incremented, ==, 1); - - /* reset callbacks */ - mongoc_client_set_apm_callbacks (client, NULL, NULL); - /* destroys cmd_reply */ - cursor = mongoc_cursor_new_from_command_reply (client, &cmd_reply, sd->id); - ASSERT (mongoc_cursor_next (cursor, &b)); - ASSERT_CMPINT (incremented, ==, 1); /* same value as before */ - - mongoc_client_set_apm_callbacks (client, dec_callbacks, &decremented); - while (mongoc_cursor_next (cursor, &b)) { - } - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - ASSERT_CMPINT (decremented, ==, -1); - - mongoc_collection_drop (collection, NULL); - - mongoc_cursor_destroy (cursor); - mongoc_server_description_destroy (sd); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_apm_callbacks_destroy (inc_callbacks); - mongoc_apm_callbacks_destroy (dec_callbacks); -} - - -static void -test_set_callbacks_cb (const mongoc_apm_command_started_t *event) -{ - int *n_calls = (int *) mongoc_apm_command_started_get_context (event); - - (*n_calls)++; -} - - -static void -_test_set_callbacks (bool pooled, bool try_pop) -{ - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - mongoc_apm_callbacks_t *callbacks; - int n_calls = 0; - bson_error_t error; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, test_set_callbacks_cb); - - if (pooled) { - pool = test_framework_client_pool_new (); - ASSERT (mongoc_client_pool_set_apm_callbacks ( - pool, callbacks, (void *) &n_calls)); - if (try_pop) { - client = mongoc_client_pool_try_pop (pool); - } else { - client = mongoc_client_pool_pop (pool); - } - } else { - client = test_framework_client_new (); - ASSERT (mongoc_client_set_apm_callbacks ( - client, callbacks, (void *) &n_calls)); - } - - ASSERT_OR_PRINT ( - mongoc_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, &error), - error); - ASSERT_CMPINT (1, ==, n_calls); - - capture_logs (true); - - if (pooled) { - ASSERT ( - !mongoc_client_pool_set_apm_callbacks (pool, NULL, (void *) &n_calls)); - ASSERT_CAPTURED_LOG ("mongoc_client_pool_set_apm_callbacks", - MONGOC_LOG_LEVEL_ERROR, - "Can only set callbacks once"); - - clear_captured_logs (); - ASSERT ( - !mongoc_client_set_apm_callbacks (client, NULL, (void *) &n_calls)); - ASSERT_CAPTURED_LOG ("mongoc_client_pool_set_apm_callbacks", - MONGOC_LOG_LEVEL_ERROR, - "Cannot set callbacks on a pooled client"); - } else { - /* repeated calls ok, null is ok */ - ASSERT (mongoc_client_set_apm_callbacks (client, NULL, NULL)); - } - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_apm_callbacks_destroy (callbacks); -} - - -static void -test_set_callbacks_single (void) -{ - _test_set_callbacks (false, false); -} - - -static void -test_set_callbacks_pooled (void) -{ - _test_set_callbacks (true, false); -} - -static void -test_set_callbacks_pooled_try_pop (void) -{ - _test_set_callbacks (true, true); -} - - -typedef struct { - int64_t request_id; - int64_t op_id; -} ids_t; - - -typedef struct { - mongoc_array_t started_ids; - mongoc_array_t succeeded_ids; - mongoc_array_t failed_ids; - int started_calls; - int succeeded_calls; - int failed_calls; -} op_id_test_t; - - -static void -op_id_test_init (op_id_test_t *test) -{ - _mongoc_array_init (&test->started_ids, sizeof (ids_t)); - _mongoc_array_init (&test->succeeded_ids, sizeof (ids_t)); - _mongoc_array_init (&test->failed_ids, sizeof (ids_t)); - - test->started_calls = 0; - test->succeeded_calls = 0; - test->failed_calls = 0; -} - - -static void -op_id_test_cleanup (op_id_test_t *test) -{ - _mongoc_array_destroy (&test->started_ids); - _mongoc_array_destroy (&test->succeeded_ids); - _mongoc_array_destroy (&test->failed_ids); -} - - -static void -test_op_id_started_cb (const mongoc_apm_command_started_t *event) -{ - op_id_test_t *test; - ids_t ids; - - test = (op_id_test_t *) mongoc_apm_command_started_get_context (event); - ids.request_id = mongoc_apm_command_started_get_request_id (event); - ids.op_id = mongoc_apm_command_started_get_operation_id (event); - - _mongoc_array_append_val (&test->started_ids, ids); - - test->started_calls++; -} - - -static void -test_op_id_succeeded_cb (const mongoc_apm_command_succeeded_t *event) -{ - op_id_test_t *test; - ids_t ids; - - test = (op_id_test_t *) mongoc_apm_command_succeeded_get_context (event); - ids.request_id = mongoc_apm_command_succeeded_get_request_id (event); - ids.op_id = mongoc_apm_command_succeeded_get_operation_id (event); - - _mongoc_array_append_val (&test->succeeded_ids, ids); - - test->succeeded_calls++; -} - - -static void -test_op_id_failed_cb (const mongoc_apm_command_failed_t *event) -{ - op_id_test_t *test; - ids_t ids; - - test = (op_id_test_t *) mongoc_apm_command_failed_get_context (event); - ids.request_id = mongoc_apm_command_failed_get_request_id (event); - ids.op_id = mongoc_apm_command_failed_get_operation_id (event); - - _mongoc_array_append_val (&test->failed_ids, ids); - - test->failed_calls++; -} - - -#define REQUEST_ID(_event_type, _index) \ - _mongoc_array_index (&test._event_type##_ids, ids_t, _index).request_id - -#define OP_ID(_event_type, _index) \ - _mongoc_array_index (&test._event_type##_ids, ids_t, _index).op_id - -static void -_test_bulk_operation_id (bool pooled, bool use_bulk_operation_new) -{ - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - mongoc_apm_callbacks_t *callbacks; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - bson_error_t error; - op_id_test_t test; - int64_t op_id; - - op_id_test_init (&test); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, test_op_id_started_cb); - mongoc_apm_set_command_succeeded_cb (callbacks, test_op_id_succeeded_cb); - mongoc_apm_set_command_failed_cb (callbacks, test_op_id_failed_cb); - - if (pooled) { - pool = test_framework_client_pool_new (); - ASSERT (mongoc_client_pool_set_apm_callbacks ( - pool, callbacks, (void *) &test)); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - ASSERT ( - mongoc_client_set_apm_callbacks (client, callbacks, (void *) &test)); - } - - collection = get_test_collection (client, "test_bulk_operation_id"); - if (use_bulk_operation_new) { - bulk = mongoc_bulk_operation_new (false); - mongoc_bulk_operation_set_client (bulk, client); - mongoc_bulk_operation_set_database (bulk, collection->db); - mongoc_bulk_operation_set_collection (bulk, collection->collection); - } else { - bson_append_bool (&opts, "ordered", 7, false); - bulk = - mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - } - - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 1}")); - mongoc_bulk_operation_update_one ( - bulk, tmp_bson ("{'_id': 1}"), tmp_bson ("{'$set': {'x': 1}}"), false); - mongoc_bulk_operation_remove (bulk, tmp_bson ("{}")); - - /* ensure we monitor with bulk->operation_id, not cluster->operation_id */ - client->cluster.operation_id = 42; - - /* write errors don't trigger failed events, so we only test success */ - ASSERT_OR_PRINT (mongoc_bulk_operation_execute (bulk, NULL, &error), error); - ASSERT_CMPINT (test.started_calls, ==, 3); - ASSERT_CMPINT (test.succeeded_calls, ==, 3); - - ASSERT_CMPINT64 (REQUEST_ID (started, 0), ==, REQUEST_ID (succeeded, 0)); - ASSERT_CMPINT64 (REQUEST_ID (started, 1), ==, REQUEST_ID (succeeded, 1)); - ASSERT_CMPINT64 (REQUEST_ID (started, 2), ==, REQUEST_ID (succeeded, 2)); - - /* 3 unique request ids */ - ASSERT_CMPINT64 (REQUEST_ID (started, 0), !=, REQUEST_ID (started, 1)); - ASSERT_CMPINT64 (REQUEST_ID (started, 0), !=, REQUEST_ID (started, 2)); - ASSERT_CMPINT64 (REQUEST_ID (started, 1), !=, REQUEST_ID (started, 2)); - ASSERT_CMPINT64 (REQUEST_ID (succeeded, 0), !=, REQUEST_ID (succeeded, 1)); - ASSERT_CMPINT64 (REQUEST_ID (succeeded, 0), !=, REQUEST_ID (succeeded, 2)); - ASSERT_CMPINT64 (REQUEST_ID (succeeded, 1), !=, REQUEST_ID (succeeded, 2)); - - /* events' operation ids all equal bulk->operation_id */ - op_id = bulk->operation_id; - ASSERT_CMPINT64 (op_id, !=, (int64_t) 0); - ASSERT_CMPINT64 (op_id, ==, OP_ID (started, 0)); - ASSERT_CMPINT64 (op_id, ==, OP_ID (started, 1)); - ASSERT_CMPINT64 (op_id, ==, OP_ID (started, 2)); - ASSERT_CMPINT64 (op_id, ==, OP_ID (succeeded, 0)); - ASSERT_CMPINT64 (op_id, ==, OP_ID (succeeded, 1)); - ASSERT_CMPINT64 (op_id, ==, OP_ID (succeeded, 2)); - - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - bson_destroy (&opts); - op_id_test_cleanup (&test); - mongoc_apm_callbacks_destroy (callbacks); -} - - -static void -test_collection_bulk_op_single (void) -{ - _test_bulk_operation_id (false, false); -} - - -static void -test_collection_bulk_op_pooled (void) -{ - _test_bulk_operation_id (true, false); -} - - -static void -test_bulk_op_single (void) -{ - _test_bulk_operation_id (false, true); -} - - -static void -test_bulk_op_pooled (void) -{ - _test_bulk_operation_id (true, true); -} - - -static void -_test_query_operation_id (bool pooled) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - mongoc_apm_callbacks_t *callbacks; - mongoc_collection_t *collection; - op_id_test_t test; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - int64_t op_id; - - op_id_test_init (&test); - - server = mock_server_with_autoismaster (4); - mock_server_run (server); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, test_op_id_started_cb); - mongoc_apm_set_command_succeeded_cb (callbacks, test_op_id_succeeded_cb); - mongoc_apm_set_command_failed_cb (callbacks, test_op_id_failed_cb); - - if (pooled) { - pool = mongoc_client_pool_new (mock_server_get_uri (server)); - ASSERT (mongoc_client_pool_set_apm_callbacks ( - pool, callbacks, (void *) &test)); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT ( - mongoc_client_set_apm_callbacks (client, callbacks, (void *) &test)); - } - - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 1, tmp_bson ("{}"), NULL, NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_request (server); - mock_server_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK, - 123 /* cursor id */, - 1, - "db.collection", - "{}", - true); - - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - - ASSERT_CMPINT (test.started_calls, ==, 1); - ASSERT_CMPINT (test.succeeded_calls, ==, 1); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_request (server); - mock_server_replies_simple (request, - "{'ok': 0, 'code': 42, 'errmsg': 'bad!'}"); - - ASSERT (!future_get_bool (future)); - future_destroy (future); - request_destroy (request); - - ASSERT_CMPINT (test.started_calls, ==, 2); - ASSERT_CMPINT (test.succeeded_calls, ==, 1); - ASSERT_CMPINT (test.failed_calls, ==, 1); - - ASSERT_CMPINT64 (REQUEST_ID (started, 0), ==, REQUEST_ID (succeeded, 0)); - ASSERT_CMPINT64 (REQUEST_ID (started, 1), ==, REQUEST_ID (failed, 0)); - - /* unique request ids */ - ASSERT_CMPINT64 (REQUEST_ID (started, 0), !=, REQUEST_ID (started, 1)); - - /* operation ids all the same */ - op_id = OP_ID (started, 0); - ASSERT_CMPINT64 (op_id, !=, (int64_t) 0); - ASSERT_CMPINT64 (op_id, ==, OP_ID (started, 1)); - ASSERT_CMPINT64 (op_id, ==, OP_ID (failed, 0)); - - mock_server_destroy (server); - - /* client logs warning because it can't send killCursors or endSessions */ - capture_logs (true); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - op_id_test_cleanup (&test); - mongoc_apm_callbacks_destroy (callbacks); -} - - -static void -test_query_operation_id_single_cmd (void) -{ - _test_query_operation_id (false); -} - - -static void -test_query_operation_id_pooled_cmd (void) -{ - _test_query_operation_id (true); -} - -typedef struct { - int started_calls; - int succeeded_calls; - int failed_calls; - char db[100]; - char cmd_name[100]; - bson_t cmd; -} cmd_test_t; - - -static void -cmd_test_init (cmd_test_t *test) -{ - memset (test, 0, sizeof *test); - bson_init (&test->cmd); -} - - -static void -cmd_test_cleanup (cmd_test_t *test) -{ - bson_destroy (&test->cmd); -} - - -static void -cmd_started_cb (const mongoc_apm_command_started_t *event) -{ - cmd_test_t *test; - - if (!strcmp (mongoc_apm_command_started_get_command_name (event), - "endSessions")) { - /* the test is ending */ - return; - } - - test = (cmd_test_t *) mongoc_apm_command_started_get_context (event); - test->started_calls++; - bson_destroy (&test->cmd); - bson_strncpy (test->db, - mongoc_apm_command_started_get_database_name (event), - sizeof (test->db)); - bson_copy_to (mongoc_apm_command_started_get_command (event), &test->cmd); - bson_strncpy (test->cmd_name, - mongoc_apm_command_started_get_command_name (event), - sizeof (test->cmd_name)); -} - - -static void -cmd_succeeded_cb (const mongoc_apm_command_succeeded_t *event) -{ - cmd_test_t *test; - int64_t duration; - - if (!strcmp (mongoc_apm_command_succeeded_get_command_name (event), - "endSessions")) { - return; - } - - test = (cmd_test_t *) mongoc_apm_command_succeeded_get_context (event); - test->succeeded_calls++; - ASSERT_CMPSTR (test->cmd_name, - mongoc_apm_command_succeeded_get_command_name (event)); - - duration = mongoc_apm_command_succeeded_get_duration (event); - ASSERT_CMPINT64 (duration, >=, (int64_t) 0); - ASSERT_CMPINT64 (duration, <=, (int64_t) 10000000); /* ten seconds */ -} - - -static void -cmd_failed_cb (const mongoc_apm_command_failed_t *event) -{ - cmd_test_t *test; - int64_t duration; - - test = (cmd_test_t *) mongoc_apm_command_failed_get_context (event); - test->failed_calls++; - ASSERT_CMPSTR (test->cmd_name, - mongoc_apm_command_failed_get_command_name (event)); - - duration = mongoc_apm_command_failed_get_duration (event); - ASSERT_CMPINT64 (duration, >=, (int64_t) 0); - ASSERT_CMPINT64 (duration, <=, (int64_t) 10000000); /* ten seconds */ -} - - -static void -set_cmd_test_callbacks (mongoc_client_t *client, void *context) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, cmd_started_cb); - mongoc_apm_set_command_succeeded_cb (callbacks, cmd_succeeded_cb); - mongoc_apm_set_command_failed_cb (callbacks, cmd_failed_cb); - ASSERT (mongoc_client_set_apm_callbacks (client, callbacks, context)); - mongoc_apm_callbacks_destroy (callbacks); -} - - -static void -test_client_cmd (void) -{ - cmd_test_t test; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - const bson_t *reply; - - cmd_test_init (&test); - client = test_framework_client_new (); - set_cmd_test_callbacks (client, (void *) &test); - cursor = mongoc_client_command (client, - "admin", - MONGOC_QUERY_SLAVE_OK, - 0, - 0, - 0, - tmp_bson ("{'ping': 1}"), - NULL, - NULL); - - ASSERT (mongoc_cursor_next (cursor, &reply)); - ASSERT_CMPSTR (test.cmd_name, "ping"); - ASSERT_MATCH (&test.cmd, "{'ping': 1}"); - ASSERT_CMPSTR (test.db, "admin"); - ASSERT_CMPINT (1, ==, test.started_calls); - ASSERT_CMPINT (1, ==, test.succeeded_calls); - ASSERT_CMPINT (0, ==, test.failed_calls); - - cmd_test_cleanup (&test); - mongoc_cursor_destroy (cursor); - - cmd_test_init (&test); - cursor = mongoc_client_command (client, - "admin", - MONGOC_QUERY_SLAVE_OK, - 0, - 0, - 0, - tmp_bson ("{'foo': 1}"), - NULL, - NULL); - - ASSERT (!mongoc_cursor_next (cursor, &reply)); - ASSERT_CMPSTR (test.cmd_name, "foo"); - ASSERT_MATCH (&test.cmd, "{'foo': 1}"); - ASSERT_CMPSTR (test.db, "admin"); - ASSERT_CMPINT (1, ==, test.started_calls); - ASSERT_CMPINT (0, ==, test.succeeded_calls); - ASSERT_CMPINT (1, ==, test.failed_calls); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); - cmd_test_cleanup (&test); -} - - -static void -test_client_cmd_simple (void) -{ - cmd_test_t test; - mongoc_client_t *client; - bool r; - bson_error_t error; - - cmd_test_init (&test); - client = test_framework_client_new (); - set_cmd_test_callbacks (client, (void *) &test); - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - ASSERT_CMPSTR (test.cmd_name, "ping"); - ASSERT_MATCH (&test.cmd, "{'ping': 1}"); - ASSERT_CMPSTR (test.db, "admin"); - ASSERT_CMPINT (1, ==, test.started_calls); - ASSERT_CMPINT (1, ==, test.succeeded_calls); - ASSERT_CMPINT (0, ==, test.failed_calls); - - cmd_test_cleanup (&test); - cmd_test_init (&test); - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'foo': 1}"), NULL, NULL, &error); - - ASSERT (!r); - ASSERT_CMPSTR (test.cmd_name, "foo"); - ASSERT_MATCH (&test.cmd, "{'foo': 1}"); - ASSERT_CMPSTR (test.db, "admin"); - ASSERT_CMPINT (1, ==, test.started_calls); - ASSERT_CMPINT (0, ==, test.succeeded_calls); - ASSERT_CMPINT (1, ==, test.failed_calls); - - mongoc_client_destroy (client); - cmd_test_cleanup (&test); -} - - -static void -test_client_cmd_op_ids (void) -{ - op_id_test_t test; - mongoc_client_t *client; - mongoc_apm_callbacks_t *callbacks; - bool r; - bson_error_t error; - int64_t op_id; - - op_id_test_init (&test); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, test_op_id_started_cb); - mongoc_apm_set_command_succeeded_cb (callbacks, test_op_id_succeeded_cb); - mongoc_apm_set_command_failed_cb (callbacks, test_op_id_failed_cb); - - client = test_framework_client_new (); - mongoc_client_set_apm_callbacks (client, callbacks, (void *) &test); - - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - ASSERT_CMPINT (1, ==, test.started_calls); - ASSERT_CMPINT (1, ==, test.succeeded_calls); - ASSERT_CMPINT (0, ==, test.failed_calls); - ASSERT_CMPINT64 (REQUEST_ID (started, 0), ==, REQUEST_ID (succeeded, 0)); - ASSERT_CMPINT64 (OP_ID (started, 0), ==, OP_ID (succeeded, 0)); - op_id = OP_ID (started, 0); - ASSERT_CMPINT64 (op_id, !=, (int64_t) 0); - - op_id_test_cleanup (&test); - op_id_test_init (&test); - - /* again. test that we use a new op_id. */ - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - ASSERT_CMPINT (1, ==, test.started_calls); - ASSERT_CMPINT (1, ==, test.succeeded_calls); - ASSERT_CMPINT (0, ==, test.failed_calls); - ASSERT_CMPINT64 (REQUEST_ID (started, 0), ==, REQUEST_ID (succeeded, 0)); - ASSERT_CMPINT64 (OP_ID (started, 0), ==, OP_ID (succeeded, 0)); - ASSERT_CMPINT64 (OP_ID (started, 0), !=, (int64_t) 0); - - /* new op_id */ - ASSERT_CMPINT64 (OP_ID (started, 0), !=, op_id); - - mongoc_client_destroy (client); - op_id_test_cleanup (&test); - mongoc_apm_callbacks_destroy (callbacks); -} - - -static void -test_killcursors_deprecated (void) -{ - cmd_test_t test; - mongoc_client_t *client; - bool r; - bson_error_t error; - - cmd_test_init (&test); - client = test_framework_client_new (); - - /* connect */ - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - set_cmd_test_callbacks (client, (void *) &test); - - /* deprecated function without "db" or "collection", skips APM */ - mongoc_client_kill_cursor (client, 123); - - ASSERT_CMPINT (0, ==, test.started_calls); - ASSERT_CMPINT (0, ==, test.succeeded_calls); - ASSERT_CMPINT (0, ==, test.failed_calls); - - mongoc_client_destroy (client); - cmd_test_cleanup (&test); -} - - -typedef struct { - int failed_calls; - bson_t reply; -} cmd_failed_reply_test_t; - - -static void -cmd_failed_reply_test_init (cmd_failed_reply_test_t *test) -{ - memset (test, 0, sizeof *test); - bson_init (&test->reply); -} - - -static void -cmd_failed_reply_test_cleanup (cmd_failed_reply_test_t *test) -{ - bson_destroy (&test->reply); -} - - -static void -command_failed_reply_command_failed_cb ( - const mongoc_apm_command_failed_t *event) -{ - cmd_failed_reply_test_t *test; - - test = - (cmd_failed_reply_test_t *) mongoc_apm_command_failed_get_context (event); - test->failed_calls++; - bson_destroy (&test->reply); - - bson_copy_to (mongoc_apm_command_failed_get_reply (event), &test->reply); -} - - -static void -test_command_failed_reply_mock (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_apm_callbacks_t *callbacks; - mongoc_collection_t *collection; - cmd_failed_reply_test_t test; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - - /* test that the command_failed_event's reply is the same as a mocked reply - */ - cmd_failed_reply_test_init (&test); - - server = mock_server_with_autoismaster (4); - mock_server_run (server); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_failed_cb (callbacks, - command_failed_reply_command_failed_cb); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT (mongoc_client_set_apm_callbacks (client, callbacks, (void *) &test)); - - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 1, tmp_bson ("{}"), NULL, NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_request (server); - mock_server_replies_simple (request, - "{'ok': 0, 'code': 42, 'errmsg': 'bad!'}"); - - ASSERT (!future_get_bool (future)); - future_destroy (future); - request_destroy (request); - - ASSERT_MATCH (&test.reply, "{'ok': 0, 'code': 42, 'errmsg': 'bad!'}"); - ASSERT_CMPINT (test.failed_calls, ==, 1); - - mock_server_destroy (server); - - /* client logs warning because it can't send killCursors or endSessions */ - capture_logs (true); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - mongoc_client_destroy (client); - - cmd_failed_reply_test_cleanup (&test); - mongoc_apm_callbacks_destroy (callbacks); -} - - -static void -test_command_failed_reply_hangup (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_apm_callbacks_t *callbacks; - mongoc_collection_t *collection; - cmd_failed_reply_test_t test; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - - /* test that the command_failed_event's reply is empty if there is a network - * error (i.e. the server hangs up) */ - cmd_failed_reply_test_init (&test); - - server = mock_server_with_autoismaster (4); - mock_server_run (server); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_failed_cb (callbacks, - command_failed_reply_command_failed_cb); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT (mongoc_client_set_apm_callbacks (client, callbacks, (void *) &test)); - - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 1, tmp_bson ("{}"), NULL, NULL); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_request (server); - mock_server_replies_simple (request, - "{'ok': 0, 'code': 42, 'errmsg': 'bad!'}"); - - ASSERT (!future_get_bool (future)); - future_destroy (future); - mock_server_hangs_up (request); - request_destroy (request); - - ASSERT_MATCH (&test.reply, "{}"); - ASSERT_CMPINT (test.failed_calls, ==, 1); - - mock_server_destroy (server); - - /* client logs warning because it can't send killCursors or endSessions */ - capture_logs (true); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - mongoc_client_destroy (client); - - cmd_failed_reply_test_cleanup (&test); - mongoc_apm_callbacks_destroy (callbacks); -} - - -void -test_command_monitoring_install (TestSuite *suite) -{ - test_all_spec_tests (suite); - TestSuite_AddMockServerTest ( - suite, "/command_monitoring/get_error", test_get_error); - TestSuite_AddLive (suite, - "/command_monitoring/set_callbacks/single", - test_set_callbacks_single); - TestSuite_AddLive (suite, - "/command_monitoring/set_callbacks/pooled", - test_set_callbacks_pooled); - TestSuite_AddLive (suite, - "/command_monitoring/set_callbacks/pooled_try_pop", - test_set_callbacks_pooled_try_pop); - /* require aggregation cursor */ - TestSuite_AddLive ( - suite, "/command_monitoring/set_callbacks/change", test_change_callbacks); - TestSuite_AddLive ( - suite, "/command_monitoring/set_callbacks/reset", test_reset_callbacks); - TestSuite_AddLive (suite, - "/command_monitoring/operation_id/bulk/collection/single", - test_collection_bulk_op_single); - TestSuite_AddLive (suite, - "/command_monitoring/operation_id/bulk/collection/pooled", - test_collection_bulk_op_pooled); - TestSuite_AddLive (suite, - "/command_monitoring/operation_id/bulk/new/single", - test_bulk_op_single); - TestSuite_AddLive (suite, - "/command_monitoring/operation_id/bulk/new/pooled", - test_bulk_op_pooled); - TestSuite_AddMockServerTest ( - suite, - "/command_monitoring/operation_id/query/single/cmd", - test_query_operation_id_single_cmd); - TestSuite_AddMockServerTest ( - suite, - "/command_monitoring/operation_id/query/pooled/cmd", - test_query_operation_id_pooled_cmd); - TestSuite_AddLive (suite, "/command_monitoring/client_cmd", test_client_cmd); - TestSuite_AddLive ( - suite, "/command_monitoring/client_cmd_simple", test_client_cmd_simple); - TestSuite_AddLive ( - suite, "/command_monitoring/client_cmd/op_ids", test_client_cmd_op_ids); - TestSuite_AddLive (suite, - "/command_monitoring/killcursors_deprecated", - test_killcursors_deprecated); - TestSuite_AddMockServerTest (suite, - "/command_monitoring/failed_reply_mock", - test_command_failed_reply_mock); - TestSuite_AddMockServerTest (suite, - "/command_monitoring/failed_reply_hangup", - test_command_failed_reply_hangup); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-connection-uri.c b/lib/mongoc/libmongoc/tests/test-mongoc-connection-uri.c deleted file mode 100644 index ffc6686f9b858ea05b2de0d8c29ccec6043a63bf..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-connection-uri.c +++ /dev/null @@ -1,371 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-util-private.h> - -#include "json-test.h" -#include "test-libmongoc.h" -#include "mongoc/mongoc-read-concern-private.h" - - -/* - * Asserts every key-value pair in 'needle' is in 'haystack', including those in - * embedded documents. - */ -static void -bson_contains_iter (const bson_t *haystack, bson_iter_t *needle) -{ - bson_iter_t iter; - uint32_t bson_type; - - if (!bson_iter_next (needle)) { - return; - } - - ASSERT (bson_iter_init_find_case (&iter, haystack, bson_iter_key (needle))); - - bson_type = bson_iter_type (needle); - switch (bson_type) { - case BSON_TYPE_ARRAY: - case BSON_TYPE_DOCUMENT: { - bson_t sub_bson; - bson_iter_t sub_iter; - - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - bson_iter_bson (&iter, &sub_bson); - - bson_iter_recurse (needle, &sub_iter); - bson_contains_iter (&sub_bson, &sub_iter); - - bson_destroy (&sub_bson); - return; - } - case BSON_TYPE_BOOL: - ASSERT (bson_iter_as_bool (needle) == bson_iter_as_bool (&iter)); - return bson_contains_iter (haystack, needle); - case BSON_TYPE_UTF8: - ASSERT (0 == - strcmp (bson_iter_utf8 (needle, 0), bson_iter_utf8 (&iter, 0))); - return bson_contains_iter (haystack, needle); - case BSON_TYPE_DOUBLE: - ASSERT (bson_iter_double (needle) == bson_iter_double (&iter)); - return bson_contains_iter (haystack, needle); - case BSON_TYPE_INT64: - case BSON_TYPE_INT32: - ASSERT (bson_iter_as_int64 (needle) == bson_iter_as_int64 (&iter)); - return bson_contains_iter (haystack, needle); - default: - ASSERT (false); - return; - } -} - -static void -run_uri_test (const char *uri_string, - bool valid, - const bson_t *hosts, - const bson_t *auth, - const bson_t *options) -{ - mongoc_uri_t *uri; - bson_iter_t auth_iter; - const char *db; - bson_error_t error; - - uri = mongoc_uri_new_with_error (uri_string, &error); - - /* BEGIN Exceptions to test suite */ - - /* some spec tests assume we allow DB names like "auth.foo" */ - if ((bson_iter_init_find (&auth_iter, auth, "db") || - bson_iter_init_find (&auth_iter, auth, "source")) && - BSON_ITER_HOLDS_UTF8 (&auth_iter)) { - db = bson_iter_utf8 (&auth_iter, NULL); - if (strchr (db, '.')) { - BSON_ASSERT (!uri); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid database name in URI"); - clear_captured_logs (); - return; - } - } - - if (valid && !uri && error.domain) { - /* Eager failures which the spec expects to be warnings. */ - /* CDRIVER-3167 */ - if (strstr (uri_string, "=invalid") || - strstr (uri_string, "heartbeatFrequencyMS=-2") || - strstr (uri_string, "w=-2") || strstr (uri_string, "wTimeoutMS=-2") || - strstr (uri_string, "zlibCompressionLevel=-2") || - strstr (uri_string, "zlibCompressionLevel=10")) { - MONGOC_WARNING ("Error parsing URI: '%s'", error.message); - return; - } - } - - if (uri) { - /* mongoc does not warn on negative timeouts when it should. */ - /* CDRIVER-3167 */ - if ((mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_CONNECTTIMEOUTMS, 0) < 0) || - (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_LOCALTHRESHOLDMS, 0) < 0) || - (mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_MAXIDLETIMEMS, 0) < - 0) || - (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_SERVERSELECTIONTIMEOUTMS, 0) < 0) || - (mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_SOCKETTIMEOUTMS, 0) < - 0)) { - MONGOC_WARNING ("Invalid negative timeout"); - } - - /* mongoc does not store lists the way the spec test expects. */ - if (strstr (uri_string, "compressors=") || - strstr (uri_string, "readPreferenceTags=")) { - options = NULL; - } - - /* mongoc eagerly warns about unsupported compressors. */ -#ifndef MONGOC_ENABLE_COMPRESSION_SNAPPY - if (strstr (uri_string, "compressors=snappy")) { - clear_captured_logs (); - } -#endif - -#ifndef MONGOC_ENABLE_COMPRESSION_ZLIB - if (strstr (uri_string, "compressors=zlib") || - strstr (uri_string, "compressors=snappy,zlib")) { - clear_captured_logs (); - } -#endif - } - - /* END Exceptions to test suite */ - - if (valid) { - ASSERT_OR_PRINT (uri, error); - } else { - BSON_ASSERT (!uri); - return; - } - - if (!bson_empty0 (hosts)) { - const mongoc_host_list_t *hl; - bson_iter_t iter; - bson_iter_t host_iter; - - for (bson_iter_init (&iter, hosts); - bson_iter_next (&iter) && bson_iter_recurse (&iter, &host_iter);) { - const char *host = "localhost"; - int port = 27017; - bool ok = false; - - if (bson_iter_find (&host_iter, "host") && - BSON_ITER_HOLDS_UTF8 (&host_iter)) { - host = bson_iter_utf8 (&host_iter, NULL); - } - if (bson_iter_find (&host_iter, "port") && - BSON_ITER_HOLDS_INT (&host_iter)) { - port = bson_iter_as_int64 (&host_iter); - } - - for (hl = mongoc_uri_get_hosts (uri); hl; hl = hl->next) { - if (!strcmp (host, hl->host) && port == hl->port) { - ok = true; - break; - } - } - - if (!ok) { - fprintf (stderr, - "Could not find '%s':%d in uri '%s'\n", - host, - port, - mongoc_uri_get_string (uri)); - BSON_ASSERT (0); - } - } - } - - if (!bson_empty0 (auth)) { - const char *auth_source = mongoc_uri_get_auth_source (uri); - const char *username = mongoc_uri_get_username (uri); - const char *password = mongoc_uri_get_password (uri); - bson_iter_t iter; - - if (bson_iter_init_find (&iter, auth, "username") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - ASSERT_CMPSTR (username, bson_iter_utf8 (&iter, NULL)); - } - - if (bson_iter_init_find (&iter, auth, "password") && - BSON_ITER_HOLDS_UTF8 (&iter)) { - ASSERT_CMPSTR (password, bson_iter_utf8 (&iter, NULL)); - } - - if ((bson_iter_init_find (&iter, auth, "db") || - bson_iter_init_find (&iter, auth, "source")) && - BSON_ITER_HOLDS_UTF8 (&iter)) { - ASSERT_CMPSTR (auth_source, bson_iter_utf8 (&iter, NULL)); - } - } - - if (options) { - const mongoc_read_concern_t *rc; - bson_t uri_options = BSON_INITIALIZER; - bson_t test_options = BSON_INITIALIZER; - bson_iter_t iter; - - bson_concat (&uri_options, mongoc_uri_get_options (uri)); - bson_concat (&uri_options, mongoc_uri_get_credentials (uri)); - - rc = mongoc_uri_get_read_concern (uri); - if (!mongoc_read_concern_is_default (rc)) { - BSON_APPEND_UTF8 (&uri_options, - "readconcernlevel", - mongoc_read_concern_get_level (rc)); - } - - bson_copy_to_excluding_noinit ( - options, - &test_options, - "username", /* these 'auth' params may be included in 'options' */ - "password", - "source", - "mechanism", /* renamed to 'authmechanism' for consistency */ - "mechanism_properties", /* renamed to 'authmechanismproperties' for - * consistency */ - NULL); - - if ((bson_iter_init_find (&iter, options, "mechanism") || - bson_iter_init_find (&iter, options, "authmechanism")) && - BSON_ITER_HOLDS_UTF8 (&iter)) { - BSON_APPEND_UTF8 ( - &test_options, "authmechanism", bson_iter_utf8 (&iter, NULL)); - } - - if ((bson_iter_init_find (&iter, options, "mechanism_properties") || - bson_iter_init_find (&iter, options, "authmechanismproperties")) && - BSON_ITER_HOLDS_DOCUMENT (&iter)) { - ASSERT (bson_append_iter ( - &test_options, "authmechanismproperties", -1, &iter)); - } - - bson_iter_init (&iter, &test_options); - bson_contains_iter (&uri_options, &iter); - - bson_destroy (&test_options); - bson_destroy (&uri_options); - } - - if (uri) { - mongoc_uri_destroy (uri); - } -} - -static void -test_connection_uri_cb (bson_t *scenario) -{ - bson_iter_t iter; - bson_iter_t descendent; - bson_iter_t tests_iter; - bson_iter_t warning_iter; - const char *uri_string = NULL; - bson_t hosts; - bson_t auth; - bson_t options; - bool valid; - int c = 0; - - BSON_ASSERT (scenario); - - - BSON_ASSERT (bson_iter_init_find (&iter, scenario, "tests")); - BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (&iter)); - ASSERT (bson_iter_recurse (&iter, &tests_iter)); - - while (bson_iter_next (&tests_iter)) { - bson_t test_case; - - bson_iter_bson (&tests_iter, &test_case); - c++; - - if (test_suite_debug_output ()) { - bson_iter_t test_case_iter; - - ASSERT (bson_iter_recurse (&tests_iter, &test_case_iter)); - if (bson_iter_find (&test_case_iter, "description")) { - const char *description = bson_iter_utf8 (&test_case_iter, NULL); - ASSERT (bson_iter_find_case (&test_case_iter, "uri")); - - printf (" - %s: '%s'\n", - description, - bson_iter_utf8 (&test_case_iter, 0)); - fflush (stdout); - } else { - fprintf (stderr, "Couldn't find `description` field in testcase\n"); - BSON_ASSERT (0); - } - } - - uri_string = bson_lookup_utf8 (&test_case, "uri"); - /* newer spec test replaces both "auth" and "options" with "credential" - */ - if (bson_has_field (&test_case, "credential")) { - bson_lookup_doc_null_ok (&test_case, "credential", &auth); - bson_lookup_doc_null_ok (&test_case, "credential", &options); - bson_init (&hosts); - } else if (bson_has_field (&test_case, "auth")) { - bson_lookup_doc_null_ok (&test_case, "auth", &auth); - bson_lookup_doc_null_ok (&test_case, "options", &options); - bson_lookup_doc_null_ok (&test_case, "hosts", &hosts); - } else { - /* These are expected to be initialized */ - bson_init (&hosts); - bson_init (&auth); - bson_init (&options); - } - - valid = _mongoc_lookup_bool (&test_case, "valid", true); - capture_logs (true); - run_uri_test (uri_string, valid, &hosts, &auth, &options); - - bson_iter_init (&warning_iter, &test_case); - - if (bson_iter_find_descendant (&warning_iter, "warning", &descendent) && - BSON_ITER_HOLDS_BOOL (&descendent)) { - if (bson_iter_as_bool (&descendent)) { - ASSERT_CAPTURED_LOG ("mongoc_uri", MONGOC_LOG_LEVEL_WARNING, ""); - } else { - ASSERT_NO_CAPTURED_LOGS ("mongoc_uri"); - } - } - - bson_destroy (&hosts); - bson_destroy (&auth); - bson_destroy (&options); - } -} - - -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - test_framework_resolve_path (JSON_DIR "/uri-options", resolved); - install_json_test_suite (suite, resolved, &test_connection_uri_cb); - - test_framework_resolve_path (JSON_DIR "/connection_uri", resolved); - install_json_test_suite (suite, resolved, &test_connection_uri_cb); - - test_framework_resolve_path (JSON_DIR "/auth", resolved); - install_json_test_suite (suite, resolved, &test_connection_uri_cb); -} - - -void -test_connection_uri_install (TestSuite *suite) -{ - test_all_spec_tests (suite); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-counters.c b/lib/mongoc/libmongoc/tests/test-mongoc-counters.c deleted file mode 100644 index b80ea145c75a5c4ed1a4285ec248a2768ca5959e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-counters.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Copyright 2018-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 <mongoc/mongoc-util-private.h> -#include "mongoc/mongoc-counters-private.h" -#include "mock_server/mock-server.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "TestSuite.h" -#include "mock_server/future-functions.h" - -/* test statistics counters excluding OP_INSERT, OP_UPDATE, and OP_DELETE since - * those were superseded by write commands in 2.6. */ -#ifdef MONGOC_ENABLE_SHM_COUNTERS -/* define a count function for each counter. */ -#define COUNTER(id, category, name, description) \ - uint32_t prev_##id; \ - uint32_t count_##id (void) \ - { \ - uint32_t _sum = 0; \ - uint32_t _i; \ - for (_i = 0; _i < _mongoc_get_cpu_count (); _i++) { \ - _sum += __mongoc_counter_##id.cpus[_i] \ - .slots[COUNTER_##id % SLOTS_PER_CACHELINE]; \ - } \ - return _sum; \ - } -#include "mongoc/mongoc-counters.defs" -#undef COUNTER - -#define RESET(id) prev_##id = count_##id (); - -#define DIFF_AND_RESET(id, cmp, expected) \ - do { \ - uint32_t old_count = prev_##id; \ - uint32_t new_count = count_##id (); \ - uint32_t _diff = new_count - old_count; \ - ASSERT_CMPINT32 (_diff, cmp, expected); \ - RESET (id) \ - } while (0); - -static void -reset_all_counters () -{ -#define COUNTER(id, category, name, description) RESET (id); -#include "mongoc/mongoc-counters.defs" -#undef COUNTER -} - -/* create a client and disable server selection after performing it. */ -static mongoc_client_t * -_client_new_disable_ss (bool use_compression) -{ - mongoc_client_t *client; - mongoc_uri_t *uri; - mongoc_server_description_t *sd; - bson_error_t err; - - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 99999); - mongoc_uri_set_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 99999); - if (use_compression) { - char *compressors = test_framework_get_compressors (); - mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_COMPRESSORS, compressors); - bson_free (compressors); - } - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - sd = mongoc_client_select_server (client, true, NULL, &err); - ASSERT_OR_PRINT (sd, err); - mongoc_server_description_destroy (sd); - mongoc_uri_destroy (uri); - /* reset counters to exclude anything done in server selection. */ - reset_all_counters (); - return client; -} - - -mongoc_collection_t * -_drop_and_populate_coll (mongoc_client_t *client) -{ - /* insert thrice. */ - mongoc_collection_t *coll; - bool ret; - bson_error_t err; - int i; - coll = mongoc_client_get_collection (client, "test", "test"); - mongoc_collection_drop (coll, NULL); /* don't care if ns not found. */ - for (i = 0; i < 3; i++) { - ret = - mongoc_collection_insert_one (coll, tmp_bson ("{}"), NULL, NULL, &err); - ASSERT_OR_PRINT (ret, err); - } - return coll; -} - - -void -_ping (mongoc_client_t *client) -{ - bool ret; - bson_error_t err; - ret = mongoc_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, &err); - ASSERT_OR_PRINT (ret, err); -} - - -static void -test_counters_op_msg (void *ctx) -{ - mongoc_collection_t *coll; - mongoc_cursor_t *exhaust_cursor; - const bson_t *bson; - mongoc_client_t *client; - - client = _client_new_disable_ss (false); - _ping (client); - DIFF_AND_RESET (op_egress_msg, ==, 1); - DIFF_AND_RESET (op_egress_total, ==, 1); - DIFF_AND_RESET (op_ingress_msg, ==, 1); - DIFF_AND_RESET (op_ingress_total, ==, 1); - coll = _drop_and_populate_coll (client); - DIFF_AND_RESET (op_egress_msg, ==, 4); - DIFF_AND_RESET (op_egress_total, ==, 4); - DIFF_AND_RESET (op_ingress_msg, ==, 4); - DIFF_AND_RESET (op_ingress_total, ==, 4); - /* an exhaust cursor still must use an OP_QUERY find. */ - exhaust_cursor = mongoc_collection_find (coll, - MONGOC_QUERY_EXHAUST, - 0 /* skip */, - 0 /* limit */, - 1 /* batch size */, - tmp_bson ("{}"), - NULL /* fields */, - NULL /* read prefs */); - while (mongoc_cursor_next (exhaust_cursor, &bson)) - ; - mongoc_cursor_destroy (exhaust_cursor); - DIFF_AND_RESET (op_egress_msg, ==, 0); - DIFF_AND_RESET (op_ingress_msg, ==, 0); - DIFF_AND_RESET (op_egress_query, ==, 1); - DIFF_AND_RESET (op_ingress_reply, >, 0); - DIFF_AND_RESET (op_egress_total, >, 0); - DIFF_AND_RESET (op_ingress_total, >, 0); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - - -static void -test_counters_op_compressed (void *ctx) -{ - mongoc_collection_t *coll; - mongoc_client_t *client; - - client = _client_new_disable_ss (true); - _ping (client); - /* we count one OP_MSG and one OP_COMPRESSED for the same message. */ - DIFF_AND_RESET (op_egress_msg, ==, 1); - DIFF_AND_RESET (op_egress_compressed, ==, 1); - DIFF_AND_RESET (op_egress_total, ==, 2); - DIFF_AND_RESET (op_ingress_msg, ==, 1); - DIFF_AND_RESET (op_ingress_compressed, ==, 1); - DIFF_AND_RESET (op_ingress_total, ==, 2); - coll = _drop_and_populate_coll (client); - DIFF_AND_RESET (op_egress_msg, ==, 4); - DIFF_AND_RESET (op_egress_compressed, ==, 4); - DIFF_AND_RESET (op_egress_total, ==, 8); - DIFF_AND_RESET (op_ingress_msg, ==, 4); - DIFF_AND_RESET (op_ingress_compressed, ==, 4); - DIFF_AND_RESET (op_ingress_total, ==, 8); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - - -static void -test_counters_op_query (void *ctx) -{ - mongoc_collection_t *coll; - mongoc_cursor_t *cursor; - const bson_t *bson; - mongoc_client_t *client; - - client = _client_new_disable_ss (false); - /* with WIRE_VERSION < 6, commands are sent over OP_QUERY with db.$cmd. */ - _ping (client); - DIFF_AND_RESET (op_egress_query, ==, 1); - DIFF_AND_RESET (op_egress_total, ==, 1); - DIFF_AND_RESET (op_ingress_reply, ==, 1); - DIFF_AND_RESET (op_ingress_total, ==, 1); - coll = _drop_and_populate_coll (client); - DIFF_AND_RESET (op_egress_query, ==, 4); - DIFF_AND_RESET (op_egress_total, ==, 4); - DIFF_AND_RESET (op_ingress_reply, ==, 4); - DIFF_AND_RESET (op_ingress_total, ==, 4); - cursor = mongoc_collection_find_with_opts ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 1}"), NULL); - while (mongoc_cursor_next (cursor, &bson)) - ; - mongoc_cursor_destroy (cursor); - DIFF_AND_RESET (op_egress_query, >, 0); - DIFF_AND_RESET (op_ingress_reply, >, 0); - DIFF_AND_RESET (op_egress_total, >, 0); - DIFF_AND_RESET (op_ingress_total, >, 0); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - - -static void -test_counters_op_getmore_killcursors (void *ctx) -{ - mongoc_collection_t *coll; - mongoc_cursor_t *cursor; - const bson_t *bson; - mongoc_client_t *client; - - client = _client_new_disable_ss (false); - coll = _drop_and_populate_coll (client); - DIFF_AND_RESET (op_egress_query, ==, 4); - DIFF_AND_RESET (op_egress_total, ==, 4); - DIFF_AND_RESET (op_ingress_reply, ==, 4); - DIFF_AND_RESET (op_ingress_total, ==, 4); - /* do *not* use batchSize 1 here. that returns one doc and closes. */ - cursor = mongoc_collection_find_with_opts ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 2}"), NULL); - while (mongoc_cursor_next (cursor, &bson)) - ; - mongoc_cursor_destroy (cursor); - DIFF_AND_RESET (op_egress_query, ==, 1); - DIFF_AND_RESET (op_ingress_reply, ==, 2); - DIFF_AND_RESET (op_egress_total, ==, 2); - DIFF_AND_RESET (op_ingress_total, ==, 2); - DIFF_AND_RESET (op_egress_getmore, ==, 1); - DIFF_AND_RESET (op_egress_killcursors, ==, 0); - cursor = mongoc_collection_find_with_opts ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 2}"), NULL); - /* only iterate once so the server keeps the cursor alive and cursor_destroy - * sends a killCursors cmd. */ - BSON_ASSERT (mongoc_cursor_next (cursor, &bson)); - mongoc_cursor_destroy (cursor); - DIFF_AND_RESET (op_egress_query, ==, 1); - DIFF_AND_RESET (op_ingress_reply, ==, 1); - DIFF_AND_RESET (op_egress_total, ==, 2); - DIFF_AND_RESET (op_ingress_total, ==, 1); - DIFF_AND_RESET (op_egress_getmore, ==, 0); - DIFF_AND_RESET (op_egress_killcursors, ==, 1); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - - -static void -test_counters_cursors (void) -{ - mongoc_collection_t *coll; - mongoc_cursor_t *cursor; - const bson_t *bson; - mongoc_client_t *client; - - client = _client_new_disable_ss (false); - coll = _drop_and_populate_coll (client); - cursor = mongoc_collection_find_with_opts ( - coll, tmp_bson ("{}"), tmp_bson ("{'batchSize': 1}"), NULL); - DIFF_AND_RESET (cursors_active, ==, 1); - while (mongoc_cursor_next (cursor, &bson)) - ; - mongoc_cursor_destroy (cursor); - DIFF_AND_RESET (cursors_active, ==, -1); - DIFF_AND_RESET (cursors_disposed, ==, 1); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - - -static void -test_counters_clients (void) -{ - mongoc_client_pool_t *client_pool; - mongoc_client_t *client; - mongoc_uri_t *uri; - uri = test_framework_get_uri (); - - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 99999); - mongoc_uri_set_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 99999); - reset_all_counters (); - client = mongoc_client_new_from_uri (uri); - BSON_ASSERT (client); - DIFF_AND_RESET (clients_active, ==, 1); - DIFF_AND_RESET (clients_disposed, ==, 0); - DIFF_AND_RESET (client_pools_active, ==, 0); - DIFF_AND_RESET (client_pools_disposed, ==, 0); - mongoc_client_destroy (client); - DIFF_AND_RESET (clients_active, ==, -1); - DIFF_AND_RESET (clients_disposed, ==, 1); - DIFF_AND_RESET (client_pools_active, ==, 0); - DIFF_AND_RESET (client_pools_disposed, ==, 0); - /* check client pools. */ - client_pool = mongoc_client_pool_new (uri); - BSON_ASSERT (client_pool); - DIFF_AND_RESET (clients_active, ==, 0); - DIFF_AND_RESET (clients_disposed, ==, 0); - DIFF_AND_RESET (client_pools_active, ==, 1); - DIFF_AND_RESET (client_pools_disposed, ==, 0); - client = mongoc_client_pool_pop (client_pool); - DIFF_AND_RESET (clients_active, ==, 1); - DIFF_AND_RESET (clients_disposed, ==, 0); - DIFF_AND_RESET (client_pools_active, ==, 0); - DIFF_AND_RESET (client_pools_disposed, ==, 0); - mongoc_client_destroy (client); - DIFF_AND_RESET (clients_active, ==, -1); - DIFF_AND_RESET (clients_disposed, ==, 1); - DIFF_AND_RESET (client_pools_active, ==, 0); - DIFF_AND_RESET (client_pools_disposed, ==, 0); - mongoc_client_pool_destroy (client_pool); - DIFF_AND_RESET (clients_active, ==, 0); - DIFF_AND_RESET (clients_disposed, ==, 0); - DIFF_AND_RESET (client_pools_active, ==, -1); - DIFF_AND_RESET (client_pools_disposed, ==, 1); - mongoc_uri_destroy (uri); -} - - -static void -test_counters_streams (void *ctx) -{ - mongoc_client_t *client = _client_new_disable_ss (false); - mongoc_socket_t *sock; - mongoc_stream_t *stream_sock; - mongoc_stream_t *buffered_stream_sock; - mongoc_stream_t *file_stream; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_stream_t *gridfs_stream; - bool used_ssl = false; - bson_error_t err; - char buf[16] = {0}; - const int TIMEOUT = 500; - mongoc_gridfs_file_opt_t gridfs_opts = {0}; - bool ret; - - /* test ingress and egress of a stream to a server. */ - _ping (client); - DIFF_AND_RESET (streams_egress, >, 0); - DIFF_AND_RESET (streams_ingress, >, 0); - /* test that creating and destroying each type of stream changes the - * streams active and not active. */ - sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - DIFF_AND_RESET (streams_active, ==, 0); - DIFF_AND_RESET (streams_disposed, ==, 0); - stream_sock = mongoc_stream_socket_new (sock); - DIFF_AND_RESET (streams_active, ==, 1); - DIFF_AND_RESET (streams_disposed, ==, 0); - buffered_stream_sock = mongoc_stream_buffered_new (stream_sock, 16); - DIFF_AND_RESET (streams_active, ==, 1); - DIFF_AND_RESET (streams_disposed, ==, 0); -#ifdef MONGOC_ENABLE_SSL - do { - const mongoc_ssl_opt_t *default_opts = mongoc_ssl_opt_get_default (); - mongoc_ssl_opt_t opts = *default_opts; - mongoc_stream_t *ssl_buffered_stream_socket; - - ssl_buffered_stream_socket = mongoc_stream_tls_new_with_hostname ( - buffered_stream_sock, NULL, &opts, 0); - DIFF_AND_RESET (streams_active, ==, 1); - DIFF_AND_RESET (streams_disposed, ==, 0); - mongoc_stream_destroy (ssl_buffered_stream_socket); - DIFF_AND_RESET (streams_active, ==, -3); - DIFF_AND_RESET (streams_disposed, ==, 3); - used_ssl = true; - } while (0); -#endif - if (!used_ssl) { - mongoc_stream_destroy (buffered_stream_sock); - DIFF_AND_RESET (streams_active, ==, -2); - DIFF_AND_RESET (streams_disposed, ==, 2); - } -/* check a file stream. */ -#ifdef WIN32 - file_stream = mongoc_stream_file_new_for_path ( - BINARY_DIR "/temp.dat", O_CREAT | O_WRONLY | O_TRUNC, _S_IWRITE); -#else - file_stream = mongoc_stream_file_new_for_path ( - BINARY_DIR "/temp.dat", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU); -#endif - BSON_ASSERT (file_stream); - DIFF_AND_RESET (streams_active, ==, 1); - DIFF_AND_RESET (streams_disposed, ==, 0); - mongoc_stream_write (file_stream, buf, 16, TIMEOUT); - DIFF_AND_RESET (streams_egress, ==, 16); - DIFF_AND_RESET (streams_ingress, ==, 0); - mongoc_stream_destroy (file_stream); - DIFF_AND_RESET (streams_active, ==, -1); - DIFF_AND_RESET (streams_disposed, ==, 1); - file_stream = - mongoc_stream_file_new_for_path (BINARY_DIR "/temp.dat", O_RDONLY, 0); - BSON_ASSERT (file_stream); - DIFF_AND_RESET (streams_active, ==, 1); - DIFF_AND_RESET (streams_disposed, ==, 0); - mongoc_stream_read (file_stream, buf, 16, 0, TIMEOUT); - DIFF_AND_RESET (streams_egress, ==, 0); - DIFF_AND_RESET (streams_ingress, ==, 16); - mongoc_stream_destroy (file_stream); - DIFF_AND_RESET (streams_active, ==, -1); - DIFF_AND_RESET (streams_disposed, ==, 1); - unlink (BINARY_DIR "/temp.dat"); - /* check a gridfs stream. */ - gridfs = mongoc_client_get_gridfs (client, "test", "fs", &err); - ASSERT_OR_PRINT (gridfs, err); - ret = mongoc_gridfs_drop (gridfs, &err); - ASSERT_OR_PRINT (ret, err); - reset_all_counters (); - gridfs_opts.filename = "example"; - file = mongoc_gridfs_create_file (gridfs, &gridfs_opts); - ASSERT_OR_PRINT (file, err); - gridfs_stream = mongoc_stream_gridfs_new (file); - DIFF_AND_RESET (streams_active, ==, 1); - DIFF_AND_RESET (streams_disposed, ==, 0); - mongoc_stream_write (gridfs_stream, buf, 16, TIMEOUT); - DIFF_AND_RESET (streams_egress, ==, 16); - DIFF_AND_RESET (streams_ingress, ==, 0); - mongoc_stream_destroy (gridfs_stream); - DIFF_AND_RESET (streams_active, ==, -1); - DIFF_AND_RESET (streams_disposed, ==, 1); - DIFF_AND_RESET (streams_egress, >, 0); - mongoc_gridfs_file_save (file); - mongoc_gridfs_file_destroy (file); - file = mongoc_gridfs_find_one_by_filename (gridfs, "example", &err); - ASSERT_OR_PRINT (file, err); - gridfs_stream = mongoc_stream_gridfs_new (file); - DIFF_AND_RESET (streams_active, ==, 1); - DIFF_AND_RESET (streams_disposed, ==, 0); - RESET (streams_egress); - mongoc_stream_read (gridfs_stream, buf, 16, 0, TIMEOUT); - DIFF_AND_RESET (streams_egress, >, 0); - DIFF_AND_RESET (streams_ingress, >, 16); - mongoc_stream_destroy (gridfs_stream); - DIFF_AND_RESET (streams_active, ==, -1); - DIFF_AND_RESET (streams_disposed, ==, 1); - mongoc_gridfs_file_destroy (file); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -static void -test_counters_auth (void *ctx) -{ - char *host_and_port = test_framework_get_host_and_port (); - char *uri_str = test_framework_get_uri_str (); - char *uri_str_bad = bson_strdup_printf ( - "mongodb://%s:%s@%s/", "bad_user", "bad_pass", host_and_port); - mongoc_client_t *client; - mongoc_uri_t *uri; - bool ret; - bson_error_t err; - - uri = mongoc_uri_new (uri_str); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 99999); - mongoc_uri_set_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 99999); - reset_all_counters (); - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - BSON_ASSERT (client); - ret = mongoc_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, &err); - ASSERT_OR_PRINT (ret, err); - DIFF_AND_RESET (auth_success, ==, 1); - DIFF_AND_RESET (auth_failure, ==, 0); - mongoc_uri_destroy (uri); - bson_free (uri_str); - bson_free (uri_str_bad); - bson_free (host_and_port); - mongoc_client_destroy (client); -} - - -static void -test_counters_dns (void) -{ - mongoc_client_t *client; - mongoc_server_description_t *sd; - bson_error_t err; - reset_all_counters (); - client = test_framework_client_new (); - sd = mongoc_client_select_server (client, false, NULL, &err); - ASSERT_OR_PRINT (sd, err); - DIFF_AND_RESET (dns_success, >, 0); - DIFF_AND_RESET (dns_failure, ==, 0); - mongoc_server_description_destroy (sd); - mongoc_client_destroy (client); - client = mongoc_client_new ("mongodb://invalidhostname/"); - test_framework_set_ssl_opts (client); - sd = mongoc_client_select_server (client, false, NULL, &err); - ASSERT (!sd); - DIFF_AND_RESET (dns_success, ==, 0); - DIFF_AND_RESET (dns_failure, ==, 1); - mongoc_client_destroy (client); -} - - -static void -test_counters_streams_timeout () -{ - mock_server_t *server; - bson_error_t err = {0}; - bool ret; - future_t *future; - mongoc_client_t *client; - request_t *request; - mongoc_uri_t *uri; - mongoc_server_description_t *sd; - - server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_SOCKETTIMEOUTMS, 300); - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - mongoc_uri_destroy (uri); - sd = mongoc_client_select_server (client, true, NULL, &err); - mongoc_server_description_destroy (sd); - reset_all_counters (); - future = future_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, NULL, &err); - request = mock_server_receives_msg ( - server, MONGOC_QUERY_NONE, tmp_bson ("{'ping': 1}")); - _mongoc_usleep (350); - request_destroy (request); - ret = future_get_bool (future); - BSON_ASSERT (!ret); - future_destroy (future); - /* can't ASSERT == because the mock server times out normally reading. */ - DIFF_AND_RESET (streams_timeout, >=, 1); - mongoc_client_destroy (client); - mock_server_destroy (server); -} -#endif - -void -test_counters_install (TestSuite *suite) -{ -#ifdef MONGOC_ENABLE_SHM_COUNTERS - TestSuite_AddFull (suite, - "/counters/op_msg", - test_counters_op_msg, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_6, - test_framework_skip_if_auth, - test_framework_skip_if_compressors); - TestSuite_AddFull (suite, - "/counters/op_compressed", - test_counters_op_compressed, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_6, - test_framework_skip_if_no_compressors, - test_framework_skip_if_auth); - /* test before OP_MSG. */ - TestSuite_AddFull (suite, - "/counters/op_query", - test_counters_op_query, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_4, - test_framework_skip_if_max_wire_version_more_than_5, - test_framework_skip_if_compressors, - test_framework_skip_if_auth); - /* test before the getMore and killCursors commands were introduced. */ - TestSuite_AddFull (suite, - "/counters/op_getmore_killcursors", - test_counters_op_getmore_killcursors, - NULL, - NULL, - test_framework_skip_if_max_wire_version_more_than_3, - test_framework_skip_if_compressors, - test_framework_skip_if_auth); - 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/auth", - test_counters_auth, - NULL, - NULL, - test_framework_skip_if_no_auth, - test_framework_skip_if_not_single); - TestSuite_AddLive (suite, "/counters/dns", test_counters_dns); - TestSuite_AddMockServerTest ( - suite, "/counters/streams_timeout", test_counters_streams_timeout); -#endif -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-crud.c b/lib/mongoc/libmongoc/tests/test-mongoc-crud.c deleted file mode 100644 index db1f2b4b0e4e937433082ff1db25cd4d9048ae92..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-crud.c +++ /dev/null @@ -1,50 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "json-test.h" -#include "json-test-operations.h" -#include "test-libmongoc.h" - -static bool -crud_test_operation_cb (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation) -{ - bson_t reply; - bool res; - - res = - json_test_operation (ctx, test, operation, ctx->collection, NULL, &reply); - - bson_destroy (&reply); - - return res; -} - -static void -test_crud_cb (bson_t *scenario) -{ - json_test_config_t config = JSON_TEST_CONFIG_INIT; - config.run_operation_cb = crud_test_operation_cb; - config.command_started_events_only = true; - config.scenario = scenario; - run_json_general_test (&config); -} - -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - test_framework_resolve_path (JSON_DIR "/crud", resolved); - - install_json_test_suite_with_check (suite, - resolved, - &test_crud_cb, - test_framework_skip_if_no_sessions); -} - -void -test_crud_install (TestSuite *suite) -{ - test_all_spec_tests (suite); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-cursor.c b/lib/mongoc/libmongoc/tests/test-mongoc-cursor.c deleted file mode 100644 index aeaadc758beaad62df23c1ffd9752deac82cc22d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-cursor.c +++ /dev/null @@ -1,2411 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-client-private.h> - -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "mock_server/mock-rs.h" -#include "mock_server/future-functions.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "test-conveniences.h" - -#define CURSOR_COMMON_SETUP \ - do { \ - bson_error_t _err; \ - bool _ret; \ - client = test_framework_client_new (); \ - coll = mongoc_client_get_collection (client, "test", "test"); \ - /* populate to ensure db and coll exist. */ \ - _ret = mongoc_collection_insert_one ( \ - coll, tmp_bson ("{}"), NULL, NULL, &_err); \ - ASSERT_OR_PRINT (_ret, _err); \ - ctor = (make_cursor_fn) ctx; \ - } while (0) - -#define CURSOR_COMMON_TEARDOWN \ - do { \ - mongoc_collection_destroy (coll); \ - mongoc_client_destroy (client); \ - } while (0) - -typedef mongoc_cursor_t *(*make_cursor_fn) (mongoc_collection_t *); - -static mongoc_cursor_t * -_make_array_cursor (mongoc_collection_t *coll); - -/* test that the host a cursor returns belongs to a server it connected to. */ -static void -_test_common_get_host (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - make_cursor_fn ctor; - mongoc_cursor_t *cursor; - const mongoc_host_list_t *hosts; - mongoc_host_list_t cursor_host; - mongoc_uri_t *uri; - const bson_t *doc; - bson_error_t err; - bool ret; - - CURSOR_COMMON_SETUP; - cursor = ctor (coll); - uri = test_framework_get_uri (); - hosts = mongoc_uri_get_hosts (uri); - ret = mongoc_cursor_next (cursor, &doc); - if (!ret && mongoc_cursor_error (cursor, &err)) { - test_error ("%s", err.message); - abort (); - } - mongoc_cursor_get_host (cursor, &cursor_host); - /* In a production deployment the driver can discover servers not in the seed - * list, but for this test assume the cursor uses one of the seeds. */ - while (hosts) { - if (strcmp (cursor_host.host_and_port, hosts->host_and_port) == 0) { - /* the cursor is using this server */ - ASSERT_CMPSTR (cursor_host.host, hosts->host); - ASSERT_CMPINT (cursor_host.port, ==, hosts->port); - ASSERT_CMPINT (cursor_host.family, ==, hosts->family); - break; - } - hosts = hosts->next; - } - mongoc_uri_destroy (uri); - mongoc_cursor_destroy (cursor); - CURSOR_COMMON_TEARDOWN; -} - - -/* test cloning cursors returns the same results. */ -static void -_test_common_clone (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - make_cursor_fn ctor; - mongoc_cursor_t *cursor; - mongoc_cursor_t *cloned; - const bson_t *doc; - bson_error_t err; - - CURSOR_COMMON_SETUP; - cursor = ctor (coll); - cloned = mongoc_cursor_clone (cursor); - /* check that both cursors return the same number of documents. don't check - * that they return the same exact documents. A cursor on the listDatabases - * returns the database size, which may change in the background. */ - while (mongoc_cursor_next (cursor, &doc)) { - BSON_ASSERT (mongoc_cursor_next (cloned, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cloned, &err), err); - } - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &err), err); - BSON_ASSERT (!mongoc_cursor_next (cloned, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cloned, &err), err); - mongoc_cursor_destroy (cursor); - mongoc_cursor_destroy (cloned); - CURSOR_COMMON_TEARDOWN; -} - - -/* test cloning cursors with read and write concerns set. */ -static void -_test_common_clone_w_concerns (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - make_cursor_fn ctor; - mongoc_cursor_t *cursor; - mongoc_cursor_t *cloned; - mongoc_read_concern_t *read_concern; - mongoc_write_concern_t *write_concern; - const bson_t *bson; - bson_iter_t iter; - - CURSOR_COMMON_SETUP; - cursor = ctor (coll); - read_concern = mongoc_read_concern_new (); - ASSERT (read_concern); - mongoc_read_concern_set_level (read_concern, - MONGOC_READ_CONCERN_LEVEL_LOCAL); - write_concern = mongoc_write_concern_new (); - ASSERT (write_concern); - mongoc_write_concern_set_fsync (write_concern, true); - mongoc_write_concern_set_journal (write_concern, true); - mongoc_write_concern_set_wmajority (write_concern, 1000); - cursor->write_concern = write_concern; - mongoc_read_concern_destroy (cursor->read_concern); - cursor->read_concern = read_concern; - /* don't call mongoc_cursor_next (), since the test may run against a version - * of MongoDB that doesn't support read/write concerns, and we are only - * interested in testing if the clone process works. */ - cloned = mongoc_cursor_clone (cursor); - /* test cloned read_concern. */ - ASSERT (!mongoc_read_concern_is_default (cloned->read_concern)); - ASSERT_CMPSTR (mongoc_read_concern_get_level (cloned->read_concern), - MONGOC_READ_CONCERN_LEVEL_LOCAL); - /* test cloned write_concern. */ - ASSERT (mongoc_write_concern_get_wmajority (cloned->write_concern)); - ASSERT (mongoc_write_concern_get_wtimeout_int64 (cloned->write_concern) == 1000); - ASSERT (mongoc_write_concern_get_w (cloned->write_concern) == - MONGOC_WRITE_CONCERN_W_MAJORITY); - /* check generated bson in cloned cursor. */ - ASSERT_MATCH (_mongoc_read_concern_get_bson (cloned->read_concern), - "{'level': 'local'}"); - bson = _mongoc_write_concern_get_bson (cloned->write_concern); - ASSERT (bson); - ASSERT (bson_iter_init_find (&iter, bson, "fsync") && - BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)); - ASSERT (bson_iter_init_find (&iter, bson, "j") && - BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)); - ASSERT (bson_iter_init_find (&iter, bson, "w") && - BSON_ITER_HOLDS_UTF8 (&iter)); - ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL), "majority"); - mongoc_cursor_destroy (cursor); - mongoc_cursor_destroy (cloned); - CURSOR_COMMON_TEARDOWN; -} - - -/* test calling mongoc_cursor_next again after it returns false. */ -static void -_test_common_advancing_past_end (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - make_cursor_fn ctor; - mongoc_cursor_t *cursor; - const bson_t *doc; - const bson_t *current; - const bson_t *err_doc; - bson_error_t err; - - CURSOR_COMMON_SETUP; - cursor = ctor (coll); - while (mongoc_cursor_next (cursor, &doc)) { - current = mongoc_cursor_current (cursor); - /* should be same address. */ - BSON_ASSERT (doc == current); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &err), err); - /* cursor will report more until certain there are no documents left. */ - ASSERT (mongoc_cursor_more (cursor)); - } - /* advance one past the end. */ - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (mongoc_cursor_error (cursor, &err)); - BSON_ASSERT (mongoc_cursor_error_document (cursor, &err, &err_doc)); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot advance a completed or failed cursor."); - /* this is not a server error, the error document should be NULL. */ - BSON_ASSERT (bson_empty (err_doc)); - mongoc_cursor_destroy (cursor); - CURSOR_COMMON_TEARDOWN; -} - - -typedef struct { - char *expected_host_and_port; - bool called; -} test_common_server_hint_ctx_t; - - -static void -_test_common_server_hint_command_started ( - const mongoc_apm_command_started_t *event) -{ - const mongoc_host_list_t *host = mongoc_apm_command_started_get_host (event); - const char *cmd = mongoc_apm_command_started_get_command_name (event); - test_common_server_hint_ctx_t *ctx; - /* only check command associated with cursor priming. */ - if (strcmp (cmd, "find") == 0 || strcmp (cmd, "ping") == 0 || - strcmp (cmd, "listDatabases") == 0) { - ctx = (test_common_server_hint_ctx_t *) - mongoc_apm_command_started_get_context (event); - ASSERT_CMPSTR (host->host_and_port, ctx->expected_host_and_port); - BSON_ASSERT (!ctx->called); - ctx->called = true; - } -} - - -/* test setting the server id (hint) on cursors that support it. */ -static void -_test_common_server_hint (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - make_cursor_fn ctor; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t err; - mongoc_server_description_t *sd; - mongoc_read_prefs_t *read_prefs; - test_common_server_hint_ctx_t test_ctx = {0}; - mongoc_apm_callbacks_t *callbacks; - - CURSOR_COMMON_SETUP; - /* set APM callbacks, and then set server hint. Make sure we target the same - * host that we select. */ - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, - _test_common_server_hint_command_started); - cursor = ctor (coll); - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - sd = mongoc_client_select_server (client, false, read_prefs, &err); - ASSERT_OR_PRINT (sd, err); - test_ctx.expected_host_and_port = bson_strdup (sd->host.host_and_port); - mongoc_read_prefs_destroy (read_prefs); - mongoc_client_set_apm_callbacks (client, callbacks, &test_ctx); - mongoc_apm_callbacks_destroy (callbacks); - BSON_ASSERT (mongoc_cursor_set_hint (cursor, sd->id)); - ASSERT_CMPUINT32 (mongoc_cursor_get_hint (cursor), ==, sd->id); - mongoc_server_description_destroy (sd); - - BSON_ASSERT (mongoc_cursor_next (cursor, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &err), err); - mongoc_cursor_destroy (cursor); - bson_free (test_ctx.expected_host_and_port); - BSON_ASSERT (test_ctx.called); - CURSOR_COMMON_TEARDOWN; -} - - -/* test setting options on unprimed, non-aggregate cursors. */ -static void -_test_common_opts (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - make_cursor_fn ctor; - mongoc_cursor_t *cursor; - const bson_t *doc; - mongoc_server_description_t *sd; - bson_error_t err; - - CURSOR_COMMON_SETUP; - sd = mongoc_client_select_server (client, true, NULL, &err); - ASSERT_OR_PRINT (sd, err); - cursor = ctor (coll); - /* check that we get what we set. */ - BSON_ASSERT (mongoc_cursor_set_hint (cursor, sd->id)); - ASSERT_CMPINT (mongoc_cursor_get_hint (cursor), ==, sd->id); - - /* listDatabases prohibits limit and batchSize */ - if ((make_cursor_fn) ctx != _make_array_cursor) { - mongoc_cursor_set_batch_size (cursor, 1); - ASSERT_CMPINT (mongoc_cursor_get_batch_size (cursor), ==, 1); - BSON_ASSERT (mongoc_cursor_set_limit (cursor, 2)); - ASSERT_CMPINT ((int) mongoc_cursor_get_limit (cursor), ==, 2); - } - - mongoc_cursor_set_max_await_time_ms (cursor, 3); - ASSERT_CMPINT (mongoc_cursor_get_max_await_time_ms (cursor), ==, 3); - /* prime the cursor. */ - BSON_ASSERT (mongoc_cursor_next (cursor, &doc)); - /* options should be unchanged. */ - ASSERT_CMPINT (mongoc_cursor_get_hint (cursor), ==, sd->id); - if ((make_cursor_fn) ctx != _make_array_cursor) { - ASSERT_CMPINT (mongoc_cursor_get_batch_size (cursor), ==, 1); - ASSERT_CMPINT ((int) mongoc_cursor_get_limit (cursor), ==, 2); - /* limit cannot be set again. */ - BSON_ASSERT (!mongoc_cursor_set_limit (cursor, 5)); - ASSERT_CMPINT ((int) mongoc_cursor_get_limit (cursor), ==, 2); - } - - ASSERT_CMPINT (mongoc_cursor_get_max_await_time_ms (cursor), ==, 3); - /* trying to set hint again logs an error. */ - capture_logs (true); - BSON_ASSERT (!mongoc_cursor_set_hint (cursor, 123)); - capture_logs (false); - ASSERT_CMPINT (mongoc_cursor_get_hint (cursor), ==, sd->id); - /* batch size can be set again without issue. */ - mongoc_cursor_set_batch_size (cursor, 4); - ASSERT_CMPINT (mongoc_cursor_get_batch_size (cursor), ==, 4); - /* max await time ms cannot be set (but fails quietly). */ - mongoc_cursor_set_max_await_time_ms (cursor, 6); - ASSERT_CMPINT (mongoc_cursor_get_max_await_time_ms (cursor), ==, 3); - mongoc_cursor_destroy (cursor); - mongoc_server_description_destroy (sd); - CURSOR_COMMON_TEARDOWN; -} - - -/* test setting options on cursors that are primed on construction. */ -static void -_test_common_opts_after_prime (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - make_cursor_fn ctor; - mongoc_cursor_t *cursor; - - CURSOR_COMMON_SETUP; - cursor = ctor (coll); - /* trying to set hint logs an error. */ - capture_logs (true); - BSON_ASSERT (!mongoc_cursor_set_hint (cursor, 123)); - capture_logs (false); - ASSERT_CMPINT (mongoc_cursor_get_hint (cursor), !=, 0); - /* batch size can be set again without issue. */ - mongoc_cursor_set_batch_size (cursor, 4); - ASSERT_CMPINT (mongoc_cursor_get_batch_size (cursor), ==, 4); - /* limit cannot be set. */ - BSON_ASSERT (!mongoc_cursor_set_limit (cursor, 5)); - ASSERT_CMPINT ((int) mongoc_cursor_get_limit (cursor), ==, 0); - /* max await time ms cannot be set (but fails quietly). */ - mongoc_cursor_set_max_await_time_ms (cursor, 6); - ASSERT_CMPINT (mongoc_cursor_get_max_await_time_ms (cursor), ==, 0); - mongoc_cursor_destroy (cursor); - CURSOR_COMMON_TEARDOWN; -} - - -/* test setting options on a cursor constructed from an aggregation. */ -static void -_test_common_opts_agg (void *ctx) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - make_cursor_fn ctor; - mongoc_cursor_t *cursor; - - CURSOR_COMMON_SETUP; - cursor = ctor (coll); - /* trying to set hint logs an error. */ - capture_logs (true); - BSON_ASSERT (!mongoc_cursor_set_hint (cursor, 123)); - capture_logs (false); - ASSERT_CMPINT (mongoc_cursor_get_hint (cursor), !=, 0); - /* batch size can be set again without issue. */ - mongoc_cursor_set_batch_size (cursor, 4); - ASSERT_CMPINT (mongoc_cursor_get_batch_size (cursor), ==, 4); - /* limit can be set. */ - BSON_ASSERT (mongoc_cursor_set_limit (cursor, 5)); - ASSERT_CMPINT ((int) mongoc_cursor_get_limit (cursor), ==, 5); - /* max await time ms can be set. */ - mongoc_cursor_set_max_await_time_ms (cursor, 6); - ASSERT_CMPINT (mongoc_cursor_get_max_await_time_ms (cursor), ==, 6); - mongoc_cursor_destroy (cursor); - CURSOR_COMMON_TEARDOWN; -} - - -static mongoc_cursor_t * -_make_find_cursor (mongoc_collection_t *coll) -{ - return mongoc_collection_find_with_opts (coll, tmp_bson ("{}"), NULL, NULL); -} - - -static mongoc_cursor_t * -_make_cmd_cursor (mongoc_collection_t *coll) -{ - return mongoc_collection_find_indexes_with_opts (coll, NULL); -} - - -static mongoc_cursor_t * -_make_cmd_cursor_from_agg (mongoc_collection_t *coll) -{ - return mongoc_collection_aggregate ( - coll, MONGOC_QUERY_SLAVE_OK, tmp_bson ("{}"), NULL, NULL); -} - - -static mongoc_cursor_t * -_make_cmd_deprecated_cursor (mongoc_collection_t *coll) -{ - return mongoc_collection_command (coll, - MONGOC_QUERY_SLAVE_OK, - 0, - 0, - 0, - tmp_bson ("{'ping': 1}"), - NULL, - NULL); -} - - -static mongoc_cursor_t * -_make_array_cursor (mongoc_collection_t *coll) -{ - return mongoc_client_find_databases_with_opts (coll->client, NULL); -} - -#define TEST_CURSOR_FIND(prefix, fn) \ - TestSuite_AddFull (suite, \ - prefix "/find", \ - fn, \ - NULL, \ - _make_find_cursor, \ - TestSuite_CheckLive); - -#define TEST_CURSOR_CMD(prefix, fn) \ - TestSuite_AddFull ( \ - suite, prefix "/cmd", fn, NULL, _make_cmd_cursor, TestSuite_CheckLive); - -#define TEST_CURSOR_CMD_DEPRECATED(prefix, fn) \ - TestSuite_AddFull (suite, \ - prefix "/cmd_deprecated", \ - fn, \ - NULL, \ - _make_cmd_deprecated_cursor, \ - TestSuite_CheckLive); - -#define TEST_CURSOR_ARRAY(prefix, fn) \ - TestSuite_AddFull (suite, \ - prefix "/array", \ - fn, \ - NULL, \ - _make_array_cursor, \ - TestSuite_CheckLive); - -#define TEST_CURSOR_AGG(prefix, fn) \ - TestSuite_AddFull (suite, \ - prefix "/agg", \ - fn, \ - NULL, \ - _make_cmd_cursor_from_agg, \ - TestSuite_CheckLive); - - -#define TEST_FOREACH_CURSOR(prefix, fn) \ - TEST_CURSOR_FIND (prefix, fn); \ - TEST_CURSOR_CMD (prefix, fn); \ - TEST_CURSOR_CMD_DEPRECATED (prefix, fn); \ - TEST_CURSOR_ARRAY (prefix, fn); \ - TEST_CURSOR_AGG (prefix, fn); - - -static void -test_common_cursor_functions_install (TestSuite *suite) -{ - /* test functionality common to all cursor implementations. */ - TEST_FOREACH_CURSOR ("/Cursor/common/get_host", _test_common_get_host); - TEST_FOREACH_CURSOR ("/Cursor/common/clone", _test_common_clone); - TEST_FOREACH_CURSOR ("/Cursor/common/clone_w_concerns", - _test_common_clone_w_concerns); - TEST_FOREACH_CURSOR ("/Cursor/common/advancing_past_end", - _test_common_advancing_past_end); - /* an agg/cmd cursors do not support setting server id. test others. */ - TEST_CURSOR_FIND ("/Cursor/common/hint", _test_common_server_hint); - TEST_CURSOR_CMD_DEPRECATED ("/Cursor/common/hint", _test_common_server_hint); - TEST_CURSOR_ARRAY ("/Cursor/common/hint", _test_common_server_hint); - /* find, cmd_depr, and array cursors can have all options set. */ - TEST_CURSOR_FIND ("/Cursor/common/opts", _test_common_opts); - TEST_CURSOR_CMD_DEPRECATED ("/Cursor/common/opts", _test_common_opts); - TEST_CURSOR_ARRAY ("/Cursor/common/opts", _test_common_opts); - /* a command cursor created from find_indexes_with_opts is already primed. */ - TEST_CURSOR_CMD ("/Cursor/common/opts", _test_common_opts_after_prime); - /* a command cursor created from an agg has the server id set, but is not - * primed. */ - TEST_CURSOR_AGG ("/Cursor/common/opts", _test_common_opts_agg); -} - - -static void -test_limit (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *b; - bson_t *opts; - int i, n_docs; - mongoc_cursor_t *cursor; - bson_error_t error; - int64_t limits[] = {5, -5}; - const bson_t *doc = NULL; - bool r; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_limit"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - b = tmp_bson ("{}"); - for (i = 0; i < 10; ++i) { - mongoc_bulk_operation_insert (bulk, b); - } - - r = (0 != mongoc_bulk_operation_execute (bulk, NULL, &error)); - ASSERT_OR_PRINT (r, error); - - /* test positive and negative limit */ - for (i = 0; i < 2; i++) { - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, tmp_bson ("{}"), NULL, NULL); - ASSERT_CMPINT64 ((int64_t) 0, ==, mongoc_cursor_get_limit (cursor)); - ASSERT (mongoc_cursor_set_limit (cursor, limits[i])); - ASSERT_CMPINT64 (limits[i], ==, mongoc_cursor_get_limit (cursor)); - n_docs = 0; - while (mongoc_cursor_next (cursor, &doc)) { - ++n_docs; - } - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - ASSERT (!mongoc_cursor_more (cursor)); - ASSERT_CMPINT (n_docs, ==, 5); - ASSERT (!mongoc_cursor_set_limit (cursor, 123)); /* no effect */ - ASSERT_CMPINT64 (limits[i], ==, mongoc_cursor_get_limit (cursor)); - - mongoc_cursor_destroy (cursor); - - if (limits[i] > 0) { - opts = - tmp_bson ("{'limit': {'$numberLong': '%" PRId64 "'}}", limits[i]); - } else { - opts = tmp_bson ( - "{'singleBatch': true, 'limit': {'$numberLong': '%" PRId64 "'}}", - -limits[i]); - } - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), opts, NULL); - - ASSERT_CMPINT64 (limits[i], ==, mongoc_cursor_get_limit (cursor)); - n_docs = 0; - while (mongoc_cursor_next (cursor, &doc)) { - ++n_docs; - } - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - ASSERT_CMPINT (n_docs, ==, 5); - - mongoc_cursor_destroy (cursor); - } - - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -typedef struct { - int succeeded_count; - int64_t cursor_id; -} killcursors_test_t; - - -static void -killcursors_succeeded (const mongoc_apm_command_succeeded_t *event) -{ - killcursors_test_t *ctx; - const bson_t *reply; - bson_iter_t iter; - bson_iter_t array; - - if (bson_strcasecmp (mongoc_apm_command_succeeded_get_command_name (event), - "killcursors") != 0) { - return; - } - - ctx = - (killcursors_test_t *) mongoc_apm_command_succeeded_get_context (event); - ctx->succeeded_count++; - - if (!test_framework_max_wire_version_at_least ( - WIRE_VERSION_KILLCURSORS_CMD)) { - return; - } - - reply = mongoc_apm_command_succeeded_get_reply (event); - -#define ASSERT_EMPTY(_fieldname) \ - BSON_ASSERT (bson_iter_init_find (&iter, reply, (_fieldname))); \ - BSON_ASSERT (bson_iter_recurse (&iter, &array)); \ - BSON_ASSERT (!bson_iter_next (&array)); - - ASSERT_EMPTY ("cursorsNotFound"); - ASSERT_EMPTY ("cursorsAlive"); - ASSERT_EMPTY ("cursorsUnknown"); - - BSON_ASSERT (bson_iter_init_find (&iter, reply, "cursorsKilled")); - BSON_ASSERT (bson_iter_recurse (&iter, &array)); - BSON_ASSERT (bson_iter_next (&array)); - ASSERT_CMPINT64 (ctx->cursor_id, ==, bson_iter_int64 (&array)); -} - -extern void -_mongoc_cursor_impl_find_opquery_init (mongoc_cursor_t *cursor, bson_t *filter); - -/* test killing a cursor with mongo_cursor_destroy and a real server */ -static void -test_kill_cursor_live (void) -{ - mongoc_apm_callbacks_t *callbacks; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *b; - mongoc_bulk_operation_t *bulk; - int i; - bson_error_t error; - uint32_t server_id; - bool r; - mongoc_cursor_t *cursor; - const bson_t *doc; - killcursors_test_t ctx; - - ctx.succeeded_count = 0; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_succeeded_cb (callbacks, killcursors_succeeded); - client = test_framework_client_new (); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - collection = get_test_collection (client, "test"); - b = tmp_bson ("{}"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - for (i = 0; i < 200; i++) { - mongoc_bulk_operation_insert (bulk, b); - } - - server_id = mongoc_bulk_operation_execute (bulk, NULL, &error); - ASSERT_OR_PRINT (server_id > 0, error); - - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0, - 0, - 2, /* batch size 2 */ - b, - NULL, - NULL); - - r = mongoc_cursor_next (cursor, &doc); - ASSERT (r); - ctx.cursor_id = mongoc_cursor_get_id (cursor); - ASSERT (ctx.cursor_id); - - /* sends OP_KILLCURSORS or killCursors command to server */ - mongoc_cursor_destroy (cursor); - - ASSERT_CMPINT (ctx.succeeded_count, ==, 1); - - b = bson_new (); - cursor = _mongoc_cursor_find_new ( - client, collection->ns, b, NULL, NULL, NULL, NULL); - /* override the typical priming, and immediately transition to an OPQUERY - * find cursor. */ - cursor->impl.destroy (&cursor->impl); - _mongoc_cursor_impl_find_opquery_init (cursor, b); - - cursor->cursor_id = ctx.cursor_id; - cursor->state = END_OF_BATCH; /* meaning, "finished reading first batch" */ - r = mongoc_cursor_next (cursor, &doc); - ASSERT (!r); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_CURSOR, 16, "cursor is invalid"); - - mongoc_cursor_destroy (cursor); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_apm_callbacks_destroy (callbacks); -} - - -/* test OP_KILLCURSORS or the killCursors command with mock servers */ -static void -_test_kill_cursors (bool pooled, bool use_killcursors_cmd) -{ - mock_rs_t *rs; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *q = BCON_NEW ("a", BCON_INT32 (1)); - mongoc_read_prefs_t *prefs; - mongoc_cursor_t *cursor; - const bson_t *doc = NULL; - future_t *future; - request_t *request; - bson_error_t error; - request_t *kill_cursors; - const char *ns_out; - int64_t cursor_id_out; - - rs = - mock_rs_with_autoismaster (use_killcursors_cmd ? 4 : 3, /* wire version */ - true, /* has primary */ - 5, /* number of secondaries */ - 0); /* number of arbiters */ - - mock_rs_run (rs); - - if (pooled) { - pool = mongoc_client_pool_new (mock_rs_get_uri (rs)); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - } - - collection = mongoc_client_get_collection (client, "db", "collection"); - - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, q, NULL, prefs); - - future = future_cursor_next (cursor, &doc); - request = mock_rs_receives_request (rs); - - /* reply as appropriate to OP_QUERY or find command */ - mock_rs_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK, - 123, - 1, - "db.collection", - "{'b': 1}", - use_killcursors_cmd); - - if (!future_get_bool (future)) { - mongoc_cursor_error (cursor, &error); - fprintf (stderr, "%s\n", error.message); - abort (); - }; - - ASSERT_MATCH (doc, "{'b': 1}"); - ASSERT_CMPINT (123, ==, (int) mongoc_cursor_get_id (cursor)); - - future_destroy (future); - future = future_cursor_destroy (cursor); - - if (use_killcursors_cmd) { - kill_cursors = - mock_rs_receives_command (rs, "db", MONGOC_QUERY_SLAVE_OK, NULL); - - /* mock server framework can't test "cursors" array, CDRIVER-994 */ - ASSERT (BCON_EXTRACT ((bson_t *) request_get_doc (kill_cursors, 0), - "killCursors", - BCONE_UTF8 (ns_out), - "cursors", - "[", - BCONE_INT64 (cursor_id_out), - "]")); - - ASSERT_CMPSTR ("collection", ns_out); - ASSERT_CMPINT64 ((int64_t) 123, ==, cursor_id_out); - - mock_rs_replies_simple (request, "{'ok': 1}"); - } else { - kill_cursors = mock_rs_receives_kill_cursors (rs, 123); - } - - /* OP_KILLCURSORS was sent to the right secondary */ - ASSERT_CMPINT (request_get_server_port (kill_cursors), - ==, - request_get_server_port (request)); - - BSON_ASSERT (future_wait (future)); - - request_destroy (kill_cursors); - request_destroy (request); - future_destroy (future); - mongoc_read_prefs_destroy (prefs); - mongoc_collection_destroy (collection); - bson_destroy (q); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mock_rs_destroy (rs); -} - - -static void -test_kill_cursors_single (void) -{ - _test_kill_cursors (false, false); -} - - -static void -test_kill_cursors_pooled (void) -{ - _test_kill_cursors (true, false); -} - - -static void -test_kill_cursors_single_cmd (void) -{ - _test_kill_cursors (false, true); -} - - -static void -test_kill_cursors_pooled_cmd (void) -{ - _test_kill_cursors (true, true); -} - - -/* We already test that mongoc_cursor_destroy sends OP_KILLCURSORS in - * test_kill_cursors_single / pooled. Here, test explicit - * mongoc_client_kill_cursor. */ -static void -_test_client_kill_cursor (bool has_primary, bool wire_version_4) -{ - mock_rs_t *rs; - mongoc_client_t *client; - mongoc_read_prefs_t *read_prefs; - bson_error_t error; - future_t *future; - request_t *request; - - rs = mock_rs_with_autoismaster (wire_version_4 ? 4 : 3, - has_primary, /* maybe a primary*/ - 1, /* definitely a secondary */ - 0); /* no arbiter */ - mock_rs_run (rs); - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - /* make client open a connection - it won't open one to kill a cursor */ - future = future_client_command_simple ( - client, "admin", tmp_bson ("{'foo': 1}"), read_prefs, NULL, &error); - - request = - mock_rs_receives_command (rs, "admin", MONGOC_QUERY_SLAVE_OK, NULL); - - mock_rs_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - request_destroy (request); - future_destroy (future); - - future = future_client_kill_cursor (client, 123); - mock_rs_set_request_timeout_msec (rs, 100); - - /* we don't pass namespace so client always sends legacy OP_KILLCURSORS */ - request = mock_rs_receives_kill_cursors (rs, 123); - - if (has_primary) { - BSON_ASSERT (request); - - /* weird but true. see mongoc_client_kill_cursor's documentation */ - BSON_ASSERT (mock_rs_request_is_to_primary (rs, request)); - - request_destroy (request); /* server has no reply to OP_KILLCURSORS */ - } else { - /* TODO: catch and check warning */ - BSON_ASSERT (!request); - } - - future_wait (future); /* no return value */ - future_destroy (future); - mongoc_read_prefs_destroy (read_prefs); - mongoc_client_destroy (client); - mock_rs_destroy (rs); -} - -static void -test_client_kill_cursor_with_primary (void) -{ - _test_client_kill_cursor (true, false); -} - - -static void -test_client_kill_cursor_without_primary (void) -{ - _test_client_kill_cursor (false, false); -} - - -static void -test_client_kill_cursor_with_primary_wire_version_4 (void) -{ - _test_client_kill_cursor (true, true); -} - - -static void -test_client_kill_cursor_without_primary_wire_version_4 (void) -{ - _test_client_kill_cursor (false, true); -} - - -static int -count_docs (mongoc_cursor_t *cursor) -{ - int n = 0; - const bson_t *doc; - bson_error_t error; - - while (mongoc_cursor_next (cursor, &doc)) { - ++n; - } - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - return n; -} - - -static void -_test_cursor_new_from_command (const char *cmd_json, - const char *collection_name) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bool r; - bson_error_t error; - mongoc_server_description_t *sd; - uint32_t server_id; - bson_t reply; - mongoc_cursor_t *cmd_cursor; - - client = test_framework_client_new (); - collection = mongoc_client_get_collection (client, "test", collection_name); - mongoc_collection_delete_many ( - collection, tmp_bson ("{}"), NULL, NULL, NULL); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 'a'}")); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 'b'}")); - r = (0 != mongoc_bulk_operation_execute (bulk, NULL, &error)); - ASSERT_OR_PRINT (r, error); - - sd = mongoc_topology_select (client->topology, MONGOC_SS_READ, NULL, &error); - - ASSERT_OR_PRINT (sd, error); - server_id = sd->id; - mongoc_client_command_simple_with_server_id ( - client, "test", tmp_bson (cmd_json), NULL, server_id, &reply, &error); - cmd_cursor = mongoc_cursor_new_from_command_reply_with_opts ( - client, &reply, tmp_bson ("{'serverId': %d}", server_id)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cmd_cursor, &error), error); - ASSERT_CMPUINT32 (server_id, ==, mongoc_cursor_get_hint (cmd_cursor)); - ASSERT_CMPINT (count_docs (cmd_cursor), ==, 2); - - mongoc_cursor_destroy (cmd_cursor); - mongoc_server_description_destroy (sd); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_cursor_empty_collection (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - const bson_t *doc; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - collection = mongoc_client_get_collection ( - client, "test", "test_cursor_empty_collection"); - mongoc_collection_delete_many ( - collection, tmp_bson ("{}"), NULL, NULL, NULL); - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), NULL, NULL); - - ASSERT (cursor); - ASSERT (!mongoc_cursor_error (cursor, &error)); - ASSERT (mongoc_cursor_more (cursor)); - - mongoc_cursor_next (cursor, &doc); - - ASSERT (!mongoc_cursor_error (cursor, &error)); - ASSERT (!mongoc_cursor_more (cursor)); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_cursor_new_from_aggregate (void) -{ - _test_cursor_new_from_command ( - "{'aggregate': 'test_cursor_new_from_aggregate'," - " 'pipeline': [], 'cursor': {}}", - "test_cursor_new_from_aggregate"); -} - - -static void -test_cursor_new_from_aggregate_no_initial (void) -{ - _test_cursor_new_from_command ( - "{'aggregate': 'test_cursor_new_from_aggregate_no_initial'," - " 'pipeline': [], 'cursor': {'batchSize': 0}}", - "test_cursor_new_from_aggregate_no_initial"); -} - - -static void -test_cursor_new_from_find (void *ctx) -{ - _test_cursor_new_from_command ("{'find': 'test_cursor_new_from_find'}", - "test_cursor_new_from_find"); -} - - -static void -test_cursor_new_from_find_batches (void *ctx) -{ - _test_cursor_new_from_command ( - "{'find': 'test_cursor_new_from_find_batches', 'batchSize': 1}", - "test_cursor_new_from_find_batches"); -} - - -static void -test_cursor_new_invalid (void) -{ - mongoc_client_t *client; - bson_error_t error; - mongoc_cursor_t *cursor; - bson_t b = BSON_INITIALIZER; - const bson_t *error_doc; - - client = test_framework_client_new (); - cursor = mongoc_cursor_new_from_command_reply_with_opts (client, &b, NULL); - ASSERT (cursor); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Couldn't parse cursor document"); - - ASSERT (mongoc_cursor_error_document (cursor, &error, &error_doc)); - ASSERT (bson_empty (error_doc)); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); -} - - -static void -test_cursor_new_tailable_await (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - future_t *future; - request_t *request; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - cursor = mongoc_cursor_new_from_command_reply_with_opts ( - client, - bson_copy (tmp_bson ("{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '123'}," - " 'ns': 'db.collection'," - " 'firstBatch': []" - " }," - " 'tailable': true," - " 'awaitData': true," - " 'maxAwaitTimeMS': 100" - "}")), - tmp_bson ("{'tailable': true," - " 'awaitData': true," - " 'maxAwaitTimeMS': 100" - "}")); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'getMore': {'$numberLong': '123'}," - " 'collection': 'collection'," - " 'maxTimeMS': 100" - "}"); - mock_server_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK, - 0 /* cursor id */, - 1 /* number returned */, - "db.collection", - "{'_id': 1}", - true); - - BSON_ASSERT (future_get_bool (future)); - ASSERT_MATCH (doc, "{'_id': 1}"); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_cursor_int64_t_maxtimems (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - future_t *future; - request_t *request; - bson_t *max_await_time_ms; - uint64_t ms_int64 = UINT32_MAX + (uint64_t) 1; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - max_await_time_ms = tmp_bson (NULL); - bson_append_bool (max_await_time_ms, "tailable", 8, true); - bson_append_bool (max_await_time_ms, "awaitData", 9, true); - bson_append_int64 (max_await_time_ms, - MONGOC_CURSOR_MAX_AWAIT_TIME_MS, - MONGOC_CURSOR_MAX_AWAIT_TIME_MS_LEN, - ms_int64); - - cursor = mongoc_cursor_new_from_command_reply_with_opts ( - client, - bson_copy (tmp_bson ("{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '123'}," - " 'ns': 'db.collection'," - " 'firstBatch': []" - " }" - "}")), - max_await_time_ms); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'getMore': {'$numberLong': '123'}," - " 'collection': 'collection'," - " 'maxTimeMS': {'$numberLong': '%" PRIu64 "'}" - "}", - ms_int64); - mock_server_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK, - 0 /* cursor id */, - 1 /* number returned */, - "db.collection", - "{'_id': 1}", - true); - - BSON_ASSERT (future_get_bool (future)); - ASSERT_MATCH (doc, "{'_id': 1}"); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_cursor_new_ignores_fields (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - cursor = mongoc_cursor_new_from_command_reply_with_opts ( - client, - bson_copy (tmp_bson ("{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'test.foo'," - " 'firstBatch': []" - " }," - " 'operationTime' : {}," - " '$clusterTime': {}," - " '$gleStats': {}" - "}")), - tmp_bson ("{'batchSize': 10}")); - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - ASSERT_MATCH (&cursor->opts, "{'batchSize': 10}"); - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_cursor_new_invalid_filter (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *error_doc; - - client = test_framework_client_new (); - collection = mongoc_client_get_collection (client, "test", "test"); - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{'': 1}"), NULL, NULL); - - ASSERT (cursor); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Invalid filter: empty key"); - - ASSERT (mongoc_cursor_error_document (cursor, &error, &error_doc)); - ASSERT (bson_empty (error_doc)); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_cursor_new_invalid_opts (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *error_doc; - - client = test_framework_client_new (); - collection = mongoc_client_get_collection (client, "test", "test"); - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), tmp_bson ("{'projection': {'': 1}}"), NULL); - - ASSERT (cursor); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Invalid opts: empty key"); - - ASSERT (mongoc_cursor_error_document (cursor, &error, &error_doc)); - ASSERT (bson_empty (error_doc)); - mongoc_cursor_destroy (cursor); - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), tmp_bson ("{'$invalid': 1}"), NULL); - - ASSERT (cursor); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot use $-modifiers in opts: \"$invalid\""); - - ASSERT (mongoc_cursor_error_document (cursor, &error, &error_doc)); - ASSERT (bson_empty (error_doc)); - - mongoc_cursor_destroy (cursor); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_cursor_new_static (void) -{ - mongoc_client_t *client; - bson_error_t error; - mongoc_cursor_t *cursor; - bson_t *bson_alloced; - bson_t bson_static; - bson_t *bson_copied; - - bson_alloced = tmp_bson ("{ 'ok':1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'test.foo'," - " 'firstBatch': [{'x': 1}, {'x': 2}]}}"); - - ASSERT (bson_init_static ( - &bson_static, bson_get_data (bson_alloced), bson_alloced->len)); - - /* test heap-allocated bson */ - client = test_framework_client_new (); - bson_copied = bson_copy (bson_alloced); - cursor = mongoc_cursor_new_from_command_reply_with_opts ( - client, bson_copied, NULL); - - ASSERT (cursor); - ASSERT (!mongoc_cursor_error (cursor, &error)); - mongoc_cursor_destroy (cursor); - - /* test static bson */ - cursor = mongoc_cursor_new_from_command_reply_with_opts ( - client, &bson_static, NULL); - ASSERT (cursor); - ASSERT (!mongoc_cursor_error (cursor, &error)); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); -} - - -static void -test_cursor_hint_errors (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - - client = test_framework_client_new (); - collection = mongoc_client_get_collection (client, "db", "collection"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, tmp_bson ("{}"), NULL, NULL); - - capture_logs (true); - ASSERT (!mongoc_cursor_set_hint (cursor, 0)); - ASSERT_CAPTURED_LOG ("mongoc_cursor_set_hint", - MONGOC_LOG_LEVEL_ERROR, - "cannot set server_id to 0"); - - capture_logs (true); /* clear logs */ - ASSERT (mongoc_cursor_set_hint (cursor, 123)); - ASSERT_CMPUINT32 ((uint32_t) 123, ==, mongoc_cursor_get_hint (cursor)); - ASSERT_NO_CAPTURED_LOGS ("mongoc_cursor_set_hint"); - ASSERT (!mongoc_cursor_set_hint (cursor, 42)); - ASSERT_CAPTURED_LOG ("mongoc_cursor_set_hint", - MONGOC_LOG_LEVEL_ERROR, - "server_id already set"); - - /* last set_hint had no effect */ - ASSERT_CMPUINT32 ((uint32_t) 123, ==, mongoc_cursor_get_hint (cursor)); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static uint32_t -server_id_for_read_mode (mongoc_client_t *client, mongoc_read_mode_t read_mode) -{ - mongoc_read_prefs_t *prefs; - mongoc_server_description_t *sd; - bson_error_t error; - uint32_t server_id; - - prefs = mongoc_read_prefs_new (read_mode); - sd = - mongoc_topology_select (client->topology, MONGOC_SS_READ, prefs, &error); - - ASSERT_OR_PRINT (sd, error); - server_id = sd->id; - - mongoc_server_description_destroy (sd); - mongoc_read_prefs_destroy (prefs); - - return server_id; -} - - -static void -_test_cursor_hint (bool pooled, bool use_primary) -{ - mock_rs_t *rs; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *q = BCON_NEW ("a", BCON_INT32 (1)); - mongoc_cursor_t *cursor; - uint32_t server_id; - mongoc_query_flags_t expected_flags; - const bson_t *doc = NULL; - future_t *future; - request_t *request; - - /* wire version WIRE_VERSION_MIN, primary, two secondaries, no arbiters */ - rs = mock_rs_with_autoismaster (WIRE_VERSION_MIN, true, 2, 0); - mock_rs_run (rs); - - if (pooled) { - pool = mongoc_client_pool_new (mock_rs_get_uri (rs)); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - } - - collection = mongoc_client_get_collection (client, "test", "test"); - - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, q, NULL, NULL); - ASSERT_CMPUINT32 ((uint32_t) 0, ==, mongoc_cursor_get_hint (cursor)); - - if (use_primary) { - server_id = server_id_for_read_mode (client, MONGOC_READ_PRIMARY); - expected_flags = MONGOC_QUERY_NONE; - } else { - server_id = server_id_for_read_mode (client, MONGOC_READ_SECONDARY); - expected_flags = MONGOC_QUERY_SLAVE_OK; - } - - ASSERT (mongoc_cursor_set_hint (cursor, server_id)); - ASSERT_CMPUINT32 (server_id, ==, mongoc_cursor_get_hint (cursor)); - - future = future_cursor_next (cursor, &doc); - request = mock_rs_receives_query ( - rs, "test.test", expected_flags, 0, 0, "{'a': 1}", NULL); - - if (use_primary) { - BSON_ASSERT (mock_rs_request_is_to_primary (rs, request)); - } else { - BSON_ASSERT (mock_rs_request_is_to_secondary (rs, request)); - } - - mock_rs_replies (request, 0, 0, 0, 1, "{'b': 1}"); - BSON_ASSERT (future_get_bool (future)); - ASSERT_MATCH (doc, "{'b': 1}"); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mock_rs_destroy (rs); - bson_destroy (q); -} - -static void -test_hint_single_secondary (void) -{ - _test_cursor_hint (false, false); -} - -static void -test_hint_single_primary (void) -{ - _test_cursor_hint (false, true); -} - -static void -test_hint_pooled_secondary (void) -{ - _test_cursor_hint (true, false); -} - -static void -test_hint_pooled_primary (void) -{ - _test_cursor_hint (true, true); -} - -mongoc_read_mode_t modes[] = { - MONGOC_READ_PRIMARY, - MONGOC_READ_PRIMARY_PREFERRED, - MONGOC_READ_SECONDARY, - MONGOC_READ_SECONDARY_PREFERRED, - MONGOC_READ_NEAREST, -}; - -mongoc_query_flags_t expected_flag[] = { - MONGOC_QUERY_NONE, - MONGOC_QUERY_SLAVE_OK, - MONGOC_QUERY_SLAVE_OK, - MONGOC_QUERY_SLAVE_OK, - MONGOC_QUERY_SLAVE_OK, -}; - -/* test that mongoc_cursor_set_hint sets slaveok for mongos only if read pref - * is secondaryPreferred. */ -static void -test_cursor_hint_mongos (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - size_t i; - mongoc_read_prefs_t *prefs; - mongoc_cursor_t *cursor; - const bson_t *doc = NULL; - future_t *future; - request_t *request; - - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "test", "test"); - - for (i = 0; i < sizeof (modes) / sizeof (mongoc_read_mode_t); i++) { - prefs = mongoc_read_prefs_new (modes[i]); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, tmp_bson (NULL), NULL, prefs); - - ASSERT_CMPUINT32 ((uint32_t) 0, ==, mongoc_cursor_get_hint (cursor)); - ASSERT (mongoc_cursor_set_hint (cursor, 1)); - ASSERT_CMPUINT32 ((uint32_t) 1, ==, mongoc_cursor_get_hint (cursor)); - - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_query ( - server, "test.test", expected_flag[i], 0, 0, "{}", NULL); - - mock_server_replies_simple (request, "{}"); - BSON_ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_read_prefs_destroy (prefs); - } - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_cursor_hint_mongos_cmd (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - size_t i; - mongoc_read_prefs_t *prefs; - const bson_t *doc = NULL; - future_t *future; - request_t *request; - - server = mock_mongos_new (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "test", "test"); - - for (i = 0; i < sizeof (modes) / sizeof (mongoc_read_mode_t); i++) { - prefs = mongoc_read_prefs_new (modes[i]); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, tmp_bson (NULL), NULL, prefs); - - ASSERT_CMPUINT32 ((uint32_t) 0, ==, mongoc_cursor_get_hint (cursor)); - ASSERT (mongoc_cursor_set_hint (cursor, 1)); - ASSERT_CMPUINT32 ((uint32_t) 1, ==, mongoc_cursor_get_hint (cursor)); - - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_command ( - server, "test", expected_flag[i], 0, 0, "{'find': 'test'}", NULL); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'test.test'," - " 'firstBatch': [{}]}}"); - - BSON_ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_read_prefs_destroy (prefs); - } - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -/* Tests CDRIVER-562: after calling ismaster to handshake a new connection we - * must update topology description with the server response. If not, this test - * fails under auth with "auth failed" because we use the wrong auth protocol. - */ -static void -_test_cursor_hint_no_warmup (bool pooled) -{ - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t *q = tmp_bson (NULL); - mongoc_cursor_t *cursor; - const bson_t *doc = NULL; - bson_error_t error; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - collection = get_test_collection (client, "test_cursor_hint_no_warmup"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, q, NULL, NULL); - - /* no chance for topology scan, no server selection */ - ASSERT (mongoc_cursor_set_hint (cursor, 1)); - ASSERT_CMPUINT32 (1, ==, mongoc_cursor_get_hint (cursor)); - - mongoc_cursor_next (cursor, &doc); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - -static void -test_hint_no_warmup_single (void) -{ - _test_cursor_hint_no_warmup (false); -} - -static void -test_hint_no_warmup_pooled (void) -{ - _test_cursor_hint_no_warmup (true); -} - - -static void -test_tailable_alive (void) -{ - mongoc_client_t *client; - mongoc_database_t *database; - char *collection_name; - mongoc_collection_t *collection; - bool r; - bson_error_t error; - mongoc_cursor_t *cursor; - const bson_t *doc; - - client = test_framework_client_new (); - database = mongoc_client_get_database (client, "test"); - collection_name = gen_collection_name ("test"); - - collection = mongoc_database_get_collection (database, collection_name); - mongoc_collection_drop (collection, NULL); - mongoc_collection_destroy (collection); - - collection = mongoc_database_create_collection ( - database, - collection_name, - tmp_bson ("{'capped': true, 'size': 10000}"), - &error); - - ASSERT_OR_PRINT (collection, error); - - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - - /* test mongoc_collection_find and mongoc_collection_find_with_opts */ - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_TAILABLE_CURSOR | - MONGOC_QUERY_AWAIT_DATA, - 0, - 0, - 0, - tmp_bson (NULL), - NULL, - NULL); - - ASSERT (mongoc_cursor_more (cursor)); - ASSERT (mongoc_cursor_next (cursor, &doc)); - - /* still alive */ - ASSERT (mongoc_cursor_more (cursor)); - - /* no next document, but still alive and could return more in the future - * see CDRIVER-1530 */ - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_more (cursor)); - - mongoc_cursor_destroy (cursor); - - cursor = mongoc_collection_find_with_opts ( - collection, - tmp_bson (NULL), - tmp_bson ("{'tailable': true, 'awaitData': true}"), - NULL); - - ASSERT (mongoc_cursor_more (cursor)); - ASSERT (mongoc_cursor_next (cursor, &doc)); - - /* still alive */ - ASSERT (mongoc_cursor_more (cursor)); - - mongoc_cursor_destroy (cursor); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - bson_free (collection_name); - mongoc_client_destroy (client); -} - - -typedef struct { - int64_t skip; - int64_t limit; - int64_t batch_size; - int64_t expected_n_return[3]; - int64_t reply_length[3]; -} cursor_n_return_test; - - -static void -_make_reply_batch (bson_string_t *reply, - uint32_t n_docs, - bool first_batch, - bool finished) -{ - uint32_t j; - - bson_string_append_printf (reply, - "{'ok': 1, 'cursor': {" - " 'id': %d," - " 'ns': 'db.coll',", - finished ? 0 : 123); - - if (first_batch) { - bson_string_append (reply, "'firstBatch': [{}"); - } else { - bson_string_append (reply, "'nextBatch': [{}"); - } - - for (j = 1; j < n_docs; j++) { - bson_string_append (reply, ", {}"); - } - - bson_string_append (reply, "]}}"); -} - - -static void -_test_cursor_n_return_find_cmd (mongoc_cursor_t *cursor, - mock_server_t *server, - cursor_n_return_test *test) -{ - bson_t find_cmd = BSON_INITIALIZER; - bson_t getmore_cmd = BSON_INITIALIZER; - const bson_t *doc; - request_t *request; - future_t *future; - int j; - int reply_no; - bson_string_t *reply; - bool cursor_finished; - - BSON_APPEND_UTF8 (&find_cmd, "find", "coll"); - if (test->skip) { - BSON_APPEND_INT64 (&find_cmd, "skip", test->skip); - } - if (test->limit > 0) { - BSON_APPEND_INT64 (&find_cmd, "limit", test->limit); - } else if (test->limit < 0) { - BSON_APPEND_INT64 (&find_cmd, "limit", -test->limit); - BSON_APPEND_BOOL (&find_cmd, "singleBatch", true); - } - - if (test->batch_size) { - BSON_APPEND_INT64 (&find_cmd, "batchSize", BSON_ABS (test->batch_size)); - } - - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, NULL); - - ASSERT (match_bson (request_get_doc (request, 0), &find_cmd, true)); - - reply = bson_string_new (NULL); - _make_reply_batch (reply, (uint32_t) test->reply_length[0], true, false); - mock_server_replies_simple (request, reply->str); - bson_string_free (reply, true); - - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - - /* advance to the end of the batch */ - for (j = 1; j < test->reply_length[0]; j++) { - ASSERT (mongoc_cursor_next (cursor, &doc)); - } - - for (reply_no = 1; reply_no < 3; reply_no++) { - /* expect getMore command, send reply_length[reply_no] docs to client */ - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, NULL); - - bson_reinit (&getmore_cmd); - BSON_APPEND_INT64 (&getmore_cmd, "getMore", 123); - if (test->expected_n_return[reply_no] && test->batch_size) { - BSON_APPEND_INT64 (&getmore_cmd, - "batchSize", - BSON_ABS (test->expected_n_return[reply_no])); - } else { - BSON_APPEND_DOCUMENT ( - &getmore_cmd, "batchSize", tmp_bson ("{'$exists': false}")); - } - - ASSERT (match_bson (request_get_doc (request, 0), &getmore_cmd, true)); - - reply = bson_string_new (NULL); - cursor_finished = (reply_no == 2); - _make_reply_batch (reply, - (uint32_t) test->reply_length[reply_no], - false, - cursor_finished); - - mock_server_replies_simple (request, reply->str); - bson_string_free (reply, true); - - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - - /* advance to the end of the batch */ - for (j = 1; j < test->reply_length[reply_no]; j++) { - ASSERT (mongoc_cursor_next (cursor, &doc)); - } - } - - bson_destroy (&find_cmd); - bson_destroy (&getmore_cmd); -} - - -static void -_test_cursor_n_return (bool find_with_opts) -{ - cursor_n_return_test tests[] = {{ - 0, /* skip */ - 0, /* limit */ - 0, /* batch_size */ - {0, 0, 0}, /* expected_n_return */ - {1, 1, 1} /* reply_length */ - }, - { - 7, /* skip */ - 0, /* limit */ - 0, /* batch_size */ - {0, 0, 0}, /* expected_n_return */ - {1, 1, 1} /* reply_length */ - }, - { - 0, /* skip */ - 3, /* limit */ - 0, /* batch_size */ - {3, 2, 1}, /* expected_n_return */ - {1, 1, 1} /* reply_length */ - }, - { - 0, /* skip */ - 5, /* limit */ - 2, /* batch_size */ - {2, 2, 1}, /* expected_n_return */ - {2, 2, 1} /* reply_length */ - }, - { - 0, /* skip */ - 4, /* limit */ - 7, /* batch_size */ - {4, 2, 1}, /* expected_n_return */ - {2, 1, 1} /* reply_length */ - }, - { - 0, /* skip */ - -3, /* limit */ - 1, /* batch_size */ - {-3, -3, -3}, /* expected_n_return */ - {1, 1, 1} /* reply_length */ - }}; - - cursor_n_return_test *test; - size_t i; - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_cursor_t *cursor; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "coll"); - - for (i = 0; i < sizeof (tests) / sizeof (cursor_n_return_test); i++) { - test = &tests[i]; - - if (find_with_opts) { - bson_reinit (&opts); - - if (test->skip) { - BSON_APPEND_INT64 (&opts, "skip", test->skip); - } - - if (test->limit > 0) { - BSON_APPEND_INT64 (&opts, "limit", test->limit); - } else if (test->limit < 0) { - BSON_APPEND_INT64 (&opts, "limit", -test->limit); - BSON_APPEND_BOOL (&opts, "singleBatch", true); - } - - if (test->batch_size) { - BSON_APPEND_INT64 (&opts, "batchSize", test->batch_size); - } - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (NULL), &opts, NULL); - } else { - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - (uint32_t) test->skip, - (uint32_t) test->limit, - (uint32_t) test->batch_size, - tmp_bson (NULL), - NULL, - NULL); - } - - _test_cursor_n_return_find_cmd (cursor, server, test); - - mongoc_cursor_destroy (cursor); - } - - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_n_return_find_cmd (void) -{ - _test_cursor_n_return (false); -} - - -static void -test_n_return_find_cmd_with_opts (void) -{ - _test_cursor_n_return (true); -} - - -/* mongos can return empty final batch with limit and batchSize, which had - * caused an abort in the cursor */ -static void -test_empty_final_batch_live (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - int i; - bool r; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - collection = get_test_collection (client, "test_empty_final_batch_live"); - - mongoc_collection_delete_many ( - collection, tmp_bson ("{}"), NULL, NULL, NULL); - for (i = 0; i < 3; i++) { - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - } - - cursor = mongoc_collection_find_with_opts ( - collection, - tmp_bson ("{}"), - tmp_bson ("{'limit': 3, 'batchSize': 3}"), - NULL); - - for (i = 0; i < 3; i++) { - ASSERT (mongoc_cursor_next (cursor, &doc)); - } - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_empty_final_batch (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "coll"); - cursor = mongoc_collection_find_with_opts ( - collection, - tmp_bson ("{}"), - tmp_bson ("{'limit': 1, 'batchSize': 1}"), - NULL); - - /* - * one document in first batch - */ - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, NULL); - - mock_server_replies_to_find ( - request, MONGOC_QUERY_SLAVE_OK, 1234, 0, "db.coll", "{}", true); - - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - - /* - * empty batch with nonzero cursor id - */ - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, NULL); - - mock_server_replies_to_find ( - request, MONGOC_QUERY_SLAVE_OK, 1234, 0, "db.coll", "" /* empty */, true); - - ASSERT (!future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - future_destroy (future); - request_destroy (request); - - /* - * final batch, empty with zero cursor id - */ - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, NULL); - - ASSERT_CMPINT64 ( - bson_lookup_int64 (request_get_doc (request, 0), "batchSize"), - ==, - (int64_t) 1); - - mock_server_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK, - 0 /* cursor id */, - 0, - "db.coll", - "" /* empty */, - true); - - ASSERT (!future_get_bool (future)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_error_document_query (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - const bson_t *error_doc; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - collection = get_test_collection (client, "test_error_document_query"); - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{'x': {'$badOperator': 1}}"), NULL, NULL); - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_error_document (cursor, &error, &error_doc)); - ASSERT_CMPUINT32 (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CONTAINS (error.message, "$badOperator"); - ASSERT_CMPINT32 ( - bson_lookup_int32 (error_doc, "code"), ==, (int32_t) error.code); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_error_document_command (void) -{ - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - const bson_t *error_doc; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - cursor = mongoc_client_command (client, - "test", - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{'foo': 1}"), /* no such cmd */ - NULL, - NULL); - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_error_document (cursor, &error, &error_doc)); - ASSERT_CMPUINT32 (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CONTAINS (error.message, "no such"); - - ASSERT_CMPINT32 ( - bson_lookup_int32 (error_doc, "code"), ==, (int32_t) error.code); - - mongoc_cursor_destroy (cursor); - mongoc_client_destroy (client); -} - - -static void -test_error_document_getmore (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - int i; - bool r; - bson_error_t error; - mongoc_cursor_t *cursor; - const bson_t *doc; - const bson_t *error_doc; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - collection = get_test_collection (client, "test_error_document_getmore"); - mongoc_collection_drop (collection, NULL); - - for (i = 0; i < 10; i++) { - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{'i': %d}", i), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - } - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), tmp_bson ("{'batchSize': 2}"), NULL); - - ASSERT (mongoc_cursor_next (cursor, &doc)); - - mongoc_collection_drop (collection, NULL); - - ASSERT (mongoc_cursor_next (cursor, &doc)); - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_error_document (cursor, &error, &error_doc)); - - /* results vary by server version */ - if (error.domain == MONGOC_ERROR_CURSOR) { - /* MongoDB 3.0 and older */ - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "cursor is invalid"); - } else { - /* MongoDB 3.2+ */ - ASSERT_CMPUINT32 (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CMPINT32 ( - bson_lookup_int32 (error_doc, "code"), ==, (int32_t) error.code); - } - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -/* test that an error during constructing a find cursor causes the cursor to - * be marked as failed, so mongoc_cursor_is_alive and mongoc_cursor_more return - * false */ -static void -test_find_error_is_alive (void) -{ - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_cursor_t *cursor; - bson_error_t err; - const bson_t *bson; - client = test_framework_client_new (); - coll = mongoc_client_get_collection (client, "test", "test"); - cursor = - mongoc_collection_find (coll, - MONGOC_QUERY_NONE, - 0, - 0, - 0, - tmp_bson ("{'$query': {}, 'non_dollar': {}}"), - NULL, - NULL); - BSON_ASSERT (mongoc_cursor_error (cursor, &err)); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot mix $query with non-dollar field"); - BSON_ASSERT (!mongoc_cursor_is_alive (cursor)); - BSON_ASSERT (!mongoc_cursor_more (cursor)); - BSON_ASSERT (!mongoc_cursor_next (cursor, &bson)); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - - -void -test_cursor_install (TestSuite *suite) -{ - test_common_cursor_functions_install (suite); - TestSuite_AddLive (suite, "/Cursor/limit", test_limit); - TestSuite_AddLive (suite, - "" - "/Cursor/kill/live", - test_kill_cursor_live); - TestSuite_AddMockServerTest ( - suite, "/Cursor/kill/single", test_kill_cursors_single); - TestSuite_AddMockServerTest ( - suite, "/Cursor/kill/pooled", test_kill_cursors_pooled); - TestSuite_AddMockServerTest ( - suite, "/Cursor/kill/single/cmd", test_kill_cursors_single_cmd); - TestSuite_AddMockServerTest ( - suite, "/Cursor/kill/pooled/cmd", test_kill_cursors_pooled_cmd); - TestSuite_AddMockServerTest (suite, - "/Cursor/client_kill_cursor/with_primary", - test_client_kill_cursor_with_primary); - TestSuite_AddMockServerTest (suite, - "/Cursor/client_kill_cursor/without_primary", - test_client_kill_cursor_without_primary); - TestSuite_AddMockServerTest ( - suite, - "/Cursor/client_kill_cursor/with_primary/wv4", - test_client_kill_cursor_with_primary_wire_version_4); - TestSuite_AddMockServerTest ( - suite, - "/Cursor/client_kill_cursor/without_primary/wv4", - test_client_kill_cursor_without_primary_wire_version_4); - 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, - test_framework_skip_if_max_wire_version_less_than_4); - TestSuite_AddFull (suite, - "/Cursor/new_from_find_batches", - test_cursor_new_from_find_batches, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_4); - 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); - TestSuite_AddMockServerTest ( - suite, "/Cursor/new_ignores_fields", test_cursor_new_ignores_fields); - TestSuite_AddLive ( - suite, "/Cursor/new_invalid_filter", test_cursor_new_invalid_filter); - TestSuite_AddLive ( - suite, "/Cursor/new_invalid_opts", test_cursor_new_invalid_opts); - TestSuite_AddLive (suite, "/Cursor/new_static", test_cursor_new_static); - TestSuite_AddLive (suite, "/Cursor/hint/errors", test_cursor_hint_errors); - TestSuite_AddMockServerTest ( - suite, "/Cursor/hint/single/secondary", test_hint_single_secondary); - TestSuite_AddMockServerTest ( - suite, "/Cursor/hint/single/primary", test_hint_single_primary); - TestSuite_AddMockServerTest ( - suite, "/Cursor/hint/pooled/secondary", test_hint_pooled_secondary); - TestSuite_AddMockServerTest ( - suite, "/Cursor/hint/pooled/primary", test_hint_pooled_primary); - TestSuite_AddMockServerTest ( - suite, "/Cursor/hint/mongos", test_cursor_hint_mongos); - TestSuite_AddMockServerTest ( - suite, "/Cursor/hint/mongos/cmd", test_cursor_hint_mongos_cmd); - TestSuite_AddLive ( - suite, "/Cursor/hint/no_warmup/single", test_hint_no_warmup_single); - TestSuite_AddLive ( - suite, "/Cursor/hint/no_warmup/pooled", test_hint_no_warmup_pooled); - TestSuite_AddLive (suite, "/Cursor/tailable/alive", test_tailable_alive); - TestSuite_AddMockServerTest ( - suite, "/Cursor/n_return/find_cmd", test_n_return_find_cmd); - TestSuite_AddMockServerTest (suite, - "/Cursor/n_return/find_cmd/with_opts", - test_n_return_find_cmd_with_opts); - TestSuite_AddLive ( - suite, "/Cursor/empty_final_batch_live", test_empty_final_batch_live); - TestSuite_AddMockServerTest ( - suite, "/Cursor/empty_final_batch", test_empty_final_batch); - TestSuite_AddLive ( - suite, "/Cursor/error_document/query", test_error_document_query); - TestSuite_AddLive ( - suite, "/Cursor/error_document/getmore", test_error_document_getmore); - TestSuite_AddLive ( - suite, "/Cursor/error_document/command", test_error_document_command); - TestSuite_AddLive ( - suite, "/Cursor/find_error/is_alive", test_find_error_is_alive); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-cyrus.c b/lib/mongoc/libmongoc/tests/test-mongoc-cyrus.c deleted file mode 100644 index e8e139181fbadebbf8ad38bad2fc7d87eb4df174..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-cyrus.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2015 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 <mongoc/mongoc.h> -#include <mongoc/mongoc-cyrus-private.h> -#include <mongoc/mongoc-client-private.h> - -#include "TestSuite.h" -#include "test-libmongoc.h" - - -static void -test_sasl_properties (void) -{ - mongoc_uri_t *uri; - mongoc_cyrus_t sasl; - - uri = mongoc_uri_new ( - "mongodb://user@host/?authMechanism=GSSAPI&" - "authMechanismProperties=SERVICE_NAME:sn,CANONICALIZE_HOST_NAME:TrUe"); - - BSON_ASSERT (uri); - memset (&sasl, 0, sizeof sasl); - _mongoc_sasl_set_properties ((mongoc_sasl_t *) &sasl, uri); - - ASSERT (sasl.credentials.canonicalize_host_name); - ASSERT_CMPSTR (sasl.credentials.service_name, "sn"); - - mongoc_uri_destroy (uri); - - capture_logs (true); - /* authMechanismProperties take precedence */ - uri = mongoc_uri_new ( - "mongodb://user@host/?authMechanism=GSSAPI&" - "canonicalizeHostname=true&gssapiServiceName=blah&" - "authMechanismProperties=SERVICE_NAME:sn,CANONICALIZE_HOST_NAME:False"); - - ASSERT_CAPTURED_LOG ( - "authMechanismProperties should overwrite gssapiServiceName", - MONGOC_LOG_LEVEL_WARNING, - "Overwriting previously provided value for 'authmechanismproperties'"); - - _mongoc_cyrus_destroy (&sasl); - memset (&sasl, 0, sizeof sasl); - _mongoc_sasl_set_properties ((mongoc_sasl_t *) &sasl, uri); - - ASSERT (!sasl.credentials.canonicalize_host_name); - ASSERT_CMPSTR (sasl.credentials.service_name, "sn"); - - _mongoc_cyrus_destroy (&sasl); - mongoc_uri_destroy (uri); -} - - -static void -test_sasl_canonicalize_hostname (void *ctx) -{ - mongoc_client_t *client; - mongoc_server_stream_t *ss; - char real_name[BSON_HOST_NAME_MAX + 1] = {'\0'}; - bson_error_t error; - - client = test_framework_client_new (); - ss = mongoc_cluster_stream_for_reads ( - &client->cluster, NULL, NULL, NULL, &error); - ASSERT_OR_PRINT (ss, error); - - BSON_ASSERT (_mongoc_sasl_get_canonicalized_name ( - ss->stream, real_name, sizeof real_name)); - - ASSERT_CMPSIZE_T (strlen (real_name), >, (size_t) 0); - - mongoc_server_stream_cleanup (ss); - mongoc_client_destroy (client); -} - - -void -test_cyrus_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/SASL/properties", test_sasl_properties); - TestSuite_AddFull (suite, - "/SASL/canonicalize", - test_sasl_canonicalize_hostname, - NULL, - NULL, - TestSuite_CheckLive, - test_framework_skip_if_offline); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-database.c b/lib/mongoc/libmongoc/tests/test-mongoc-database.c deleted file mode 100644 index 61bcf479d0f4d72871cd5f23178396eed21b4be4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-database.c +++ /dev/null @@ -1,1270 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-collection-private.h> -#include <mongoc/mongoc-write-concern-private.h> -#include <mongoc/mongoc-read-concern-private.h> -#include <mongoc/mongoc-util-private.h> - -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-database-private.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" -#include "test-conveniences.h" - - -static void -test_aggregate_write_concern (void) -{ - mongoc_database_t *database; - mock_server_t *server; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_t *with_out_key; - bson_t *no_out_key; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - - /* The newest wire version that is still too old to - support aggregate with writeConcern and $out/$merge */ - server = mock_server_with_autoismaster (WIRE_VERSION_READ_CONCERN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - database = mongoc_client_get_database (client, "agg"); - - /* If we run an aggregate without a terminal stage, - then it should be ok for us to have a write concern, - even with an old wire version. */ - no_out_key = BCON_NEW ( - "pipeline", "[", "{", "$match", "{", "fakeField", "A", "}", "}", "]"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_wmajority (wc, 100); - mongoc_write_concern_append (wc, &opts); - cursor = mongoc_database_aggregate (database, no_out_key, &opts, NULL); - ASSERT_ERROR_CONTAINS (cursor->error, 0, 0, ""); - mongoc_cursor_destroy (cursor); - - /* If we run an aggregate with a terminal stage and - a write concern, it should not be allowed. */ - with_out_key = BCON_NEW ("pipeline", - "[", - "{", - "$currentOp", - "{", - "}", - "}", - "{", - "$out", - BCON_UTF8 ("ops"), - "}", - "]"); - - cursor = mongoc_database_aggregate (database, with_out_key, &opts, NULL); - - ASSERT_ERROR_CONTAINS (cursor->error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "does not support writeConcern with wire version"); - - - bson_destroy (&opts); - bson_destroy (with_out_key); - bson_destroy (no_out_key); - mongoc_write_concern_destroy (wc); - mongoc_cursor_destroy (cursor); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_aggregate_inherit_database (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - mongoc_database_t *database; - const bson_t *doc; - request_t *request; - future_t *future; - bson_t *pipeline; - bson_t opts = BSON_INITIALIZER; - mongoc_read_concern_t *rc2; - mongoc_read_concern_t *rc; - mongoc_write_concern_t *wc2; - mongoc_write_concern_t *wc; - - server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - database = mongoc_client_get_database (client, "admin"); - - pipeline = BCON_NEW ("pipeline", - "[", - "{", - "$currentOp", - "{", - "}", - "}", - "{", - "$out", - BCON_UTF8 ("ops"), - "}", - "]"); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_read_concern_append (rc, &opts); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_write_concern_append (wc, &opts); - - /* Uses the opts */ - cursor = mongoc_database_aggregate (database, pipeline, &opts, NULL); - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate' : 1," - " 'pipeline' : [ { '$currentOp': { } }, { '$out' : 'ops' } ]," - " 'cursor' : { }," - " '$db' : 'admin'," - " '$readPreference' : { '$exists': false }," - " 'readConcern' : { 'level' : 'majority' }," - " 'writeConcern' : { 'w' : 2 } }")); - - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (!future_get_bool (future)); - - /* Set database level defaults */ - wc2 = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc2, 3); - mongoc_database_set_write_concern (database, wc2); - rc2 = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc2, MONGOC_READ_CONCERN_LEVEL_LOCAL); - mongoc_database_set_read_concern (database, rc2); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - - /* Inherits from database */ - cursor = mongoc_database_aggregate (database, pipeline, NULL, NULL); - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate' : 1," - " 'pipeline' : [ { '$currentOp': { } }, { '$out' : 'ops' } ]," - " 'cursor' : { }," - " '$db' : 'admin'," - " '$readPreference' : { '$exists': false }," - " 'readConcern' : { 'level' : 'local' }," - " 'writeConcern' : { 'w' : 3 } }")); - - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (!future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - - /* Uses the opts, not default database level */ - cursor = mongoc_database_aggregate (database, pipeline, &opts, NULL); - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate' : 1," - " 'pipeline' : [ { '$currentOp': { } }, { '$out' : 'ops' } ]," - " 'cursor' : { }," - " '$db' : 'admin'," - " '$readPreference' : { '$exists': false }," - " 'readConcern' : { 'level' : 'majority' }," - " 'writeConcern' : { 'w' : 2 } }")); - - mock_server_replies_simple (request, "{'ok': 1}"); - - ASSERT (!future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - - /* Doesn't inherit write concern when not using $out */ - bson_destroy (pipeline); - pipeline = BCON_NEW ("pipeline", "[", "{", "$currentOp", "{", "}", "}", "]"); - - cursor = mongoc_database_aggregate (database, pipeline, NULL, NULL); - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_msg ( - server, - MONGOC_QUERY_NONE, - tmp_bson ("{ 'aggregate' : 1," - " 'pipeline' : [ { '$currentOp': { } } ]," - " 'cursor' : { }," - " '$db' : 'admin'," - " '$readPreference' : { '$exists': false }," - " 'readConcern' : { 'level' : 'local' }," - " 'writeConcern' : { '$exists' : false } }")); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT (!future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - - bson_destroy (&opts); - bson_destroy (pipeline); - mongoc_read_concern_destroy (rc); - mongoc_read_concern_destroy (rc2); - mongoc_write_concern_destroy (wc); - mongoc_write_concern_destroy (wc2); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_create_with_write_concern (void *ctx) -{ - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error = {0}; - mongoc_write_concern_t *bad_wc; - mongoc_write_concern_t *good_wc; - bool wire_version_5; - bson_t *opts = NULL; - char *dbname; - char *name; - - capture_logs (true); - opts = bson_new (); - - client = test_framework_client_new (); - BSON_ASSERT (client); - mongoc_client_set_error_api (client, 2); - - bad_wc = mongoc_write_concern_new (); - good_wc = mongoc_write_concern_new (); - - wire_version_5 = test_framework_max_wire_version_at_least (5); - - dbname = gen_collection_name ("dbtest"); - database = mongoc_client_get_database (client, dbname); - BSON_ASSERT (database); - - name = gen_collection_name ("create_collection"); - - /* writeConcern that will not pass mongoc_write_concern_is_valid */ - bad_wc->wtimeout = -10; - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - collection = - mongoc_database_create_collection (database, name, opts, &error); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - ASSERT (!collection); - bad_wc->wtimeout = 0; - error.code = 0; - error.domain = 0; - - /* valid writeConcern on all configs */ - mongoc_write_concern_set_w (good_wc, 1); - bson_reinit (opts); - mongoc_write_concern_append (good_wc, opts); - collection = - mongoc_database_create_collection (database, name, opts, &error); - ASSERT_OR_PRINT (collection, error); - ASSERT (!error.code); - ASSERT (!error.domain); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - mongoc_collection_destroy (collection); - - /* writeConcern that results in writeConcernError */ - bad_wc->wtimeout = 0; - mongoc_write_concern_set_w (bad_wc, 99); - if (!test_framework_is_mongos ()) { /* skip if sharded */ - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - collection = - mongoc_database_create_collection (database, name, opts, &error); - - if (wire_version_5) { - ASSERT (!collection); - if (test_framework_is_replset ()) { /* replica set */ - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:"); - } else { /* standalone */ - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CMPINT (error.code, ==, 2); - } - } else { /* if wire_version <= 4, no error */ - ASSERT_OR_PRINT (collection, error); - ASSERT (!error.code); - ASSERT (!error.domain); - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - mongoc_collection_destroy (collection); - } - } - - mongoc_database_destroy (database); - bson_free (name); - bson_free (dbname); - bson_destroy (opts); - mongoc_write_concern_destroy (good_wc); - mongoc_write_concern_destroy (bad_wc); - mongoc_client_destroy (client); -} - - -static void -test_copy (void) -{ - mongoc_database_t *database; - mongoc_database_t *copy; - mongoc_client_t *client; - - client = test_framework_client_new (); - ASSERT (client); - - database = mongoc_client_get_database (client, "test"); - ASSERT (database); - - copy = mongoc_database_copy (database); - ASSERT (copy); - ASSERT (copy->client == database->client); - ASSERT (strcmp (copy->name, database->name) == 0); - - mongoc_database_destroy (copy); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_has_collection (void) -{ - mongoc_collection_t *collection; - mongoc_database_t *database; - mongoc_client_t *client; - bson_error_t error; - char *name; - bool r; - bson_oid_t oid; - bson_t b; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - name = gen_collection_name ("has_collection"); - collection = mongoc_client_get_collection (client, "test", name); - BSON_ASSERT (collection); - - database = mongoc_client_get_database (client, "test"); - BSON_ASSERT (database); - - bson_init (&b); - bson_oid_init (&oid, NULL); - bson_append_oid (&b, "_id", 3, &oid); - bson_append_utf8 (&b, "hello", 5, "world", 5); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, &b, NULL, NULL, &error), error); - bson_destroy (&b); - - r = mongoc_database_has_collection (database, name, &error); - BSON_ASSERT (!error.domain); - BSON_ASSERT (r); - - bson_free (name); - mongoc_database_destroy (database); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_command (void) -{ - mongoc_database_t *database; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - bool r; - bson_t cmd = BSON_INITIALIZER; - bson_t reply; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - database = mongoc_client_get_database (client, "admin"); - - /* - * Test a known working command, "ping". - */ - bson_append_int32 (&cmd, "ping", 4, 1); - - cursor = mongoc_database_command ( - database, MONGOC_QUERY_NONE, 0, 1, 0, &cmd, NULL, NULL); - BSON_ASSERT (cursor); - - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (r); - BSON_ASSERT (doc); - - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (!r); - BSON_ASSERT (!doc); - - mongoc_cursor_destroy (cursor); - - - /* - * Test a non-existing command to ensure we get the failure. - */ - bson_reinit (&cmd); - bson_append_int32 (&cmd, "a_non_existing_command", -1, 1); - - r = mongoc_database_command_simple (database, &cmd, NULL, &reply, &error); - BSON_ASSERT (!r); - BSON_ASSERT (error.domain == MONGOC_ERROR_QUERY); - BSON_ASSERT (error.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND); - BSON_ASSERT (strstr (error.message, "a_non_existing_command")); - - bson_destroy (&reply); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - bson_destroy (&cmd); -} - - -static void -_test_db_command_read_prefs (bool simple, bool pooled) -{ - mock_server_t *server; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_read_prefs_t *secondary_pref; - bson_t *cmd; - future_t *future; - bson_error_t error; - request_t *request; - mongoc_cursor_t *cursor; - const bson_t *reply; - - /* mock mongos: easiest way to test that read preference is configured */ - server = mock_mongos_new (WIRE_VERSION_MIN); - mock_server_run (server); - - if (pooled) { - pool = mongoc_client_pool_new (mock_server_get_uri (server)); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - } - - db = mongoc_client_get_database (client, "db"); - secondary_pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_database_set_read_prefs (db, secondary_pref); - cmd = tmp_bson ("{'foo': 1}"); - - if (simple) { - /* simple, without read preference */ - future = future_database_command_simple (db, cmd, NULL, NULL, &error); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, "{'foo': 1}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - request_destroy (request); - - /* with read preference */ - future = - future_database_command_simple (db, cmd, secondary_pref, NULL, &error); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'foo': 1}," - " '$readPreference': {'mode': 'secondary'}}"); - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - request_destroy (request); - } else { - /* not simple, no read preference */ - cursor = mongoc_database_command ( - db, MONGOC_QUERY_NONE, 0, 0, 0, cmd, NULL, NULL); - future = future_cursor_next (cursor, &reply); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, "{'foo': 1}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - - /* with read preference */ - cursor = mongoc_database_command ( - db, MONGOC_QUERY_NONE, 0, 0, 0, cmd, NULL, secondary_pref); - future = future_cursor_next (cursor, &reply); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'foo': 1}," - " '$readPreference': {'mode': 'secondary'}}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - } - - mongoc_database_destroy (db); - mongoc_read_prefs_destroy (secondary_pref); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mock_server_destroy (server); -} - - -static void -test_db_command_simple_read_prefs_single (void) -{ - _test_db_command_read_prefs (true, false); -} - - -static void -test_db_command_simple_read_prefs_pooled (void) -{ - _test_db_command_read_prefs (true, true); -} - - -static void -test_db_command_read_prefs_single (void) -{ - _test_db_command_read_prefs (false, false); -} - - -static void -test_db_command_read_prefs_pooled (void) -{ - _test_db_command_read_prefs (false, true); -} - - -static void -test_drop (void) -{ - mongoc_client_t *client; - mongoc_database_t *database; - mongoc_collection_t *collection; - bson_error_t error = {0}; - bson_t *opts = NULL; - char *dbname; - mongoc_write_concern_t *good_wc; - mongoc_write_concern_t *bad_wc; - bool wire_version_5; - bool r; - - opts = bson_new (); - client = test_framework_client_new (); - BSON_ASSERT (client); - mongoc_client_set_error_api (client, 2); - - bad_wc = mongoc_write_concern_new (); - good_wc = mongoc_write_concern_new (); - wire_version_5 = test_framework_max_wire_version_at_least (5); - - dbname = gen_collection_name ("db_drop_test"); - database = mongoc_client_get_database (client, dbname); - - /* MongoDB 3.2+ must create at least one replicated database before - * dropDatabase will check writeConcern, see SERVER-25601 */ - collection = mongoc_database_get_collection (database, "collection"); - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - - ASSERT_OR_PRINT (mongoc_database_drop (database, &error), error); - BSON_ASSERT (!error.domain); - BSON_ASSERT (!error.code); - - mongoc_database_destroy (database); - - if (wire_version_5) { - /* invalid writeConcern */ - bad_wc->wtimeout = -10; - database = mongoc_client_get_database (client, dbname); - - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - ASSERT (!mongoc_database_drop_with_opts (database, opts, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - bad_wc->wtimeout = 0; - error.code = 0; - error.domain = 0; - - /* valid writeConcern */ - mongoc_write_concern_set_w (good_wc, 1); - - bson_reinit (opts); - mongoc_write_concern_append (good_wc, opts); - ASSERT_OR_PRINT (mongoc_database_drop_with_opts (database, opts, &error), - error); - BSON_ASSERT (!error.code); - BSON_ASSERT (!error.domain); - - /* invalid writeConcern */ - mongoc_write_concern_set_w (bad_wc, 99); - mongoc_database_destroy (database); - - if (!test_framework_is_mongos ()) { /* skip if sharded */ - database = mongoc_client_get_database (client, dbname); - bson_reinit (opts); - mongoc_write_concern_append_bad (bad_wc, opts); - r = mongoc_database_drop_with_opts (database, opts, &error); - ASSERT (!r); - if (test_framework_is_replset ()) { - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:"); - } else { /* standalone */ - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER); - ASSERT_CMPINT (error.code, ==, 2); - } - mongoc_database_destroy (database); - } - } /* wire_version_5 */ - - bson_free (dbname); - bson_destroy (opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_write_concern_destroy (good_wc); - mongoc_write_concern_destroy (bad_wc); -} - - -static void -test_create_collection (void) -{ - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error = {0}; - bson_t options; - bson_t storage_opts; - bson_t wt_opts; - - char *dbname; - char *name; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - dbname = gen_collection_name ("dbtest"); - database = mongoc_client_get_database (client, dbname); - BSON_ASSERT (database); - bson_free (dbname); - - bson_init (&options); - BSON_APPEND_INT32 (&options, "size", 1234); - BSON_APPEND_INT32 (&options, "max", 4567); - BSON_APPEND_BOOL (&options, "capped", true); - - BSON_APPEND_DOCUMENT_BEGIN (&options, "storageEngine", &storage_opts); - BSON_APPEND_DOCUMENT_BEGIN (&storage_opts, "wiredTiger", &wt_opts); - BSON_APPEND_UTF8 (&wt_opts, "configString", "block_compressor=zlib"); - bson_append_document_end (&storage_opts, &wt_opts); - bson_append_document_end (&options, &storage_opts); - - - name = gen_collection_name ("create_collection"); - ASSERT_OR_PRINT (collection = mongoc_database_create_collection ( - database, name, &options, &error), - error); - - bson_destroy (&options); - bson_free (name); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - ASSERT_OR_PRINT (mongoc_database_drop (database, &error), error); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_get_collection_info (void) -{ - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error = {0}; - bson_iter_t col_iter; - bson_t capped_options = BSON_INITIALIZER; - bson_t noopts_options = BSON_INITIALIZER; - bson_t name_filter = BSON_INITIALIZER; - const bson_t *doc; - int num_infos = 0; - - const char *name; - char *dbname; - char *capped_name; - char *noopts_name; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - dbname = gen_collection_name ("dbtest"); - database = mongoc_client_get_database (client, dbname); - - BSON_ASSERT (database); - bson_free (dbname); - - capped_name = gen_collection_name ("capped"); - BSON_APPEND_BOOL (&capped_options, "capped", true); - BSON_APPEND_INT32 (&capped_options, "size", 10000000); - BSON_APPEND_INT32 (&capped_options, "max", 1024); - - noopts_name = gen_collection_name ("noopts"); - - collection = mongoc_database_create_collection ( - database, capped_name, &capped_options, &error); - ASSERT_OR_PRINT (collection, error); - mongoc_collection_destroy (collection); - - collection = mongoc_database_create_collection ( - database, noopts_name, &noopts_options, &error); - ASSERT_OR_PRINT (collection, error); - mongoc_collection_destroy (collection); - - /* first we filter on collection name. */ - BSON_APPEND_UTF8 (&name_filter, "name", noopts_name); - - /* We only test with filters since get_collection_names will - * test w/o filters for us. */ - - /* Filter on an exact match of name */ - BEGIN_IGNORE_DEPRECATIONS - cursor = mongoc_database_find_collections (database, &name_filter, &error); - END_IGNORE_DEPRECATIONS - BSON_ASSERT (cursor); - BSON_ASSERT (!error.domain); - BSON_ASSERT (!error.code); - - while (mongoc_cursor_next (cursor, &doc)) { - if (bson_iter_init (&col_iter, doc) && - bson_iter_find (&col_iter, "name") && - BSON_ITER_HOLDS_UTF8 (&col_iter) && - (name = bson_iter_utf8 (&col_iter, NULL))) { - ++num_infos; - BSON_ASSERT (0 == strcmp (name, noopts_name)); - } else { - BSON_ASSERT (false); - } - } - - BSON_ASSERT (1 == num_infos); - - mongoc_cursor_destroy (cursor); - - ASSERT_OR_PRINT (mongoc_database_drop (database, &error), error); - BSON_ASSERT (!error.domain); - BSON_ASSERT (!error.code); - - bson_free (capped_name); - bson_free (noopts_name); - - bson_destroy (&capped_options); - bson_destroy (&noopts_options); - bson_destroy (&name_filter); - - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_get_collection_info_regex (void) -{ - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error = {0}; - bson_iter_t col_iter; - bson_t name_filter = BSON_INITIALIZER; - const bson_t *doc; - char *dbname; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - dbname = gen_collection_name ("test_get_collection_info_regex"); - database = mongoc_client_get_database (client, dbname); - mongoc_database_drop_with_opts (database, NULL, NULL); - - collection = - mongoc_database_create_collection (database, "abbbc", NULL, &error); - ASSERT_OR_PRINT (collection, error); - mongoc_collection_destroy (collection); - - collection = - mongoc_database_create_collection (database, "foo", NULL, &error); - ASSERT_OR_PRINT (collection, error); - - BSON_APPEND_REGEX (&name_filter, "name", "ab+c", NULL); - - BEGIN_IGNORE_DEPRECATIONS - cursor = mongoc_database_find_collections (database, &name_filter, &error); - END_IGNORE_DEPRECATIONS - - BSON_ASSERT (cursor); - BSON_ASSERT (!error.domain); - BSON_ASSERT (!error.code); - - BSON_ASSERT (mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (bson_iter_init_find (&col_iter, doc, "name")); - BSON_ASSERT (0 == strcmp (bson_iter_utf8 (&col_iter, NULL), "abbbc")); - - /* only one match */ - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - mongoc_cursor_destroy (cursor); - - bson_destroy (&name_filter); - mongoc_collection_destroy (collection); - bson_free (dbname); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_get_collection_info_with_opts_regex (void) -{ - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_cursor_t *cursor; - bson_error_t error = {0}; - bson_iter_t col_iter; - bson_t opts = BSON_INITIALIZER; - bson_t name_filter; - const bson_t *doc; - char *dbname; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - dbname = gen_collection_name ("test_get_collection_info_regex"); - database = mongoc_client_get_database (client, dbname); - mongoc_database_drop_with_opts (database, NULL, NULL); - - collection = - mongoc_database_create_collection (database, "abbbc", NULL, &error); - ASSERT_OR_PRINT (collection, error); - mongoc_collection_destroy (collection); - - collection = - mongoc_database_create_collection (database, "foo", NULL, &error); - ASSERT_OR_PRINT (collection, error); - - BSON_APPEND_DOCUMENT_BEGIN (&opts, "filter", &name_filter); - BSON_APPEND_REGEX (&name_filter, "name", "ab+c", NULL); - bson_append_document_end (&opts, &name_filter); - - cursor = mongoc_database_find_collections_with_opts (database, &opts); - BSON_ASSERT (cursor); - - BSON_ASSERT (!error.domain); - BSON_ASSERT (!error.code); - - BSON_ASSERT (mongoc_cursor_next (cursor, &doc)); - BSON_ASSERT (bson_iter_init_find (&col_iter, doc, "name")); - BSON_ASSERT (0 == strcmp (bson_iter_utf8 (&col_iter, NULL), "abbbc")); - - /* only one match */ - BSON_ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - mongoc_cursor_destroy (cursor); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - bson_free (dbname); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -_test_get_collection_info_getmore () -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_database_t *database; - future_t *future; - request_t *request; - char **names; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - database = mongoc_client_get_database (client, "db"); - future = - future_database_get_collection_names_with_opts (database, NULL, NULL); - - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'listCollections': 1, 'nameOnly': true}"); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '123'}," - " 'ns': 'db.$cmd.listCollections'," - " 'firstBatch': [{'name': 'a'}]}}"); - request_destroy (request); - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'getMore': {'$numberLong': '123'}," - " 'collection': '$cmd.listCollections'}"); - - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': {'$numberLong': '0'}," - " 'ns': 'db.$cmd.listCollections'," - " 'nextBatch': []}}"); - request_destroy (request); - names = future_get_char_ptr_ptr (future); - BSON_ASSERT (names); - ASSERT_CMPSTR (names[0], "a"); - - bson_strfreev (names); - future_destroy (future); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_get_collection_info_getmore_cmd (void) -{ - _test_get_collection_info_getmore (); -} - -static void -test_get_collection (void) -{ - mongoc_client_t *client; - mongoc_database_t *database; - mongoc_write_concern_t *wc; - mongoc_read_concern_t *rc; - mongoc_read_prefs_t *read_prefs; - mongoc_collection_t *collection; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - database = mongoc_client_get_database (client, "test"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_database_set_write_concern (database, wc); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, "majority"); - mongoc_database_set_read_concern (database, rc); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_database_set_read_prefs (database, read_prefs); - - collection = mongoc_database_get_collection (database, "test"); - - ASSERT_CMPINT32 (collection->write_concern->w, ==, 2); - ASSERT_CMPSTR (collection->read_concern->level, "majority"); - ASSERT_CMPINT (collection->read_prefs->mode, ==, MONGOC_READ_SECONDARY); - - mongoc_collection_destroy (collection); - mongoc_read_prefs_destroy (read_prefs); - mongoc_read_concern_destroy (rc); - mongoc_write_concern_destroy (wc); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_get_collection_names (void) -{ - mongoc_database_t *database; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error = {0}; - bson_t options; - int namecount; - int explicit_nameonly; - - char **names; - char **name; - char *curname; - - char *dbname; - char *name1; - char *name2; - char *name3; - char *name4; - char *name5; - const char *system_prefix = "system."; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - dbname = gen_collection_name ("dbtest"); - database = mongoc_client_get_database (client, dbname); - - BSON_ASSERT (database); - bson_free (dbname); - - bson_init (&options); - - name1 = gen_collection_name ("name1"); - name2 = gen_collection_name ("name2"); - name3 = gen_collection_name ("name3"); - name4 = gen_collection_name ("name4"); - name5 = gen_collection_name ("name5"); - - collection = - mongoc_database_create_collection (database, name1, &options, &error); - BSON_ASSERT (collection); - mongoc_collection_destroy (collection); - - collection = - mongoc_database_create_collection (database, name2, &options, &error); - BSON_ASSERT (collection); - mongoc_collection_destroy (collection); - - collection = - mongoc_database_create_collection (database, name3, &options, &error); - BSON_ASSERT (collection); - mongoc_collection_destroy (collection); - - collection = - mongoc_database_create_collection (database, name4, &options, &error); - BSON_ASSERT (collection); - mongoc_collection_destroy (collection); - - collection = - mongoc_database_create_collection (database, name5, &options, &error); - BSON_ASSERT (collection); - mongoc_collection_destroy (collection); - - for (explicit_nameonly = 0; explicit_nameonly <= 1; explicit_nameonly++) { - namecount = 0; - - /* ensure that if users happen to pass nameOnly in opts we don't - * append it again and cause a "duplicate field" server error */ - if (explicit_nameonly) { - names = mongoc_database_get_collection_names_with_opts ( - database, tmp_bson ("{'nameOnly': true}"), &error); - } else { - names = mongoc_database_get_collection_names_with_opts ( - database, NULL, &error); - } - BSON_ASSERT (!error.domain); - BSON_ASSERT (!error.code); - - for (name = names; *name; ++name) { - /* inefficient, but OK for a unit test. */ - curname = *name; - - if (0 == strcmp (curname, name1) || 0 == strcmp (curname, name2) || - 0 == strcmp (curname, name3) || 0 == strcmp (curname, name4) || - 0 == strcmp (curname, name5)) { - ++namecount; - } else if (0 == - strncmp (curname, system_prefix, strlen (system_prefix))) { - /* Collections prefixed with 'system.' are system collections */ - } else { - BSON_ASSERT (false); - } - - bson_free (curname); - } - - BSON_ASSERT (namecount == 5); - bson_free (names); - } - - bson_free (name1); - bson_free (name2); - bson_free (name3); - bson_free (name4); - bson_free (name5); - - ASSERT_OR_PRINT (mongoc_database_drop (database, &error), error); - BSON_ASSERT (!error.domain); - BSON_ASSERT (!error.code); - - bson_destroy (&options); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_get_collection_names_error (void) -{ - mongoc_database_t *database; - mongoc_client_t *client; - mock_server_t *server; - bson_error_t error = {0}; - bson_t b = BSON_INITIALIZER; - future_t *future; - request_t *request; - char **names; - - capture_logs (true); - - server = mock_server_new (); - mock_server_auto_ismaster (server, - "{'ismaster': true," - " 'maxWireVersion': 3}"); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - database = mongoc_client_get_database (client, "test"); - future = - future_database_get_collection_names_with_opts (database, NULL, &error); - request = - mock_server_receives_command (server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{'listCollections': 1, 'nameOnly': true}"); - mock_server_hangs_up (request); - names = future_get_char_ptr_ptr (future); - BSON_ASSERT (!names); - ASSERT_CMPINT (MONGOC_ERROR_STREAM, ==, error.domain); - ASSERT_CMPINT (MONGOC_ERROR_STREAM_SOCKET, ==, error.code); - - request_destroy (request); - future_destroy (future); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - mock_server_destroy (server); - bson_destroy (&b); -} - -static void -test_get_default_database (void) -{ - /* default database is "db_name" */ - mongoc_client_t *client = mongoc_client_new ("mongodb://host/db_name"); - mongoc_database_t *db = mongoc_client_get_default_database (client); - - BSON_ASSERT (!strcmp ("db_name", mongoc_database_get_name (db))); - - mongoc_database_destroy (db); - mongoc_client_destroy (client); - - /* no default database */ - client = mongoc_client_new ("mongodb://host/"); - db = mongoc_client_get_default_database (client); - - BSON_ASSERT (!db); - - mongoc_client_destroy (client); -} - -void -test_database_install (TestSuite *suite) -{ - TestSuite_AddMockServerTest ( - suite, "/Database/aggregate/writeConcern", test_aggregate_write_concern); - - 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, - test_framework_skip_if_max_wire_version_less_than_5); - TestSuite_AddLive (suite, "/Database/copy", test_copy); - TestSuite_AddLive (suite, "/Database/has_collection", test_has_collection); - TestSuite_AddLive (suite, "/Database/command", test_command); - TestSuite_AddMockServerTest (suite, - "/Database/command/read_prefs/simple/single", - test_db_command_simple_read_prefs_single); - TestSuite_AddMockServerTest (suite, - "/Database/command/read_prefs/simple/pooled", - test_db_command_simple_read_prefs_pooled); - TestSuite_AddMockServerTest (suite, - "/Database/command/read_prefs/single", - test_db_command_read_prefs_single); - TestSuite_AddMockServerTest (suite, - "/Database/command/read_prefs/pooled", - test_db_command_read_prefs_pooled); - TestSuite_AddLive (suite, "/Database/drop", test_drop); - TestSuite_AddLive ( - suite, "/Database/create_collection", test_create_collection); - TestSuite_AddLive ( - suite, "/Database/get_collection_info", test_get_collection_info); - TestSuite_AddLive (suite, - "/Database/get_collection_info_regex", - test_get_collection_info_regex); - TestSuite_AddLive (suite, - "/Database/get_collection_info_with_opts_regex", - test_get_collection_info_with_opts_regex); - TestSuite_AddMockServerTest (suite, - "/Database/get_collection/getmore_cmd", - test_get_collection_info_getmore_cmd); - TestSuite_AddLive (suite, "/Database/get_collection", test_get_collection); - TestSuite_AddLive ( - suite, "/Database/get_collection_names", test_get_collection_names); - TestSuite_AddMockServerTest (suite, - "/Database/get_collection_names_error", - test_get_collection_names_error); - TestSuite_Add ( - suite, "/Database/get_default_database", test_get_default_database); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-dns.c b/lib/mongoc/libmongoc/tests/test-mongoc-dns.c deleted file mode 100644 index 0cf9f9f35e47a55be96ac874fc824770215aebb6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-dns.c +++ /dev/null @@ -1,341 +0,0 @@ -#include <mongoc/mongoc-util-private.h> -#include <mongoc/mongoc-client-pool-private.h> -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-thread-private.h" -#include "mongoc/mongoc-uri-private.h" - -#include "json-test.h" -#include "test-libmongoc.h" - -static void -_assert_options_match (const bson_t *test, mongoc_client_t *client) -{ - match_ctx_t ctx = {{0}}; - bson_iter_t iter; - bson_t opts_from_test; - const bson_t *opts_from_uri; - const bson_t *creds_from_uri; - const bson_t *opts_or_creds; - bson_iter_t test_opts_iter; - bson_iter_t uri_opts_iter; - const char *opt_name, *opt_name_canon; - const bson_value_t *test_value, *uri_value; - - if (!bson_iter_init_find (&iter, test, "options")) { - /* no URI options specified in the test */ - return; - } - - bson_iter_bson (&iter, &opts_from_test); - BSON_ASSERT (bson_iter_init (&test_opts_iter, &opts_from_test)); - - /* the client's URI is not updated from TXT, but the topology's copy is */ - opts_from_uri = mongoc_uri_get_options (client->topology->uri); - creds_from_uri = mongoc_uri_get_credentials (client->topology->uri); - - while (bson_iter_next (&test_opts_iter)) { - opt_name = bson_iter_key (&test_opts_iter); - opt_name_canon = mongoc_uri_canonicalize_option (opt_name); - opts_or_creds = !bson_strcasecmp (opt_name, "authSource") ? creds_from_uri - : opts_from_uri; - if (!bson_iter_init_find_case ( - &uri_opts_iter, opts_or_creds, opt_name_canon)) { - fprintf (stderr, - "URI options incorrectly set from TXT record: " - "no option named \"%s\"\n" - "expected: %s\n" - "actual: %s\n", - opt_name, - bson_as_json (&opts_from_test, NULL), - bson_as_json (opts_or_creds, NULL)); - abort (); - } - - test_value = bson_iter_value (&test_opts_iter); - uri_value = bson_iter_value (&uri_opts_iter); - if (!match_bson_value (uri_value, test_value, &ctx)) { - fprintf (stderr, - "URI option \"%s\" incorrectly set from TXT record: %s\n" - "expected: %s\n" - "actual: %s\n", - opt_name, - ctx.errmsg, - bson_as_json (&opts_from_test, NULL), - bson_as_json (opts_from_uri, NULL)); - abort (); - } - } -} - - -typedef struct { - bson_mutex_t mutex; - mongoc_host_list_t *hosts; -} context_t; - - -static void -topology_changed (const mongoc_apm_topology_changed_t *event) -{ - context_t *ctx; - const mongoc_topology_description_t *td; - size_t i; - size_t n; - mongoc_server_description_t **sds; - - ctx = (context_t *) mongoc_apm_topology_changed_get_context (event); - - td = mongoc_apm_topology_changed_get_new_description (event); - sds = mongoc_topology_description_get_servers (td, &n); - - bson_mutex_lock (&ctx->mutex); - _mongoc_host_list_destroy_all (ctx->hosts); - ctx->hosts = NULL; - for (i = 0; i < n; i++) { - ctx->hosts = _mongoc_host_list_push ( - sds[i]->host.host, sds[i]->host.port, AF_UNSPEC, ctx->hosts); - } - bson_mutex_unlock (&ctx->mutex); - - mongoc_server_descriptions_destroy_all (sds, n); -} - - -static bool -host_list_contains (const mongoc_host_list_t *hl, const char *host_and_port) -{ - while (hl) { - if (!strcmp (hl->host_and_port, host_and_port)) { - return true; - } - - hl = hl->next; - } - - return false; -} - - -static int -hosts_count (const bson_t *test) -{ - bson_iter_t iter; - bson_iter_t hosts; - int c = 0; - - BSON_ASSERT (bson_iter_init_find (&iter, test, "hosts")); - BSON_ASSERT (bson_iter_recurse (&iter, &hosts)); - while (bson_iter_next (&hosts)) { - c++; - } - - return c; -} - - -static bool -_host_list_matches (const bson_t *test, context_t *ctx) -{ - bson_iter_t iter; - bson_iter_t hosts; - const char *host_and_port; - bool ret = true; - - BSON_ASSERT (bson_iter_init_find (&iter, test, "hosts")); - BSON_ASSERT (bson_iter_recurse (&iter, &hosts)); - - bson_mutex_lock (&ctx->mutex); - BSON_ASSERT (bson_iter_recurse (&iter, &hosts)); - while (bson_iter_next (&hosts)) { - host_and_port = bson_iter_utf8 (&hosts, NULL); - if (!host_list_contains (ctx->hosts, host_and_port)) { - ret = false; - break; - } - } - - _mongoc_host_list_destroy_all (ctx->hosts); - ctx->hosts = NULL; - bson_mutex_unlock (&ctx->mutex); - - return ret; -} - - -static void -_test_dns_maybe_pooled (bson_t *test, bool pooled) -{ - context_t ctx; - bool expect_ssl; - bool expect_error; - mongoc_uri_t *uri; - mongoc_apm_callbacks_t *callbacks; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - int n_hosts; - bson_error_t error; - bool r; - - if (!test_framework_get_ssl ()) { - fprintf (stderr, - "Must configure an SSL replica set and set MONGOC_TEST_SSL=on " - "and other ssl options to test DNS\n"); - abort (); - } - - bson_mutex_init (&ctx.mutex); - ctx.hosts = NULL; - expect_ssl = strstr (bson_lookup_utf8 (test, "uri"), "ssl=false") == NULL; - expect_error = _mongoc_lookup_bool (test, "error", false /* default */); - - uri = mongoc_uri_new_with_error (bson_lookup_utf8 (test, "uri"), &error); - if (!expect_error) { - ASSERT_OR_PRINT (uri, error); - } - - if (!uri) { - /* expected failure, e.g. we're testing an invalid URI */ - return; - } - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_topology_changed_cb (callbacks, topology_changed); - - /* suppress "cannot override URI option" messages */ - capture_logs (true); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - - /* before we set SSL on so that we can connect to the test replica set, - * assert that the URI has SSL on by default, and SSL off if "ssl=false" - * is in the URI string */ - BSON_ASSERT ( - mongoc_uri_get_tls (_mongoc_client_pool_get_topology (pool)->uri) == - expect_ssl); - test_framework_set_pool_ssl_opts (pool); - mongoc_client_pool_set_apm_callbacks (pool, callbacks, &ctx); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - BSON_ASSERT (mongoc_uri_get_tls (client->uri) == expect_ssl); - test_framework_set_ssl_opts (client); - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - } - - n_hosts = hosts_count (test); - - if (n_hosts && !expect_error) { - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - WAIT_UNTIL (_host_list_matches (test, &ctx)); - } else { - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - ""); - } - - _assert_options_match (test, client); - - /* the client has a copy of the topology's URI, assert they're the same */ - ASSERT (bson_equal (mongoc_uri_get_options (client->uri), - mongoc_uri_get_options (client->topology->uri))); - ASSERT (bson_equal (mongoc_uri_get_credentials (client->uri), - mongoc_uri_get_credentials (client->topology->uri))); - if (!mongoc_uri_get_hosts (client->uri)) { - ASSERT (!mongoc_uri_get_hosts (client->topology->uri)); - } else { - _mongoc_host_list_equal (mongoc_uri_get_hosts (client->uri), - mongoc_uri_get_hosts (client->topology->uri)); - } - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_apm_callbacks_destroy (callbacks); - mongoc_uri_destroy (uri); -} - - -static void -test_dns (bson_t *test) -{ - _test_dns_maybe_pooled (test, false); - _test_dns_maybe_pooled (test, true); -} - - -static int -test_dns_check (void) -{ - return test_framework_getenv_bool ("MONGOC_TEST_DNS") ? 1 : 0; -} - - -/* ensure mongoc_topology_select_server_id handles a NULL error pointer in the - * code path it follows when the topology scanner is invalid */ -static void -test_null_error_pointer (void *ctx) -{ - mongoc_client_t *client; - - client = mongoc_client_new ("mongodb+srv://doesntexist.example.com"); - ASSERT (!mongoc_topology_select_server_id (client->topology, - MONGOC_SS_READ, - NULL /* read prefs */, - NULL /* error */)); - - mongoc_client_destroy (client); -} - - -/* - *----------------------------------------------------------------------- - * - * Runner for the JSON tests for mongodb+srv URIs. - * - *----------------------------------------------------------------------- - */ -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - test_framework_resolve_path (JSON_DIR "/initial_dns_seedlist_discovery", - resolved); - install_json_test_suite_with_check (suite, - resolved, - test_dns, - test_dns_check, - test_framework_skip_if_no_crypto); - - test_framework_resolve_path (JSON_DIR "/initial_dns_auth", resolved); - install_json_test_suite_with_check (suite, - resolved, - test_dns, - test_dns_check, - test_framework_skip_if_no_crypto); -} - - -void -test_dns_install (TestSuite *suite) -{ - test_all_spec_tests (suite); - TestSuite_AddFull (suite, - "/initial_dns_seedlist_discovery/null_error_pointer", - test_null_error_pointer, - NULL, - NULL, - test_framework_skip_if_no_crypto); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-error.c b/lib/mongoc/libmongoc/tests/test-mongoc-error.c deleted file mode 100644 index 31d52826d837e1cbf56493eb1c0e9d1dbd5519e3..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-error.c +++ /dev/null @@ -1,151 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "error-test" - - -static void -test_set_error_api_single (void) -{ - mongoc_client_t *client; - int32_t unsupported_versions[] = {-1, 0, 3}; - int i; - - capture_logs (true); - client = test_framework_client_new (); - - for (i = 0; i < sizeof (unsupported_versions) / sizeof (int32_t); i++) { - ASSERT (!mongoc_client_set_error_api (client, unsupported_versions[i])); - ASSERT_CAPTURED_LOG ("mongoc_client_set_error_api", - MONGOC_LOG_LEVEL_ERROR, - "Unsupported Error API Version"); - } - - mongoc_client_destroy (client); -} - - -static void -test_set_error_api_pooled (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - int32_t unsupported_versions[] = {-1, 0, 3}; - int i; - - capture_logs (true); - pool = test_framework_client_pool_new (); - - for (i = 0; i < sizeof (unsupported_versions) / sizeof (int32_t); i++) { - ASSERT ( - !mongoc_client_pool_set_error_api (pool, unsupported_versions[i])); - ASSERT_CAPTURED_LOG ("mongoc_client_pool_set_error_api", - MONGOC_LOG_LEVEL_ERROR, - "Unsupported Error API Version"); - } - - client = mongoc_client_pool_pop (pool); - ASSERT (!mongoc_client_set_error_api (client, 1)); - ASSERT_CAPTURED_LOG ("mongoc_client_set_error_api", - MONGOC_LOG_LEVEL_ERROR, - "Cannot set Error API Version on a pooled client"); - - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); -} - - -static void -_test_command_error (int32_t error_api_version) -{ - mock_server_t *server; - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - if (error_api_version != 0) { - BSON_ASSERT (mongoc_client_set_error_api (client, error_api_version)); - } - - future = future_client_command_simple ( - client, "db", tmp_bson ("{'foo': 1}"), NULL, &reply, &error); - request = - mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, NULL); - mock_server_replies_simple (request, - "{'ok': 0, 'code': 42, 'errmsg': 'foo'}"); - ASSERT (!future_get_bool (future)); - - if (error_api_version >= 2) { - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 42, "foo"); - } else { - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_QUERY, 42, "foo"); - } - - future_destroy (future); - request_destroy (request); - bson_destroy (&reply); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_command_error_default (void) -{ - _test_command_error (0); -} - - -static void -test_command_error_v1 (void) -{ - _test_command_error (1); -} - - -static void -test_command_error_v2 (void) -{ - _test_command_error (2); -} - -static void -test_has_label (void) -{ - bson_t *reply = tmp_bson ("{'errorLabels': ['foo', 'bar']}"); - BSON_ASSERT (mongoc_error_has_label (reply, "foo")); - BSON_ASSERT (mongoc_error_has_label (reply, "bar")); - BSON_ASSERT (!mongoc_error_has_label (reply, "baz")); - BSON_ASSERT (!mongoc_error_has_label (tmp_bson ("{}"), "foo")); -} - - -void -test_error_install (TestSuite *suite) -{ - TestSuite_AddLive ( - suite, "/Error/set_api/single", test_set_error_api_single); - TestSuite_AddLive ( - suite, "/Error/set_api/pooled", test_set_error_api_pooled); - TestSuite_AddMockServerTest ( - suite, "/Error/command/default", test_command_error_default); - TestSuite_AddMockServerTest ( - suite, "/Error/command/v1", test_command_error_v1); - TestSuite_AddMockServerTest ( - suite, "/Error/command/v2", test_command_error_v2); - TestSuite_Add (suite, "/Error/has_label", test_has_label); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-exhaust.c b/lib/mongoc/libmongoc/tests/test-mongoc-exhaust.c deleted file mode 100644 index ebb24cafa4f1a3ca3b6f4e334bae519eab2a609c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-exhaust.c +++ /dev/null @@ -1,598 +0,0 @@ -#include <fcntl.h> -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-cursor-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-util-private.h" - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" - - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "exhaust-test" - - -int -skip_if_mongos (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - return test_framework_is_mongos () ? 0 : 1; -} - - -static int64_t -get_timestamp (mongoc_client_t *client, mongoc_cursor_t *cursor) -{ - uint32_t server_id; - - server_id = mongoc_cursor_get_hint (cursor); - - if (client->topology->single_threaded) { - mongoc_topology_scanner_node_t *scanner_node; - - scanner_node = mongoc_topology_scanner_get_node ( - client->topology->scanner, server_id); - - return scanner_node->timestamp; - } else { - mongoc_cluster_node_t *cluster_node; - - cluster_node = (mongoc_cluster_node_t *) mongoc_set_get ( - client->cluster.nodes, server_id); - - return cluster_node->timestamp; - } -} - - -static void -test_exhaust_cursor (bool pooled) -{ - mongoc_stream_t *stream; - mongoc_write_concern_t *wr; - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - mongoc_cursor_t *cursor2; - const bson_t *doc; - bson_t q; - bson_t b[10]; - bson_t *bptr[10]; - int i; - bool r; - uint32_t server_id; - bson_error_t error; - bson_oid_t oid; - int64_t timestamp1; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_exhaust_cursor"); - BSON_ASSERT (collection); - - /* don't care if ns not found. */ - (void) mongoc_collection_drop (collection, &error); - - wr = mongoc_write_concern_new (); - mongoc_write_concern_set_journal (wr, true); - - /* bulk insert some records to work on */ - { - bson_init (&q); - - for (i = 0; i < 10; i++) { - bson_init (&b[i]); - bson_oid_init (&oid, NULL); - bson_append_oid (&b[i], "_id", -1, &oid); - bson_append_int32 (&b[i], "n", -1, i % 2); - bptr[i] = &b[i]; - } - - BEGIN_IGNORE_DEPRECATIONS; - ASSERT_OR_PRINT (mongoc_collection_insert_bulk (collection, - MONGOC_INSERT_NONE, - (const bson_t **) bptr, - 10, - wr, - &error), - error); - END_IGNORE_DEPRECATIONS; - } - - /* create a couple of cursors */ - { - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, &q, NULL, NULL); - - cursor2 = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, &q, NULL, NULL); - } - - /* Read from the exhaust cursor, ensure that we're in exhaust where we - * should be and ensure that an early destroy properly causes a disconnect - * */ - { - r = mongoc_cursor_next (cursor, &doc); - if (!r) { - mongoc_cursor_error (cursor, &error); - fprintf (stderr, "cursor error: %s\n", error.message); - } - BSON_ASSERT (r); - BSON_ASSERT (doc); - BSON_ASSERT (cursor->in_exhaust); - BSON_ASSERT (client->in_exhaust); - - /* destroy the cursor, make sure a disconnect happened */ - timestamp1 = get_timestamp (client, cursor); - mongoc_cursor_destroy (cursor); - BSON_ASSERT (!client->in_exhaust); - } - - /* ensure even a 1 ms-resolution clock advances significantly */ - _mongoc_usleep (1000 * 1000); - - /* Grab a new exhaust cursor, then verify that reading from that cursor - * (putting the client into exhaust), breaks a mid-stream read from a - * regular cursor */ - { - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, &q, NULL, NULL); - - r = mongoc_cursor_next (cursor2, &doc); - if (!r) { - mongoc_cursor_error (cursor2, &error); - fprintf (stderr, "cursor error: %s\n", error.message); - } - BSON_ASSERT (r); - BSON_ASSERT (doc); - ASSERT_CMPINT64 (timestamp1, <, get_timestamp (client, cursor2)); - - for (i = 0; i < 5; i++) { - r = mongoc_cursor_next (cursor2, &doc); - if (!r) { - mongoc_cursor_error (cursor2, &error); - fprintf (stderr, "cursor error: %s\n", error.message); - } - BSON_ASSERT (r); - BSON_ASSERT (doc); - } - - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (r); - BSON_ASSERT (doc); - - doc = NULL; - r = mongoc_cursor_next (cursor2, &doc); - BSON_ASSERT (!r); - BSON_ASSERT (!doc); - - mongoc_cursor_error (cursor2, &error); - ASSERT_CMPUINT32 (error.domain, ==, MONGOC_ERROR_CLIENT); - ASSERT_CMPUINT32 (error.code, ==, MONGOC_ERROR_CLIENT_IN_EXHAUST); - - mongoc_cursor_destroy (cursor2); - } - - /* make sure writes fail as well */ - { - BEGIN_IGNORE_DEPRECATIONS; - r = mongoc_collection_insert_bulk (collection, - MONGOC_INSERT_NONE, - (const bson_t **) bptr, - 10, - wr, - &error); - END_IGNORE_DEPRECATIONS; - - BSON_ASSERT (!r); - ASSERT_CMPUINT32 (error.domain, ==, MONGOC_ERROR_CLIENT); - ASSERT_CMPUINT32 (error.code, ==, MONGOC_ERROR_CLIENT_IN_EXHAUST); - } - - /* we're still in exhaust. - * - * 1. check that we can create a new cursor, as long as we don't read from it - * 2. fully exhaust the exhaust cursor - * 3. make sure that we don't disconnect at destroy - * 4. make sure we can read the cursor we made during the exhaust - */ - { - cursor2 = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, &q, NULL, NULL); - - server_id = cursor->server_id; - stream = - (mongoc_stream_t *) mongoc_set_get (client->cluster.nodes, server_id); - - for (i = 1; i < 10; i++) { - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (r); - BSON_ASSERT (doc); - } - - r = mongoc_cursor_next (cursor, &doc); - BSON_ASSERT (!r); - BSON_ASSERT (!doc); - - mongoc_cursor_destroy (cursor); - - BSON_ASSERT (stream == (mongoc_stream_t *) mongoc_set_get ( - client->cluster.nodes, server_id)); - - r = mongoc_cursor_next (cursor2, &doc); - BSON_ASSERT (r); - BSON_ASSERT (doc); - } - - bson_destroy (&q); - for (i = 0; i < 10; i++) { - bson_destroy (&b[i]); - } - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_write_concern_destroy (wr); - mongoc_cursor_destroy (cursor2); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - -static void -test_exhaust_cursor_single (void *context) -{ - test_exhaust_cursor (false); -} - -static void -test_exhaust_cursor_pool (void *context) -{ - test_exhaust_cursor (true); -} - -static void -test_exhaust_cursor_multi_batch (void *context) -{ - mongoc_client_t *client; - bson_error_t error; - mongoc_collection_t *collection; - bson_t doc = BSON_INITIALIZER; - mongoc_bulk_operation_t *bulk; - int i; - uint32_t server_id; - mongoc_cursor_t *cursor; - const bson_t *cursor_doc; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_exhaust_cursor_multi_batch"); - - ASSERT_OR_PRINT (collection, error); - - BSON_APPEND_UTF8 (&doc, "key", "value"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - /* enough to require more than initial batch */ - for (i = 0; i < 1000; i++) { - mongoc_bulk_operation_insert (bulk, &doc); - } - - server_id = mongoc_bulk_operation_execute (bulk, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, tmp_bson ("{}"), NULL, NULL); - - i = 0; - while (mongoc_cursor_next (cursor, &cursor_doc)) { - i++; - ASSERT (mongoc_cursor_more (cursor)); - } - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - ASSERT (!mongoc_cursor_more (cursor)); - ASSERT_CMPINT (i, ==, 1000); - - mongoc_cursor_destroy (cursor); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - bson_destroy (&doc); - mongoc_client_destroy (client); -} - -static void -test_cursor_set_max_await_time_ms (void) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *bson; - - client = test_framework_client_new (); - collection = - get_test_collection (client, "test_cursor_set_max_await_time_ms"); - - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_TAILABLE_CURSOR | - MONGOC_QUERY_AWAIT_DATA, - 0, - 0, - 0, - tmp_bson ("{}"), - NULL, - NULL); - - ASSERT_CMPINT (0, ==, mongoc_cursor_get_max_await_time_ms (cursor)); - mongoc_cursor_set_max_await_time_ms (cursor, 123); - ASSERT_CMPINT (123, ==, mongoc_cursor_get_max_await_time_ms (cursor)); - mongoc_cursor_next (cursor, &bson); - - /* once started, cursor ignores set_max_await_time_ms () */ - mongoc_cursor_set_max_await_time_ms (cursor, 42); - ASSERT_CMPINT (123, ==, mongoc_cursor_get_max_await_time_ms (cursor)); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -typedef enum { - FIRST_BATCH, - SECOND_BATCH, -} exhaust_error_when_t; - -typedef enum { - NETWORK_ERROR, - SERVER_ERROR, -} exhaust_error_type_t; - -static void -_request_error (request_t *request, exhaust_error_type_t error_type) -{ - if (error_type == NETWORK_ERROR) { - mock_server_resets (request); - } else { - mock_server_replies (request, - MONGOC_REPLY_QUERY_FAILURE, - 123, - 0, - 0, - "{'$err': 'uh oh', 'code': 4321}"); - } -} - -static void -_check_error (mongoc_client_t *client, - mongoc_cursor_t *cursor, - exhaust_error_type_t error_type) -{ - uint32_t server_id; - bson_error_t error; - - server_id = mongoc_cursor_get_hint (cursor); - ASSERT (server_id); - ASSERT (mongoc_cursor_error (cursor, &error)); - - if (error_type == NETWORK_ERROR) { - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "socket error or timeout"); - - /* socket was discarded */ - ASSERT (!mongoc_cluster_stream_for_server (&client->cluster, - server_id, - false /* don't reconnect */, - NULL, - NULL, - &error)); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_SOCKET, - "socket error or timeout"); - } else { - /* query failure */ - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_QUERY, - 4321 /* error from mock server */, - "uh oh" /* message from mock server */); - } -} - -static void -_mock_test_exhaust (bool pooled, - exhaust_error_when_t error_when, - exhaust_error_type_t error_type) -{ - mock_server_t *server; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - - capture_logs (true); - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - - if (pooled) { - pool = mongoc_client_pool_new (mock_server_get_uri (server)); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - } - - collection = mongoc_client_get_collection (client, "db", "test"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_EXHAUST, 0, 0, 0, tmp_bson ("{}"), NULL, NULL); - - future = future_cursor_next (cursor, &doc); - request = - mock_server_receives_query (server, - "db.test", - MONGOC_QUERY_SLAVE_OK | MONGOC_QUERY_EXHAUST, - 0, - 0, - "{}", - NULL); - - if (error_when == SECOND_BATCH) { - /* initial query succeeds, gets a doc and cursor id of 123 */ - mock_server_replies (request, MONGOC_REPLY_NONE, 123, 1, 1, "{'a': 1}"); - ASSERT (future_get_bool (future)); - ASSERT (match_bson (doc, tmp_bson ("{'a': 1}"), false)); - ASSERT_CMPINT64 ((int64_t) 123, ==, mongoc_cursor_get_id (cursor)); - - future_destroy (future); - - /* error after initial batch */ - future = future_cursor_next (cursor, &doc); - } - - _request_error (request, error_type); - ASSERT (!future_get_bool (future)); - _check_error (client, cursor, error_type); - - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mock_server_destroy (server); -} - -static void -test_exhaust_network_err_1st_batch_single (void) -{ - _mock_test_exhaust (false, FIRST_BATCH, NETWORK_ERROR); -} - -static void -test_exhaust_network_err_1st_batch_pooled (void) -{ - _mock_test_exhaust (true, FIRST_BATCH, NETWORK_ERROR); -} - -static void -test_exhaust_server_err_1st_batch_single (void) -{ - _mock_test_exhaust (false, FIRST_BATCH, SERVER_ERROR); -} - -static void -test_exhaust_server_err_1st_batch_pooled (void) -{ - _mock_test_exhaust (true, FIRST_BATCH, SERVER_ERROR); -} - -static void -test_exhaust_network_err_2nd_batch_single (void) -{ - _mock_test_exhaust (false, SECOND_BATCH, NETWORK_ERROR); -} - -static void -test_exhaust_network_err_2nd_batch_pooled (void) -{ - _mock_test_exhaust (true, SECOND_BATCH, NETWORK_ERROR); -} - -static void -test_exhaust_server_err_2nd_batch_single (void) -{ - _mock_test_exhaust (false, SECOND_BATCH, SERVER_ERROR); -} - -static void -test_exhaust_server_err_2nd_batch_pooled (void) -{ - _mock_test_exhaust (true, SECOND_BATCH, SERVER_ERROR); -} - -void -test_exhaust_install (TestSuite *suite) -{ - TestSuite_AddFull (suite, - "/Client/exhaust_cursor/single", - test_exhaust_cursor_single, - NULL, - NULL, - skip_if_mongos); - TestSuite_AddFull (suite, - "/Client/exhaust_cursor/pool", - test_exhaust_cursor_pool, - NULL, - NULL, - skip_if_mongos); - TestSuite_AddFull (suite, - "/Client/exhaust_cursor/batches", - test_exhaust_cursor_multi_batch, - NULL, - NULL, - skip_if_mongos); - TestSuite_AddLive (suite, - "/Client/set_max_await_time_ms", - test_cursor_set_max_await_time_ms); - TestSuite_AddMockServerTest ( - suite, - "/Client/exhaust_cursor/err/network/1st_batch/single", - test_exhaust_network_err_1st_batch_single); - TestSuite_AddMockServerTest ( - suite, - "/Client/exhaust_cursor/err/network/1st_batch/pooled", - test_exhaust_network_err_1st_batch_pooled); - TestSuite_AddMockServerTest ( - suite, - "/Client/exhaust_cursor/err/server/1st_batch/single", - test_exhaust_server_err_1st_batch_single); - TestSuite_AddMockServerTest ( - suite, - "/Client/exhaust_cursor/err/server/1st_batch/pooled", - test_exhaust_server_err_1st_batch_pooled); - TestSuite_AddMockServerTest ( - suite, - "/Client/exhaust_cursor/err/network/2nd_batch/single", - test_exhaust_network_err_2nd_batch_single); - TestSuite_AddMockServerTest ( - suite, - "/Client/exhaust_cursor/err/network/2nd_batch/pooled", - test_exhaust_network_err_2nd_batch_pooled); - TestSuite_AddMockServerTest ( - suite, - "/Client/exhaust_cursor/err/server/2nd_batch/single", - test_exhaust_server_err_2nd_batch_single); - TestSuite_AddMockServerTest ( - suite, - "/Client/exhaust_cursor/err/server/2nd_batch/pooled", - test_exhaust_server_err_2nd_batch_pooled); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-find-and-modify.c b/lib/mongoc/libmongoc/tests/test-mongoc-find-and-modify.c deleted file mode 100644 index d9c6251524f6a3809e6aa54e50cafb2e25a462a9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-find-and-modify.c +++ /dev/null @@ -1,597 +0,0 @@ -#include <bson/bcon.h> -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-collection-private.h> -#include <mongoc/mongoc-find-and-modify-private.h> -#include <mongoc/mongoc-client-private.h> - -#include "TestSuite.h" - -#include "test-libmongoc.h" -#include "test-conveniences.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" - -static void -auto_ismaster (mock_server_t *server, - int32_t max_wire_version, - int32_t max_message_size, - int32_t max_bson_size, - int32_t max_batch_size) -{ - char *response = bson_strdup_printf ("{'ismaster': true, " - " 'maxWireVersion': %d," - " 'maxBsonObjectSize': %d," - " 'maxMessageSizeBytes': %d," - " 'maxWriteBatchSize': %d }", - max_wire_version, - max_bson_size, - max_message_size, - max_batch_size); - - BSON_ASSERT (max_wire_version > 0); - mock_server_auto_ismaster (server, response); - - bson_free (response); -} - - -int -should_run_fam_wc (void) -{ - if (!TestSuite_CheckLive ()) { - return 0; - } - if (test_framework_is_replset ()) { - return test_framework_max_wire_version_at_least ( - WIRE_VERSION_FAM_WRITE_CONCERN); - } - return 0; -} - - -static void -test_find_and_modify_bypass (bool bypass) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - mock_server_t *server; - request_t *request; - future_t *future; - bson_error_t error; - bson_t *update; - bson_t doc = BSON_INITIALIZER; - bson_t reply; - mongoc_find_and_modify_opts_t *opts; - - server = mock_server_new (); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT (client); - - collection = - mongoc_client_get_collection (client, "test", "test_find_and_modify"); - - auto_ismaster (server, - WIRE_VERSION_FAM_WRITE_CONCERN, /* max_wire_version */ - 48000000, /* max_message_size */ - 16777216, /* max_bson_size */ - 1000); /* max_write_batch_size */ - - BSON_APPEND_INT32 (&doc, "superduper", 77889); - - update = BCON_NEW ("$set", "{", "superduper", BCON_INT32 (1234), "}"); - - opts = mongoc_find_and_modify_opts_new (); - mongoc_find_and_modify_opts_set_bypass_document_validation (opts, bypass); - BSON_ASSERT ( - bypass == - mongoc_find_and_modify_opts_get_bypass_document_validation (opts)); - mongoc_find_and_modify_opts_set_update (opts, update); - mongoc_find_and_modify_opts_set_flags (opts, - MONGOC_FIND_AND_MODIFY_RETURN_NEW); - - future = future_collection_find_and_modify_with_opts ( - collection, &doc, opts, &reply, &error); - - if (bypass) { - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_NONE, - "{ 'findAndModify' : 'test_find_and_modify', " - "'query' : { 'superduper' : 77889 }," - "'update' : { '$set' : { 'superduper' : 1234 } }," - "'new' : true," - "'bypassDocumentValidation' : true }"); - } else { - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_NONE, - "{ 'findAndModify' : 'test_find_and_modify', " - "'query' : { 'superduper' : 77889 }," - "'update' : { '$set' : { 'superduper' : 1234 } }," - "'new' : true }"); - } - - mock_server_replies_simple (request, "{ 'value' : null, 'ok' : 1 }"); - ASSERT_OR_PRINT (future_get_bool (future), error); - - future_destroy (future); - request_destroy (request); - - mongoc_find_and_modify_opts_destroy (opts); - bson_destroy (&reply); - bson_destroy (update); - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); - bson_destroy (&doc); -} - -static void -test_find_and_modify_bypass_true (void) -{ - test_find_and_modify_bypass (true); -} - -static void -test_find_and_modify_bypass_false (void) -{ - test_find_and_modify_bypass (false); -} - -static void -test_find_and_modify_write_concern (int wire_version) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - mock_server_t *server; - request_t *request; - future_t *future; - bson_error_t error; - bson_t *update; - bson_t doc = BSON_INITIALIZER; - bson_t reply; - mongoc_find_and_modify_opts_t *opts; - mongoc_write_concern_t *write_concern; - - server = mock_server_new (); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - ASSERT (client); - - collection = - mongoc_client_get_collection (client, "test", "test_find_and_modify"); - - auto_ismaster (server, - wire_version, /* max_wire_version */ - 48000000, /* max_message_size */ - 16777216, /* max_bson_size */ - 1000); /* max_write_batch_size */ - - BSON_APPEND_INT32 (&doc, "superduper", 77889); - - update = BCON_NEW ("$set", "{", "superduper", BCON_INT32 (1234), "}"); - - write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_w (write_concern, 42); - opts = mongoc_find_and_modify_opts_new (); - mongoc_collection_set_write_concern (collection, write_concern); - mongoc_find_and_modify_opts_set_update (opts, update); - mongoc_find_and_modify_opts_set_flags (opts, - MONGOC_FIND_AND_MODIFY_RETURN_NEW); - - future = future_collection_find_and_modify_with_opts ( - collection, &doc, opts, &reply, &error); - - if (wire_version >= 4) { - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_NONE, - "{ 'findAndModify' : 'test_find_and_modify', " - "'query' : { 'superduper' : 77889 }," - "'update' : { '$set' : { 'superduper' : 1234 } }," - "'new' : true," - "'writeConcern' : { 'w' : 42 } }"); - } else { - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_NONE, - "{ 'findAndModify' : 'test_find_and_modify', " - "'query' : { 'superduper' : 77889 }," - "'update' : { '$set' : { 'superduper' : 1234 } }," - "'new' : true," - "'writeConcern' : { '$exists': false } }"); - } - - mock_server_replies_simple (request, "{ 'value' : null, 'ok' : 1 }"); - ASSERT_OR_PRINT (future_get_bool (future), error); - - future_destroy (future); - request_destroy (request); - - mongoc_find_and_modify_opts_destroy (opts); - bson_destroy (&reply); - bson_destroy (update); - - mongoc_write_concern_destroy (write_concern); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&doc); - mock_server_destroy (server); -} - -static void -test_find_and_modify_write_concern_wire_32_failure (void *context) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - mongoc_find_and_modify_opts_t *opts; - bson_t reply; - bson_t query = BSON_INITIALIZER; - bson_t *update; - bool success; - mongoc_write_concern_t *wc; - - client = test_framework_client_new (); - collection = get_test_collection (client, "writeFailure"); - wc = mongoc_write_concern_new (); - - mongoc_write_concern_set_w (wc, 42); - mongoc_collection_set_write_concern (collection, wc); - - /* Find Zlatan Ibrahimovic, the striker */ - BSON_APPEND_UTF8 (&query, "firstname", "Zlatan"); - BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic"); - BSON_APPEND_UTF8 (&query, "profession", "Football player"); - BSON_APPEND_INT32 (&query, "age", 34); - BSON_APPEND_INT32 ( - &query, "goals", (16 + 35 + 23 + 57 + 16 + 14 + 28 + 84) + (1 + 6 + 62)); - - /* Add his football position */ - update = BCON_NEW ("$set", "{", "position", BCON_UTF8 ("striker"), "}"); - - opts = mongoc_find_and_modify_opts_new (); - - mongoc_find_and_modify_opts_set_update (opts, update); - - /* Create the document if it didn't exist, and return the updated document */ - mongoc_find_and_modify_opts_set_flags ( - opts, MONGOC_FIND_AND_MODIFY_UPSERT | MONGOC_FIND_AND_MODIFY_RETURN_NEW); - - success = mongoc_collection_find_and_modify_with_opts ( - collection, &query, opts, &reply, &error); - - ASSERT (!success); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_WRITE_CONCERN, 100, "Write Concern error:"); - - bson_destroy (&reply); - bson_destroy (update); - bson_destroy (&query); - mongoc_find_and_modify_opts_destroy (opts); - mongoc_collection_drop (collection, NULL); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_find_and_modify_write_concern_wire_32 (void) -{ - test_find_and_modify_write_concern (4); -} - -static void -test_find_and_modify_write_concern_wire_pre_32 (void) -{ - test_find_and_modify_write_concern (3); -} - -static void -test_find_and_modify (void) -{ - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_error_t error; - bson_iter_t iter; - bson_iter_t citer; - bson_t *update; - bson_t doc = BSON_INITIALIZER; - bson_t tmp; - bson_t reply; - mongoc_find_and_modify_opts_t *opts; - - client = test_framework_client_new (); - ASSERT (client); - - collection = get_test_collection (client, "test_find_and_modify"); - ASSERT (collection); - - BSON_APPEND_INT32 (&doc, "superduper", 77889); - - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (collection, &doc, NULL, NULL, &error), - error); - - update = BCON_NEW ("$set", "{", "superduper", BCON_INT32 (1234), "}"); - - opts = mongoc_find_and_modify_opts_new (); - mongoc_find_and_modify_opts_set_update (opts, update); - mongoc_find_and_modify_opts_get_update (opts, &tmp); - assert_match_bson (&tmp, update, false); - bson_destroy (&tmp); - mongoc_find_and_modify_opts_set_fields (opts, - tmp_bson ("{'superduper': 1}")); - mongoc_find_and_modify_opts_get_fields (opts, &tmp); - assert_match_bson (&tmp, tmp_bson ("{'superduper': 1}"), false); - bson_destroy (&tmp); - mongoc_find_and_modify_opts_set_sort (opts, tmp_bson ("{'superduper': 1}")); - mongoc_find_and_modify_opts_get_sort (opts, &tmp); - assert_match_bson (&tmp, tmp_bson ("{'superduper': 1}"), false); - bson_destroy (&tmp); - mongoc_find_and_modify_opts_set_flags (opts, - MONGOC_FIND_AND_MODIFY_RETURN_NEW); - BSON_ASSERT (MONGOC_FIND_AND_MODIFY_RETURN_NEW == - mongoc_find_and_modify_opts_get_flags (opts)); - - ASSERT_OR_PRINT (mongoc_collection_find_and_modify_with_opts ( - collection, &doc, opts, &reply, &error), - error); - - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "value")); - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - BSON_ASSERT (bson_iter_recurse (&iter, &citer)); - BSON_ASSERT (bson_iter_find (&citer, "superduper")); - BSON_ASSERT (BSON_ITER_HOLDS_INT32 (&citer)); - BSON_ASSERT (bson_iter_int32 (&citer) == 1234); - - BSON_ASSERT (bson_iter_init_find (&iter, &reply, "lastErrorObject")); - BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - BSON_ASSERT (bson_iter_recurse (&iter, &citer)); - BSON_ASSERT (bson_iter_find (&citer, "updatedExisting")); - BSON_ASSERT (BSON_ITER_HOLDS_BOOL (&citer)); - BSON_ASSERT (bson_iter_bool (&citer)); - - bson_destroy (&reply); - bson_destroy (update); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - mongoc_find_and_modify_opts_destroy (opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&doc); -} - - -static void -test_find_and_modify_opts (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - mongoc_find_and_modify_opts_t *opts; - bson_t extra; - future_t *future; - request_t *request; - - server = mock_server_with_autoismaster (WIRE_VERSION_MIN); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - opts = mongoc_find_and_modify_opts_new (); - BSON_ASSERT (mongoc_find_and_modify_opts_set_max_time_ms (opts, 42)); - ASSERT_CMPUINT32 ( - 42, ==, mongoc_find_and_modify_opts_get_max_time_ms (opts)); - BSON_ASSERT ( - mongoc_find_and_modify_opts_append (opts, tmp_bson ("{'foo': 1}"))); - mongoc_find_and_modify_opts_get_extra (opts, &extra); - assert_match_bson (&extra, tmp_bson ("{'foo': 1}"), false); - bson_destroy (&extra); - - future = future_collection_find_and_modify_with_opts ( - collection, tmp_bson ("{}"), opts, NULL, &error); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_NONE, - "{'findAndModify': 'collection', 'maxTimeMS': 42, 'foo': 1}"); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - - future_destroy (future); - mongoc_find_and_modify_opts_destroy (opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_find_and_modify_opts_write_concern (void) -{ - mongoc_write_concern_t *w2; - mongoc_write_concern_t *w3; - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - mongoc_find_and_modify_opts_t *opts; - bson_t extra = BSON_INITIALIZER; - future_t *future; - request_t *request; - - w2 = mongoc_write_concern_new (); - mongoc_write_concern_set_w (w2, 2); - w3 = mongoc_write_concern_new (); - mongoc_write_concern_set_w (w3, 3); - - server = mock_server_with_autoismaster (WIRE_VERSION_FAM_WRITE_CONCERN); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - opts = mongoc_find_and_modify_opts_new (); - mongoc_write_concern_append (w2, &extra); - BSON_ASSERT (mongoc_find_and_modify_opts_append (opts, &extra)); - bson_destroy (&extra); - - future = future_collection_find_and_modify_with_opts ( - collection, tmp_bson ("{}"), opts, NULL, &error); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_NONE, - "{'findAndModify': 'collection', 'writeConcern': {'w': 2}}"); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* opts overrides collection */ - mongoc_collection_set_write_concern (collection, w3); - future = future_collection_find_and_modify_with_opts ( - collection, tmp_bson ("{}"), opts, NULL, &error); - - /* still w: 2 */ - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_NONE, - "{'findAndModify': 'collection', 'writeConcern': {'w': 2}}"); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - mongoc_find_and_modify_opts_destroy (opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); - mongoc_write_concern_destroy (w2); - mongoc_write_concern_destroy (w3); -} - - -static void -test_find_and_modify_collation (int wire) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - mongoc_find_and_modify_opts_t *opts; - future_t *future; - request_t *request; - bson_t *collation; - - server = mock_server_with_autoismaster (wire); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - - collation = BCON_NEW ("collation", - "{", - "locale", - BCON_UTF8 ("en_US"), - "caseFirst", - BCON_UTF8 ("lower"), - "}"); - opts = mongoc_find_and_modify_opts_new (); - BSON_ASSERT (mongoc_find_and_modify_opts_append (opts, collation)); - - if (wire >= WIRE_VERSION_COLLATION) { - future = future_collection_find_and_modify_with_opts ( - collection, tmp_bson ("{}"), opts, NULL, &error); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_NONE, - "{'findAndModify': 'collection'," - " 'collation': { 'locale': 'en_US', 'caseFirst': 'lower'}" - "}"); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - } else { - bool ok = mongoc_collection_find_and_modify_with_opts ( - collection, tmp_bson ("{}"), opts, NULL, &error); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "The selected server does not support collation"); - ASSERT (!ok); - } - - bson_destroy (collation); - mongoc_find_and_modify_opts_destroy (opts); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - - mock_server_destroy (server); -} - -static void -test_find_and_modify_collation_ok (void) -{ - test_find_and_modify_collation (WIRE_VERSION_COLLATION); -} - - -static void -test_find_and_modify_collation_fail (void) -{ - test_find_and_modify_collation (WIRE_VERSION_COLLATION - 1); -} - -void -test_find_and_modify_install (TestSuite *suite) -{ - TestSuite_AddLive ( - suite, "/find_and_modify/find_and_modify", test_find_and_modify); - TestSuite_AddMockServerTest (suite, - "/find_and_modify/find_and_modify/bypass/true", - test_find_and_modify_bypass_true); - TestSuite_AddMockServerTest (suite, - "/find_and_modify/find_and_modify/bypass/false", - test_find_and_modify_bypass_false); - TestSuite_AddMockServerTest ( - suite, - "/find_and_modify/find_and_modify/write_concern", - test_find_and_modify_write_concern_wire_32); - TestSuite_AddMockServerTest ( - suite, - "/find_and_modify/find_and_modify/write_concern_pre_32", - test_find_and_modify_write_concern_wire_pre_32); - TestSuite_AddFull (suite, - "/find_and_modify/find_and_modify/write_concern_failure", - test_find_and_modify_write_concern_wire_32_failure, - NULL, - NULL, - should_run_fam_wc); - TestSuite_AddMockServerTest ( - suite, "/find_and_modify/opts", test_find_and_modify_opts); - TestSuite_AddMockServerTest (suite, - "/find_and_modify/opts/write_concern", - test_find_and_modify_opts_write_concern); - TestSuite_AddMockServerTest (suite, - "/find_and_modify/collation/ok", - test_find_and_modify_collation_ok); - TestSuite_AddMockServerTest (suite, - "/find_and_modify/collation/fail", - test_find_and_modify_collation_fail); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-gridfs-bucket.c b/lib/mongoc/libmongoc/tests/test-mongoc-gridfs-bucket.c deleted file mode 100644 index ac4c10eae71d06eca257ac5e1bd636081e5f640d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-gridfs-bucket.c +++ /dev/null @@ -1,1014 +0,0 @@ -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-gridfs-bucket-private.h" -#include "json-test.h" -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - -void -test_create_bucket (void) -{ - /* Tests creating a bucket with all opts set */ - mongoc_gridfs_bucket_t *gridfs; - mongoc_read_prefs_t *read_prefs; - mongoc_write_concern_t *write_concern; - mongoc_read_concern_t *read_concern; - mongoc_database_t *db; - mongoc_client_t *client; - bson_t *opts; - char *dbname; - - client = test_framework_client_new (); - ASSERT (client); - - dbname = gen_collection_name ("test"); - - db = mongoc_client_get_database (client, dbname); - - bson_free (dbname); - - ASSERT (db); - - opts = bson_new (); - - /* write concern */ - write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_w (write_concern, 1); - mongoc_write_concern_append (write_concern, opts); - - /* read concern */ - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, - MONGOC_READ_CONCERN_LEVEL_LOCAL); - mongoc_read_concern_append (read_concern, opts); - - /* other opts */ - BSON_APPEND_UTF8 (opts, "bucketName", "test-gridfs"); - BSON_APPEND_INT32 (opts, "chunkSizeBytes", 10); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - gridfs = mongoc_gridfs_bucket_new (db, opts, read_prefs, NULL); - - ASSERT (gridfs); - - mongoc_gridfs_bucket_destroy (gridfs); - bson_destroy (opts); - mongoc_write_concern_destroy (write_concern); - mongoc_read_concern_destroy (read_concern); - mongoc_read_prefs_destroy (read_prefs); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -void -test_upload_and_download (void) -{ - mongoc_gridfs_bucket_t *gridfs; - mongoc_stream_t *upload_stream; - mongoc_stream_t *download_stream; - bson_value_t file_id; - mongoc_database_t *db; - mongoc_client_t *client; - bson_t *opts; - /* big enough to hold all of str */ - char buf[100] = {0}; - char *str; - char *dbname; - - str = "This is a test sentence with multiple chunks."; - - client = test_framework_client_new (); - - ASSERT (client); - - dbname = gen_collection_name ("test"); - - db = mongoc_client_get_database (client, dbname); - - bson_free (dbname); - - ASSERT (db); - - opts = bson_new (); - BSON_APPEND_INT32 (opts, "chunkSizeBytes", 10); - - gridfs = mongoc_gridfs_bucket_new (db, opts, NULL, NULL); - - upload_stream = mongoc_gridfs_bucket_open_upload_stream ( - gridfs, "my-file", NULL, &file_id, NULL); - - ASSERT (upload_stream); - - /* write str to gridfs. */ - mongoc_stream_write (upload_stream, (void *) str, strlen (str), 0); - mongoc_stream_destroy (upload_stream); - - /* download str into the buffer from gridfs. */ - download_stream = - mongoc_gridfs_bucket_open_download_stream (gridfs, &file_id, NULL); - mongoc_stream_read (download_stream, buf, 100, 1, 0); - - /* compare. */ - ASSERT (strcmp (buf, str) == 0); - - bson_destroy (opts); - mongoc_stream_destroy (download_stream); - mongoc_gridfs_bucket_destroy (gridfs); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - - -bool -hex_to_bytes (const char *hex_str, - size_t *size /* OUT */, - uint8_t **bytes /* OUT */) -{ - size_t len; - uint8_t *result; - size_t i; - - len = strlen (hex_str); - - ASSERT (bytes); - ASSERT (len % 2 == 0); - - if (len == 0) { - return false; - } - - result = (uint8_t *) bson_malloc0 (len / 2); - - for (i = 0; i < len; i += 2) { - sscanf (hex_str + i, "%2hhx", &result[i / 2]); - } - - *bytes = result; - - if (size) { - *size = (len / 2); - } - - return true; -} - -bson_t * -convert_hex_to_binary (bson_t *doc) -{ - /* PLAN: Recurse to all sub documents and call this function, otherwise, just - * append */ - bson_iter_t iter; - bson_iter_t inner; - bson_t *result; - const char *key; - bson_t *sub_doc; - bson_t *sub_doc_result; - const bson_value_t *value; - - bson_t *hex_doc; - uint8_t *hex_bytes; - size_t hex_len; - const char *str; - bool r; - - result = bson_new (); - - bson_iter_init (&iter, doc); - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - value = bson_iter_value (&iter); - - if (strcmp (key, "data") == 0) { - hex_doc = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - ASSERT (bson_iter_init_find (&inner, hex_doc, "$hex")); - - str = bson_iter_utf8 (&inner, NULL); - r = hex_to_bytes (str, &hex_len, &hex_bytes); - - if (r) { - BSON_APPEND_BINARY ( - result, key, BSON_SUBTYPE_BINARY, hex_bytes, (uint32_t) hex_len); - bson_free (hex_bytes); - } else { - BSON_APPEND_BINARY ( - result, key, BSON_SUBTYPE_BINARY, (const uint8_t *) str, 0); - } - - bson_destroy (hex_doc); - - } else if (value->value_type == BSON_TYPE_DOCUMENT || - value->value_type == BSON_TYPE_ARRAY) { - sub_doc = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - sub_doc_result = convert_hex_to_binary (sub_doc); - bson_destroy (sub_doc); - if (value->value_type == BSON_TYPE_DOCUMENT) { - BSON_APPEND_DOCUMENT (result, key, sub_doc_result); - } else { - BSON_APPEND_ARRAY (result, key, sub_doc_result); - } - bson_destroy (sub_doc_result); - } else { - BSON_APPEND_VALUE (result, key, value); - } - } - - return result; -} - -/* - * Initializes the proper GridFS collections with the provided data - */ -void -setup_gridfs_collections (mongoc_database_t *db, bson_t *data) -{ - mongoc_collection_t *files; - mongoc_collection_t *chunks; - mongoc_collection_t *expected_files; - mongoc_collection_t *expected_chunks; - bson_iter_t iter; - bson_iter_t inner; - bson_t *selector; - bool r; - - files = mongoc_database_get_collection (db, "fs.files"); - chunks = mongoc_database_get_collection (db, "fs.chunks"); - expected_files = mongoc_database_get_collection (db, "expected.files"); - expected_chunks = mongoc_database_get_collection (db, "expected.chunks"); - - selector = bson_new (); - - mongoc_collection_delete_many (files, selector, NULL, NULL, NULL); - mongoc_collection_delete_many (chunks, selector, NULL, NULL, NULL); - mongoc_collection_delete_many (expected_files, selector, NULL, NULL, NULL); - mongoc_collection_delete_many (expected_chunks, selector, NULL, NULL, NULL); - - bson_destroy (selector); - - if (bson_iter_init_find (&iter, data, "files")) { - bson_t *docs = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - bson_iter_init (&inner, docs); - while (bson_iter_next (&inner)) { - bson_t *doc = - bson_new_from_data (bson_iter_value (&inner)->value.v_doc.data, - bson_iter_value (&inner)->value.v_doc.data_len); - r = mongoc_collection_insert_one (files, doc, NULL, NULL, NULL); - ASSERT (r); - r = mongoc_collection_insert_one ( - expected_files, doc, NULL, NULL, NULL); - ASSERT (r); - bson_destroy (doc); - } - - bson_destroy (docs); - } - - if (bson_iter_init_find (&iter, data, "chunks")) { - bson_t *docs = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - bson_iter_init (&inner, docs); - while (bson_iter_next (&inner)) { - bson_t *doc = - bson_new_from_data (bson_iter_value (&inner)->value.v_doc.data, - bson_iter_value (&inner)->value.v_doc.data_len); - bson_t *chunk = convert_hex_to_binary (doc); - r = mongoc_collection_insert_one (chunks, chunk, NULL, NULL, NULL); - ASSERT (r); - r = mongoc_collection_insert_one ( - expected_chunks, chunk, NULL, NULL, NULL); - ASSERT (r); - bson_destroy (doc); - bson_destroy (chunk); - } - - bson_destroy (docs); - } - - mongoc_collection_destroy (files); - mongoc_collection_destroy (chunks); - mongoc_collection_destroy (expected_files); - mongoc_collection_destroy (expected_chunks); -} - -void -gridfs_spec_run_commands (mongoc_database_t *db, bson_t *commands) -{ - bson_iter_t iter; - bson_t *data; - bson_t *command; - bson_t *hex_command; - bool r; - - ASSERT (bson_iter_init_find (&iter, commands, "data")); - data = bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - bson_iter_init (&iter, data); - - while (bson_iter_next (&iter)) { - command = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - hex_command = convert_hex_to_binary (command); - - r = mongoc_database_command_simple (db, hex_command, NULL, NULL, NULL); - ASSERT (r); - bson_destroy (command); - bson_destroy (hex_command); - } - bson_destroy (data); -} - -bson_t * -gridfs_replace_result (bson_t *doc, bson_value_t *replacement) -{ - bson_iter_t iter; - bson_t *result; - const char *key; - bson_t *sub_doc; - bson_t *sub_doc_result; - const bson_value_t *value; - - const char *str; - - result = bson_new (); - - bson_iter_init (&iter, doc); - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - value = bson_iter_value (&iter); - - if (value->value_type == BSON_TYPE_UTF8) { - str = bson_iter_utf8 (&iter, NULL); - - if (strcmp (str, "*result") == 0) { - BSON_APPEND_VALUE (result, key, replacement); - } else if (strcmp (str, "*actual") == 0) { - /* Skip adding this */ - } else { - BSON_APPEND_VALUE (result, key, value); - } - - } else if (value->value_type == BSON_TYPE_DOCUMENT || - value->value_type == BSON_TYPE_ARRAY) { - sub_doc = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - sub_doc_result = gridfs_replace_result (sub_doc, replacement); - bson_destroy (sub_doc); - if (value->value_type == BSON_TYPE_DOCUMENT) { - BSON_APPEND_DOCUMENT (result, key, sub_doc_result); - } else { - BSON_APPEND_ARRAY (result, key, sub_doc_result); - } - bson_destroy (sub_doc_result); - } else { - BSON_APPEND_VALUE (result, key, value); - } - } - - return result; -} - -void -gridfs_compare_collections (mongoc_database_t *db) -{ - mongoc_collection_t *files; - mongoc_collection_t *chunks; - mongoc_collection_t *expected_files; - mongoc_collection_t *expected_chunks; - mongoc_cursor_t *expected_cursor; - mongoc_cursor_t *actual_cursor; - const bson_t *expected_doc; - const bson_t *actual_doc; - bson_iter_t expected_iter; - bson_iter_t actual_iter; - const uint8_t *expected_binary; - const uint8_t *actual_binary; - uint32_t expected_len; - uint32_t actual_len; - bson_t filter; - - files = mongoc_database_get_collection (db, "fs.files"); - chunks = mongoc_database_get_collection (db, "fs.chunks"); - expected_files = mongoc_database_get_collection (db, "expected.files"); - expected_chunks = mongoc_database_get_collection (db, "expected.chunks"); - - bson_init (&filter); - - /* Compare files collections */ - actual_cursor = - mongoc_collection_find_with_opts (files, &filter, NULL, NULL); - expected_cursor = - mongoc_collection_find_with_opts (expected_files, &filter, NULL, NULL); - - while (mongoc_cursor_next (expected_cursor, &expected_doc)) { - ASSERT (mongoc_cursor_next (actual_cursor, &actual_doc)); - - ASSERT (bson_iter_init_find (&actual_iter, actual_doc, "_id")); - ASSERT (bson_iter_init_find (&expected_iter, expected_doc, "_id")); - ASSERT (bson_oid_compare (bson_iter_oid (&actual_iter), - bson_iter_oid (&expected_iter)) == 0); - - ASSERT (bson_iter_init_find (&actual_iter, actual_doc, "length")); - ASSERT (bson_iter_init_find (&expected_iter, expected_doc, "length")); - ASSERT (bson_iter_as_int64 (&actual_iter) == - bson_iter_as_int64 (&expected_iter)); - - ASSERT (bson_iter_init_find (&actual_iter, actual_doc, "chunkSize")); - ASSERT (bson_iter_init_find (&expected_iter, expected_doc, "chunkSize")); - ASSERT (bson_iter_int32 (&actual_iter) == - bson_iter_int32 (&expected_iter)); - - ASSERT (bson_iter_init_find (&actual_iter, actual_doc, "filename")); - ASSERT (bson_iter_init_find (&expected_iter, expected_doc, "filename")); - ASSERT (strcmp (bson_iter_utf8 (&actual_iter, NULL), - bson_iter_utf8 (&expected_iter, NULL)) == 0); - } - - /* Make sure the actual doesn't have extra docs */ - ASSERT (!mongoc_cursor_next (actual_cursor, &actual_doc)); - - mongoc_cursor_destroy (actual_cursor); - mongoc_cursor_destroy (expected_cursor); - - - /* Compare chunks collections */ - actual_cursor = - mongoc_collection_find_with_opts (chunks, &filter, NULL, NULL); - expected_cursor = - mongoc_collection_find_with_opts (expected_chunks, &filter, NULL, NULL); - - - while (mongoc_cursor_next (expected_cursor, &expected_doc)) { - ASSERT (mongoc_cursor_next (actual_cursor, &actual_doc)); - - ASSERT (bson_iter_init_find (&actual_iter, actual_doc, "files_id")); - ASSERT (bson_iter_init_find (&expected_iter, expected_doc, "files_id")); - ASSERT (bson_oid_compare (bson_iter_oid (&actual_iter), - bson_iter_oid (&expected_iter)) == 0); - - ASSERT (bson_iter_init_find (&actual_iter, actual_doc, "n")); - ASSERT (bson_iter_init_find (&expected_iter, expected_doc, "n")); - ASSERT (bson_iter_int32 (&actual_iter) == - bson_iter_int32 (&expected_iter)); - - ASSERT (bson_iter_init_find (&actual_iter, actual_doc, "data")); - ASSERT (bson_iter_init_find (&expected_iter, expected_doc, "data")); - bson_iter_binary (&actual_iter, NULL, &actual_len, &actual_binary); - bson_iter_binary (&expected_iter, NULL, &expected_len, &expected_binary); - ASSERT (actual_len == expected_len); - ASSERT (memcmp (actual_binary, expected_binary, actual_len) == 0); - } - - /* Make sure the actual doesn't have extra docs */ - ASSERT (!mongoc_cursor_next (actual_cursor, &actual_doc)); - - bson_destroy (&filter); - mongoc_cursor_destroy (actual_cursor); - mongoc_cursor_destroy (expected_cursor); - - mongoc_collection_destroy (files); - mongoc_collection_destroy (chunks); - mongoc_collection_destroy (expected_files); - mongoc_collection_destroy (expected_chunks); -} - -void -gridfs_spec_delete_operation (mongoc_database_t *db, - mongoc_gridfs_bucket_t *bucket, - bson_t *act, - bson_t *assert) -{ - bson_iter_t iter; - bson_t *arguments; - const bson_value_t *value; - bool r; - - ASSERT (bson_iter_init_find (&iter, act, "arguments")); - arguments = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - ASSERT (bson_iter_init_find (&iter, arguments, "id")); - value = bson_iter_value (&iter); - - r = mongoc_gridfs_bucket_delete_by_id (bucket, value, NULL); - ASSERT (r != bson_iter_init_find (&iter, assert, "error")); - - if (bson_iter_init_find (&iter, assert, "data")) { - gridfs_spec_run_commands (db, assert); - } - - /* compare collections! */ - gridfs_compare_collections (db); - - bson_destroy (arguments); -} - -void -gridfs_spec_download_operation (mongoc_database_t *db, - mongoc_gridfs_bucket_t *bucket, - bson_t *act, - bson_t *assert) -{ - bson_iter_t iter; - bson_t *arguments; - bson_t *hex_doc; - const bson_value_t *value; - mongoc_stream_t *stream; - char buf[100] = {0}; - uint8_t *hex_bytes; - size_t hex_len; - ssize_t ret; - const char *str; - const char *expected_error; - bson_error_t error; - bool r; - - ASSERT (bson_iter_init_find (&iter, act, "arguments")); - arguments = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - if (bson_iter_init_find (&iter, assert, "error")) { - expected_error = bson_iter_utf8 (&iter, NULL); - } else { - expected_error = ""; - } - - ASSERT (bson_iter_init_find (&iter, arguments, "id")); - value = bson_iter_value (&iter); - - stream = mongoc_gridfs_bucket_open_download_stream (bucket, value, &error); - - if (strcmp (expected_error, "FileNotFound") == 0) { - ASSERT (!stream); - ASSERT (error.code); - bson_destroy (arguments); - return; - } - - ret = mongoc_stream_read (stream, buf, 100, 0, 0); - - if (strcmp (expected_error, "ChunkIsMissing") == 0 || - strcmp (expected_error, "ChunkIsWrongSize") == 0) { - ASSERT (ret < 0); - r = mongoc_gridfs_bucket_stream_error (stream, &error); - ASSERT (r); - ASSERT (error.code); - bson_destroy (arguments); - mongoc_stream_destroy (stream); - return; - } - - mongoc_stream_close (stream); - - ASSERT (bson_iter_init_find (&iter, assert, "result")); - hex_doc = bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - ASSERT (bson_iter_init_find (&iter, hex_doc, "$hex")); - str = bson_iter_utf8 (&iter, NULL); - - r = hex_to_bytes (str, &hex_len, &hex_bytes); - if (r) { - ASSERT (ret == hex_len); - ASSERT (memcmp (buf, hex_bytes, hex_len) == 0); - bson_free (hex_bytes); - } else { - ASSERT (ret == 0); - } - - /* Make sure we don't need to run any commands */ - ASSERT (!bson_iter_init_find (&iter, assert, "data")); - - bson_destroy (hex_doc); - bson_destroy (arguments); - mongoc_stream_destroy (stream); -} - -void -gridfs_spec_download_by_name_operation (mongoc_database_t *db, - mongoc_gridfs_bucket_t *bucket, - bson_t *act, - bson_t *assert) -{ - /* The download_by_name functionality is part of the Advanced API for GridFS - * and the C Driver hasn't implemented the Advanced API yet. This is a - * placeholder to be used when the download_by_name is implemented. */ -} - -void -gridfs_spec_upload_operation (mongoc_database_t *db, - mongoc_gridfs_bucket_t *bucket, - bson_t *act, - bson_t *assert) -{ - bson_iter_t iter; - bson_t *arguments; - const char *filename; - mongoc_stream_t *stream; - uint8_t *hex_bytes; - bson_t *hex_doc; - bson_t *options; - ssize_t bytes_written; - const char *str; - bson_value_t file_id; - bson_t *assert_modified; - size_t hex_len; - bool r; - - ASSERT (bson_iter_init_find (&iter, act, "arguments")); - arguments = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - ASSERT (bson_iter_init_find (&iter, arguments, "filename")); - filename = bson_iter_utf8 (&iter, NULL); - - ASSERT (bson_iter_init_find (&iter, arguments, "source")); - hex_doc = bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - ASSERT (bson_iter_init_find (&iter, hex_doc, "$hex")); - str = bson_iter_utf8 (&iter, NULL); - - r = hex_to_bytes (str, &hex_len, &hex_bytes); - if (!r) { - hex_len = 0; - hex_bytes = bson_malloc0 (1); - } - - ASSERT (bson_iter_init_find (&iter, arguments, "options")); - options = bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - stream = mongoc_gridfs_bucket_open_upload_stream ( - bucket, filename, options, &file_id, NULL); - - ASSERT (stream); - - bytes_written = mongoc_stream_write (stream, hex_bytes, hex_len, 0); - ASSERT (bytes_written == hex_len); - bson_free (hex_bytes); - - mongoc_stream_close (stream); - mongoc_stream_destroy (stream); - - assert_modified = gridfs_replace_result (assert, &file_id); - gridfs_spec_run_commands (db, assert_modified); - gridfs_compare_collections (db); - - bson_destroy (assert_modified); - bson_destroy (options); - bson_destroy (hex_doc); - bson_destroy (arguments); -} -void -run_gridfs_spec_test (mongoc_database_t *db, - mongoc_gridfs_bucket_t *bucket, - bson_t *test) -{ - bson_iter_t iter; - bson_iter_t inner; - bson_t *act; - bson_t *assert; - bson_t *arrange; - const char *operation; - - ASSERT (bson_iter_init_find (&iter, test, "act")); - act = bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - ASSERT (bson_iter_init_find (&iter, test, "assert")); - assert = bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - if (bson_iter_init_find (&iter, test, "arrange")) { - arrange = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - gridfs_spec_run_commands (db, arrange); - bson_destroy (arrange); - } - - ASSERT (bson_iter_init_find (&inner, act, "operation")); - operation = bson_iter_utf8 (&inner, NULL); - - if (strcmp (operation, "delete") == 0) { - gridfs_spec_delete_operation (db, bucket, act, assert); - } else if (strcmp (operation, "download") == 0) { - gridfs_spec_download_operation (db, bucket, act, assert); - } else if (strcmp (operation, "download_by_name") == 0) { - gridfs_spec_download_by_name_operation (db, bucket, act, assert); - } else if (strcmp (operation, "upload") == 0) { - gridfs_spec_upload_operation (db, bucket, act, assert); - } else { - /* Shouldn't happen. */ - ASSERT (false); - } - - bson_destroy (act); - bson_destroy (assert); -} - -static void -test_gridfs_cb (bson_t *scenario) -{ - mongoc_gridfs_bucket_t *gridfs; - mongoc_database_t *db; - mongoc_client_t *client; - bson_iter_t iter; - bson_iter_t inner; - char *dbname; - bson_t *data; - bson_t *tests; - bson_t *test; - - /* Make a gridfs on generated db */ - dbname = gen_collection_name ("test"); - client = test_framework_client_new (); - db = mongoc_client_get_database (client, dbname); - gridfs = mongoc_gridfs_bucket_new (db, NULL, NULL, NULL); - - /* Insert the data */ - if (bson_iter_init_find (&iter, scenario, "data")) { - data = bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - setup_gridfs_collections (db, data); - bson_destroy (data); - } - - /* Run the tests */ - if (bson_iter_init_find (&iter, scenario, "tests")) { - tests = - bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data, - bson_iter_value (&iter)->value.v_doc.data_len); - - bson_iter_init (&inner, tests); - while (bson_iter_next (&inner)) { - test = - bson_new_from_data (bson_iter_value (&inner)->value.v_doc.data, - bson_iter_value (&inner)->value.v_doc.data_len); - run_gridfs_spec_test (db, gridfs, test); - bson_destroy (test); - } - - bson_destroy (tests); - } - - bson_free (dbname); - mongoc_gridfs_bucket_destroy (gridfs); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - test_framework_resolve_path (JSON_DIR "/gridfs", resolved); - install_json_test_suite (suite, resolved, &test_gridfs_cb); -} - -static void -test_upload_error (void *ctx) -{ - mongoc_client_t *client; - mongoc_uri_t *uri; - mongoc_database_t *db; - mongoc_gridfs_bucket_t *gridfs; - mongoc_stream_t *source; - bson_error_t error = {0}; - bool r; - - client = test_framework_client_new (); - db = mongoc_client_get_database (client, "test"); - gridfs = mongoc_gridfs_bucket_new (db, NULL, NULL, NULL); - source = mongoc_stream_file_new_for_path ( - BSON_BINARY_DIR "/test1.bson", O_RDONLY, 0); - BSON_ASSERT (source); - r = mongoc_gridfs_bucket_upload_from_stream ( - gridfs, "test1", source, NULL /* opts */, NULL /* file id */, &error); - ASSERT_OR_PRINT (r, error); - - /* create a read-only user */ - (void) mongoc_database_remove_user (db, "fake_user", NULL); - r = mongoc_database_add_user ( - db, "fake_user", "password", tmp_bson ("{'0': 'read'}"), NULL, &error); - ASSERT_OR_PRINT (r, error); - - mongoc_stream_close (source); - mongoc_stream_destroy (source); - mongoc_gridfs_bucket_destroy (gridfs); - mongoc_database_destroy (db); - mongoc_client_destroy (client); - - /* initialize gridfs with a root user. */ - uri = test_framework_get_uri (); - mongoc_uri_set_username (uri, "fake_user"); - mongoc_uri_set_password (uri, "password"); - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - mongoc_uri_destroy (uri); - - source = mongoc_stream_file_new_for_path ( - BSON_BINARY_DIR "/test1.bson", O_RDONLY, 0); - BSON_ASSERT (source); - db = mongoc_client_get_database (client, "test"); - gridfs = mongoc_gridfs_bucket_new (db, NULL, NULL, NULL); - mongoc_gridfs_bucket_upload_from_stream ( - gridfs, "test1", source, NULL /* opts */, NULL /* file id */, &error); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, ""); - - mongoc_stream_close (source); - mongoc_stream_destroy (source); - mongoc_gridfs_bucket_destroy (gridfs); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -static void -test_find_w_session (void *ctx) -{ - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_gridfs_bucket_t *gridfs; - mongoc_cursor_t *cursor; - bson_error_t error = {0}; - bson_t opts; - mongoc_client_session_t *session; - bool r; - - client = test_framework_client_new (); - db = mongoc_client_get_database (client, "test"); - gridfs = mongoc_gridfs_bucket_new (db, NULL, NULL, NULL); - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - bson_init (&opts); - r = mongoc_client_session_append (session, &opts, &error); - ASSERT_OR_PRINT (r, error); - cursor = mongoc_gridfs_bucket_find (gridfs, tmp_bson ("{}"), &opts); - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_CURSOR, - MONGOC_ERROR_CURSOR_INVALID_CURSOR, - "Cannot pass sessionId as an option"); - bson_destroy (&opts); - mongoc_cursor_destroy (cursor); - mongoc_gridfs_bucket_destroy (gridfs); - mongoc_client_session_destroy (session); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -void -test_gridfs_bucket_opts (void) -{ - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_gridfs_bucket_t *gridfs; - bson_error_t error; - mongoc_read_concern_t *rc; - mongoc_write_concern_t *wc; - bson_t *opts; - char *bucket_name; - - client = test_framework_client_new (); - db = mongoc_client_get_database (client, "test"); - - /* check defaults. */ - gridfs = mongoc_gridfs_bucket_new (db, NULL, NULL, &error); - ASSERT_OR_PRINT (gridfs, error); - ASSERT_CMPSTR (gridfs->bucket_name, "fs"); - ASSERT_CMPINT32 (gridfs->chunk_size, ==, 255 * 1024); - BSON_ASSERT (!mongoc_read_concern_get_level ( - mongoc_collection_get_read_concern (gridfs->chunks))); - BSON_ASSERT (!mongoc_read_concern_get_level ( - mongoc_collection_get_read_concern (gridfs->files))); - ASSERT_CMPINT (mongoc_write_concern_get_w ( - mongoc_collection_get_write_concern (gridfs->chunks)), - ==, - MONGOC_WRITE_CONCERN_W_DEFAULT); - ASSERT_CMPINT (mongoc_write_concern_get_w ( - mongoc_collection_get_write_concern (gridfs->files)), - ==, - MONGOC_WRITE_CONCERN_W_DEFAULT); - mongoc_gridfs_bucket_destroy (gridfs); - - /* check out-of-range chunk sizes */ - gridfs = mongoc_gridfs_bucket_new ( - db, tmp_bson ("{'chunkSizeBytes': -1}"), NULL, &error); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "should be greater than 0"); - mongoc_gridfs_bucket_destroy (gridfs); - - gridfs = mongoc_gridfs_bucket_new ( - db, tmp_bson ("{'chunkSizeBytes': 2147483648}"), NULL, &error); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "out of range"); - mongoc_gridfs_bucket_destroy (gridfs); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_AVAILABLE); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); - - opts = BCON_NEW ("bucketName", "abc", "chunkSizeBytes", BCON_INT32 (123)); - BSON_ASSERT (mongoc_read_concern_append (rc, opts)); - BSON_ASSERT (mongoc_write_concern_append (wc, opts)); - gridfs = mongoc_gridfs_bucket_new (db, opts, NULL, &error); - ASSERT_OR_PRINT (gridfs, error); - ASSERT_CMPSTR (gridfs->bucket_name, "abc"); - ASSERT_CMPINT32 (gridfs->chunk_size, ==, 123); - ASSERT_CMPSTR (mongoc_read_concern_get_level ( - mongoc_collection_get_read_concern (gridfs->chunks)), - MONGOC_READ_CONCERN_LEVEL_AVAILABLE); - ASSERT_CMPSTR (mongoc_read_concern_get_level ( - mongoc_collection_get_read_concern (gridfs->files)), - MONGOC_READ_CONCERN_LEVEL_AVAILABLE); - ASSERT_CMPINT (mongoc_write_concern_get_w ( - mongoc_collection_get_write_concern (gridfs->chunks)), - ==, - MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); - ASSERT_CMPINT (mongoc_write_concern_get_w ( - mongoc_collection_get_write_concern (gridfs->files)), - ==, - MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); - mongoc_read_concern_destroy (rc); - mongoc_write_concern_destroy (wc); - bson_destroy (opts); - mongoc_gridfs_bucket_destroy (gridfs); - - /* check validation of long bucket names */ - bucket_name = bson_malloc0 (128); - memset (bucket_name, 'a', 128 - strlen ("chunks")); - opts = BCON_NEW ("bucketName", bucket_name); - gridfs = mongoc_gridfs_bucket_new (db, opts, NULL, &error); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "must have fewer"); - bson_destroy (opts); - mongoc_gridfs_bucket_destroy (gridfs); - - /* one character shorter should be okay though. */ - *(bucket_name + ((int) (128 - strlen ("chunks") - 1))) = '\0'; - opts = BCON_NEW ("bucketName", bucket_name); - gridfs = mongoc_gridfs_bucket_new (db, opts, NULL, &error); - ASSERT_OR_PRINT (gridfs, error); - bson_destroy (opts); - mongoc_gridfs_bucket_destroy (gridfs); - - bson_free (bucket_name); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -void -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/find_w_session", - test_find_w_session, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto); - TestSuite_AddLive (suite, "/gridfs/options", test_gridfs_bucket_opts); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-gridfs-file-page.c b/lib/mongoc/libmongoc/tests/test-mongoc-gridfs-file-page.c deleted file mode 100644 index fbc3ba4ef920956752bbb11120d38472952d6d93..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-gridfs-file-page.c +++ /dev/null @@ -1,225 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-gridfs-file-page-private.h> - -#include "TestSuite.h" - -static void -test_create (void) -{ - uint8_t fox[] = "the quick brown fox jumped over the laxy dog"; - uint32_t len = sizeof fox; - - mongoc_gridfs_file_page_t *page; - - page = _mongoc_gridfs_file_page_new (fox, len, 4096); - - ASSERT (page); - - _mongoc_gridfs_file_page_destroy (page); -} - - -static void -test_is_dirty (void) -{ - uint8_t buf[] = "abcde"; - uint32_t len = sizeof buf; - int32_t r; - - mongoc_gridfs_file_page_t *page; - - page = _mongoc_gridfs_file_page_new (buf, len, 10); - ASSERT (page); - - r = _mongoc_gridfs_file_page_is_dirty (page); - ASSERT (!r); - - r = _mongoc_gridfs_file_page_write (page, "foo", 3); - ASSERT (r == 3); - - r = _mongoc_gridfs_file_page_is_dirty (page); - ASSERT (r); - - _mongoc_gridfs_file_page_destroy (page); -} - - -static void -test_get_data (void) -{ - uint8_t buf[] = "abcde"; - uint32_t len = sizeof buf; - const uint8_t *ptr; - int32_t r; - - mongoc_gridfs_file_page_t *page; - - page = _mongoc_gridfs_file_page_new (buf, len, 10); - ASSERT (page); - - ptr = _mongoc_gridfs_file_page_get_data (page); - ASSERT (ptr == buf); - - r = _mongoc_gridfs_file_page_write (page, "foo", 3); - ASSERT (r == 3); - - ptr = _mongoc_gridfs_file_page_get_data (page); - ASSERT (ptr != buf); - - _mongoc_gridfs_file_page_destroy (page); -} - - -static void -test_get_len (void) -{ - uint8_t buf[] = "abcde"; - uint32_t len = sizeof buf; - int32_t r; - - mongoc_gridfs_file_page_t *page; - - page = _mongoc_gridfs_file_page_new (buf, len, 10); - ASSERT (page); - - r = _mongoc_gridfs_file_page_get_len (page); - ASSERT (r == 6); - - _mongoc_gridfs_file_page_destroy (page); -} - - -static void -test_read (void) -{ - uint8_t fox[] = "the quick brown fox jumped over the laxy dog"; - uint32_t len = sizeof fox; - int32_t r; - char buf[100]; - - mongoc_gridfs_file_page_t *page; - - page = _mongoc_gridfs_file_page_new (fox, len, 4096); - - ASSERT (page); - - r = _mongoc_gridfs_file_page_read (page, buf, 3); - ASSERT (r == 3); - ASSERT (memcmp ("the", buf, 3) == 0); - ASSERT (page->offset == 3); - - r = _mongoc_gridfs_file_page_read (page, buf, 50); - ASSERT (r == len - 3); - ASSERT (memcmp (fox + 3, buf, len - 3) == 0); - - _mongoc_gridfs_file_page_destroy (page); -} - - -static void -test_seek (void) -{ - uint8_t fox[] = "the quick brown fox jumped over the laxy dog"; - uint32_t len = sizeof fox; - int32_t r; - - mongoc_gridfs_file_page_t *page; - - page = _mongoc_gridfs_file_page_new (fox, len, 4096); - - ASSERT (page); - - r = _mongoc_gridfs_file_page_seek (page, 4); - ASSERT (r); - ASSERT (page->offset == 4); - - r = _mongoc_gridfs_file_page_tell (page); - ASSERT (r == 4); - - _mongoc_gridfs_file_page_destroy (page); -} - - -static void -test_write (void) -{ - uint8_t buf[] = "abcde"; - uint32_t len = sizeof buf; - int32_t r; - - mongoc_gridfs_file_page_t *page; - - page = _mongoc_gridfs_file_page_new (buf, len, 10); - - ASSERT (page); - ASSERT (page->len == len); - ASSERT (!page->buf); - - r = _mongoc_gridfs_file_page_write (page, "1", 1); - ASSERT (r == 1); - ASSERT (page->buf); - ASSERT (memcmp (page->buf, "1bcde", len) == 0); - ASSERT (page->offset == 1); - ASSERT (page->len == len); - - r = _mongoc_gridfs_file_page_write (page, "234567", 6); - ASSERT (r == 6); - ASSERT (memcmp (page->buf, "1234567", 7) == 0); - ASSERT (page->offset == 7); - ASSERT (page->len == 7); - - r = _mongoc_gridfs_file_page_write (page, "8910", 4); - ASSERT (r == 3); - ASSERT (memcmp (page->buf, "1234567891", 10) == 0); - ASSERT (page->offset == 10); - ASSERT (page->len == 10); - - r = _mongoc_gridfs_file_page_write (page, "foo", 3); - ASSERT (r == 0); - - _mongoc_gridfs_file_page_destroy (page); -} - - -static void -test_memset0 (void) -{ - uint8_t buf[] = "wxyz"; - uint32_t len = sizeof buf; - mongoc_gridfs_file_page_t *page; - - page = _mongoc_gridfs_file_page_new (buf, len, 5); - - ASSERT (page); - ASSERT (page->len == len); - ASSERT (!page->buf); - - ASSERT_CMPUINT32 (1, ==, _mongoc_gridfs_file_page_memset0 (page, 1)); - ASSERT (page->buf); - ASSERT (memcmp (page->buf, "\0xyz", 4) == 0); - ASSERT (page->offset == 1); - - ASSERT_CMPUINT32 (4, ==, _mongoc_gridfs_file_page_memset0 (page, 10)); - ASSERT (page->buf); - ASSERT (memcmp (page->buf, "\0\0\0\0\0", 5) == 0); - ASSERT (page->offset == 5); - - /* file position is already at the end */ - ASSERT_CMPUINT32 (0, ==, _mongoc_gridfs_file_page_memset0 (page, 10)); - - _mongoc_gridfs_file_page_destroy (page); -} - - -void -test_gridfs_file_page_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/gridfs_old/File/Page/create", test_create); - TestSuite_Add (suite, "/gridfs_old/File/Page/get_data", test_get_data); - TestSuite_Add (suite, "/gridfs_old/File/Page/get_len", test_get_len); - TestSuite_Add (suite, "/gridfs_old/File/Page/is_dirty", test_is_dirty); - TestSuite_Add (suite, "/gridfs_old/File/Page/read", test_read); - TestSuite_Add (suite, "/gridfs_old/File/Page/seek", test_seek); - TestSuite_Add (suite, "/gridfs_old/File/Page/write", test_write); - TestSuite_Add (suite, "/gridfs_old/File/Page/memset0", test_memset0); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-gridfs.c b/lib/mongoc/libmongoc/tests/test-mongoc-gridfs.c deleted file mode 100644 index 104dbdb401574a6be7dbb8553a31b9fc733bcbb4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-gridfs.c +++ /dev/null @@ -1,1521 +0,0 @@ -#include <mongoc/mongoc.h> -#define MONGOC_INSIDE -#include <mongoc/mongoc-gridfs-file-private.h> -#include <mongoc/mongoc-client-private.h> -#include <mongoc/mongoc-gridfs-private.h> - -#undef MONGOC_INSIDE - -#include "test-libmongoc.h" -#include "TestSuite.h" -#include "test-conveniences.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" - - -static mongoc_gridfs_t * -get_test_gridfs (mongoc_client_t *client, const char *name, bson_error_t *error) -{ - char *gen; - char n[48]; - mongoc_database_t *db; - - gen = gen_collection_name ("fs"); - bson_snprintf (n, sizeof n, "%s_%s", gen, name); - bson_free (gen); - - db = mongoc_client_get_database (client, "test"); - mongoc_database_drop (db, NULL); - mongoc_database_destroy (db); - - return mongoc_client_get_gridfs (client, "test", NULL, error); -} - - -bool -drop_collections (mongoc_gridfs_t *gridfs, bson_error_t *error) -{ - return (mongoc_collection_drop (mongoc_gridfs_get_files (gridfs), error) && - mongoc_collection_drop (mongoc_gridfs_get_chunks (gridfs), error)); -} - - -static void -_check_index (mongoc_collection_t *collection, const char *index_json) -{ - mongoc_cursor_t *cursor; - bson_error_t error = {0}; - const bson_t *info; - const char *index_name; - bson_t index_key; - int n; - - cursor = mongoc_collection_find_indexes (collection, &error); - ASSERT_OR_PRINT (0 == error.code, error); - - n = 0; - - while (mongoc_cursor_next (cursor, &info)) { - index_name = bson_lookup_utf8 (info, "name"); - - /* if this is NOT the "_id" index */ - if (strcmp (index_name, "_id_")) { - bson_lookup_doc (info, "key", &index_key); - ASSERT_MATCH (&index_key, index_json); - } - - n++; - } - - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - /* _id index plus the expected index */ - ASSERT_CMPINT (n, ==, 2); - - mongoc_cursor_destroy (cursor); -} - - -static mongoc_gridfs_t * -_get_gridfs (mock_server_t *server, mongoc_client_t *client) -{ - future_t *future; - bson_error_t error; - request_t *request; - mongoc_gridfs_t *gridfs; - - /* gridfs ensures two indexes */ - future = future_client_get_gridfs (client, "db", NULL, &error); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, "{'createIndexes': 'fs.chunks'}"); - - mock_server_replies_ok_and_destroys (request); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, "{'createIndexes': 'fs.files'}"); - - mock_server_replies_ok_and_destroys (request); - - gridfs = future_get_mongoc_gridfs_ptr (future); - ASSERT (gridfs); - - future_destroy (future); - - return gridfs; -} - - -static void -test_create (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_client_t *client; - bson_error_t error; - mongoc_collection_t *files; - mongoc_collection_t *chunks; - - client = test_framework_client_new (); - ASSERT (client); - - files = mongoc_client_get_collection (client, "test", "foo.files"); - chunks = mongoc_client_get_collection (client, "test", "foo.chunks"); - mongoc_collection_drop (files, NULL); - mongoc_collection_drop (chunks, NULL); - - ASSERT_OR_PRINT ( - (gridfs = mongoc_client_get_gridfs (client, "test", "foo", &error)), - error); - - file = mongoc_gridfs_create_file (gridfs, NULL); - - _check_index (files, "{'filename': 1, 'uploadDate': 1}"); - _check_index (chunks, "{'files_id': 1, 'n': 1}"); - - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - - mongoc_collection_destroy (chunks); - mongoc_collection_destroy (files); - mongoc_client_destroy (client); -} - - -static void -test_remove (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_gridfs_file_opt_t opts = {0}; - mongoc_client_t *client; - bson_error_t error; - char name[32]; - - client = test_framework_client_new (); - ASSERT (client); - - ASSERT_OR_PRINT ( - gridfs = mongoc_client_get_gridfs (client, "test", "foo", &error), error); - - mongoc_gridfs_drop (gridfs, &error); - - bson_snprintf (name, sizeof name, "test-remove.%u", rand ()); - opts.filename = name; - - file = mongoc_gridfs_create_file (gridfs, &opts); - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - - ASSERT_OR_PRINT (mongoc_gridfs_file_remove (file, &error), error); - - mongoc_gridfs_file_destroy (file); - - file = mongoc_gridfs_find_one_by_filename (gridfs, name, &error); - ASSERT (!file); - - /* ensure "error" is cleared if we successfully find no file */ - ASSERT_CMPINT (error.domain, ==, 0); - ASSERT_CMPINT (error.code, ==, 0); - ASSERT_CMPSTR (error.message, ""); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - - mongoc_client_destroy (client); -} - - -static void -prep_files (mongoc_gridfs_t *gridfs) -{ - mongoc_gridfs_file_t *file; - mongoc_gridfs_file_opt_t opt = {0}; - char buf[100]; - int i = 0; - - for (i = 0; i < 3; i++) { - bson_snprintf (buf, sizeof buf, "file.%d", i); - opt.filename = buf; - file = mongoc_gridfs_create_file (gridfs, &opt); - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - mongoc_gridfs_file_destroy (file); - } -} - - -static void -test_list (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_client_t *client; - bson_error_t error; - mongoc_gridfs_file_list_t *list; - bson_t query, child; - char buf[100]; - int i = 0; - - client = test_framework_client_new (); - ASSERT (client); - - ASSERT_OR_PRINT (gridfs = get_test_gridfs (client, "list", &error), error); - - prep_files (gridfs); - - bson_init (&query); - bson_append_document_begin (&query, "$orderby", -1, &child); - bson_append_int32 (&child, "filename", -1, 1); - bson_append_document_end (&query, &child); - bson_append_document_begin (&query, "$query", -1, &child); - bson_append_document_end (&query, &child); - - list = mongoc_gridfs_find (gridfs, &query); - - bson_destroy (&query); - - i = 0; - while ((file = mongoc_gridfs_file_list_next (list))) { - bson_snprintf (buf, sizeof buf, "file.%d", i++); - - ASSERT_CMPINT ( - strcmp (mongoc_gridfs_file_get_filename (file), buf), ==, 0); - - mongoc_gridfs_file_destroy (file); - } - ASSERT_CMPINT (i, ==, 3); - mongoc_gridfs_file_list_destroy (list); - - bson_init (&query); - bson_append_utf8 (&query, "filename", -1, "file.1", -1); - ASSERT_OR_PRINT (file = mongoc_gridfs_find_one (gridfs, &query, &error), - error); - bson_destroy (&query); - - ASSERT_CMPINT ( - strcmp (mongoc_gridfs_file_get_filename (file), "file.1"), ==, 0); - mongoc_gridfs_file_destroy (file); - - ASSERT_OR_PRINT ( - file = mongoc_gridfs_find_one_by_filename (gridfs, "file.1", &error), - error); - - ASSERT_CMPINT ( - strcmp (mongoc_gridfs_file_get_filename (file), "file.1"), ==, 0); - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - - mongoc_client_destroy (client); -} - -static void -test_find_with_opts (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_client_t *client; - bson_error_t error; - mongoc_gridfs_file_list_t *list; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - gridfs = get_test_gridfs (client, "test_find_with_opts", &error); - ASSERT_OR_PRINT (gridfs, error); - - prep_files (gridfs); - - list = mongoc_gridfs_find_with_opts ( - gridfs, - tmp_bson ("{'filename': {'$ne': 'file.1'}}"), - tmp_bson ("{'sort': {'filename': -1}}")); - - file = mongoc_gridfs_file_list_next (list); - ASSERT (file); - ASSERT_CMPSTR ("file.2", mongoc_gridfs_file_get_filename (file)); - mongoc_gridfs_file_destroy (file); - - file = mongoc_gridfs_file_list_next (list); - ASSERT (file); - ASSERT_CMPSTR ("file.0", mongoc_gridfs_file_get_filename (file)); - mongoc_gridfs_file_destroy (file); - - file = mongoc_gridfs_file_list_next (list); - ASSERT (!file); /* done */ - ASSERT (!mongoc_gridfs_file_list_error (list, &error)); - mongoc_gridfs_file_list_destroy (list); - - file = mongoc_gridfs_find_one_with_opts ( - gridfs, tmp_bson (NULL), tmp_bson ("{'sort': {'filename': -1}}"), &error); - - ASSERT_OR_PRINT (file, error); - /* file.2 is first, according to sort order */ - ASSERT_CMPSTR ("file.2", mongoc_gridfs_file_get_filename (file)); - mongoc_gridfs_file_destroy (file); - - file = mongoc_gridfs_find_one_with_opts ( - gridfs, tmp_bson ("{'x': {'$bad_operator': 1}}"), NULL, &error); - - ASSERT (!file); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER); - - /* ensure "error" is cleared if we successfully find no file */ - file = mongoc_gridfs_find_one_with_opts ( - gridfs, tmp_bson ("{'x': 'doesntexist'}"), NULL, &error); - - ASSERT (!file); - ASSERT_CMPINT (error.domain, ==, 0); - ASSERT_CMPINT (error.code, ==, 0); - ASSERT_CMPSTR (error.message, ""); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -/* mongoc_gridfs_find_one_with_opts uses limit 1, no matter what's in "opts" */ -static void -test_find_one_with_opts_limit (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - bson_error_t error; - future_t *future; - request_t *request; - - server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - mongoc_client_set_error_api (client, 2); - - gridfs = _get_gridfs (server, client); - - future = - future_gridfs_find_one_with_opts (gridfs, tmp_bson ("{}"), NULL, &error); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'fs.files', 'filter': {}, 'limit': 1}"); - - mock_server_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK, - 0 /* cursor_id */, - 1 /* num returned */, - "db.fs.files", - "{'_id': 1, 'length': 1, 'chunkSize': 1}", - true /* is_command */); - - file = future_get_mongoc_gridfs_file_ptr (future); - ASSERT (file); - - mongoc_gridfs_file_destroy (file); - future_destroy (future); - request_destroy (request); - - future = future_gridfs_find_one_with_opts ( - gridfs, tmp_bson ("{}"), tmp_bson ("{'limit': 2}"), &error); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'fs.files', 'filter': {}, 'limit': 1}"); - - mock_server_replies_to_find (request, - MONGOC_QUERY_SLAVE_OK, - 0 /* cursor_id */, - 1 /* num returned */, - "db.fs.files", - "{'_id': 1, 'length': 1, 'chunkSize': 1}", - true /* is_command */); - - file = future_get_mongoc_gridfs_file_ptr (future); - ASSERT (file); - - mongoc_gridfs_file_destroy (file); - future_destroy (future); - request_destroy (request); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_properties (void) -{ - mongoc_client_t *client; - mongoc_gridfs_t *gridfs; - bson_error_t error; - bson_t *doc_in; - mongoc_gridfs_file_t *file; - mongoc_gridfs_file_list_t *list; - bson_t query = BSON_INITIALIZER; - const bson_value_t *file_id; - const char *alias0, *alias1; - - client = test_framework_client_new (); - - ASSERT_OR_PRINT (gridfs = get_test_gridfs (client, "list", &error), error); - - mongoc_gridfs_drop (gridfs, &error); - - /* the C Driver sets _id to an ObjectId, but other drivers can do anything */ - doc_in = BCON_NEW ("_id", - BCON_INT32 (1), - "md5", - BCON_UTF8 ("md5"), - "filename", - BCON_UTF8 ("filename"), - "contentType", - BCON_UTF8 ("content_type"), - "aliases", - "[", - BCON_UTF8 ("alias0"), - BCON_UTF8 ("alias1"), - "]", - "metadata", - "{", - "key", - BCON_UTF8 ("value"), - "}", - "chunkSize", - BCON_INT32 (100)); - - ASSERT (mongoc_collection_insert_one ( - mongoc_gridfs_get_files (gridfs), doc_in, NULL, NULL, NULL)); - - list = mongoc_gridfs_find (gridfs, &query); - file = mongoc_gridfs_file_list_next (list); - file_id = mongoc_gridfs_file_get_id (file); - ASSERT (file_id); - ASSERT_CMPINT (BSON_TYPE_INT32, ==, file_id->value_type); - ASSERT_CMPINT (1, ==, file_id->value.v_int32); - ASSERT_CMPSTR ("md5", mongoc_gridfs_file_get_md5 (file)); - ASSERT_CMPSTR ("filename", mongoc_gridfs_file_get_filename (file)); - ASSERT_CMPSTR ("content_type", mongoc_gridfs_file_get_content_type (file)); - ASSERT (BCON_EXTRACT ((bson_t *) mongoc_gridfs_file_get_aliases (file), - "0", - BCONE_UTF8 (alias0), - "1", - BCONE_UTF8 (alias1))); - - ASSERT_CMPSTR ("alias0", alias0); - ASSERT_CMPSTR ("alias1", alias1); - - drop_collections (gridfs, &error); - mongoc_gridfs_file_destroy (file); - mongoc_gridfs_file_list_destroy (list); - bson_destroy (doc_in); - bson_destroy (&query); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -static void -test_create_from_stream (void) -{ - int64_t start; - int64_t now; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - bson_t *filter; - mongoc_gridfs_file_t *file2; - mongoc_stream_t *stream; - mongoc_client_t *client; - bson_error_t error; - - client = test_framework_client_new (); - ASSERT (client); - - ASSERT_OR_PRINT ((gridfs = get_test_gridfs (client, "from_stream", &error)), - error); - - mongoc_gridfs_drop (gridfs, &error); - - start = ((int64_t) time (NULL)) * 1000; - stream = - mongoc_stream_file_new_for_path (BINARY_DIR "/gridfs.dat", O_RDONLY, 0); - ASSERT_OR_PRINT_ERRNO (stream, errno); - ASSERT (stream); - - file = mongoc_gridfs_create_file_from_stream (gridfs, stream, NULL); - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - - now = ((int64_t) time (NULL)) * 1000; - - filter = tmp_bson (NULL); - BSON_APPEND_VALUE (filter, "_id", mongoc_gridfs_file_get_id (file)); - file2 = mongoc_gridfs_find_one_with_opts (gridfs, filter, NULL, &error); - ASSERT_OR_PRINT (file2, error); - ASSERT_CMPINT64 (start, <=, mongoc_gridfs_file_get_upload_date (file2)); - ASSERT_CMPINT64 (now, >=, mongoc_gridfs_file_get_upload_date (file2)); - - mongoc_gridfs_file_destroy (file2); - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -static void -test_seek (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_stream_t *stream; - mongoc_client_t *client; - bson_error_t error; - - client = test_framework_client_new (); - - ASSERT_OR_PRINT (gridfs = get_test_gridfs (client, "seek", &error), error); - - mongoc_gridfs_drop (gridfs, &error); - - stream = mongoc_stream_file_new_for_path ( - BINARY_DIR "/gridfs-large.dat", O_RDONLY, 0); - - file = mongoc_gridfs_create_file_from_stream (gridfs, stream, NULL); - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_SET), ==, 0); - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file), ==, (uint64_t) 0); - - ASSERT_CMPINT ( - mongoc_gridfs_file_seek (file, file->chunk_size + 1, SEEK_CUR), ==, 0); - ASSERT_CMPINT64 ( - mongoc_gridfs_file_tell (file), ==, (uint64_t) (file->chunk_size + 1)); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_END), ==, 0); - ASSERT_CMPINT64 ( - mongoc_gridfs_file_tell (file), ==, mongoc_gridfs_file_get_length (file)); - - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - - mongoc_client_destroy (client); -} - - -static void -test_read (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_stream_t *stream; - mongoc_client_t *client; - bson_error_t error; - ssize_t r; - char buf[10], buf2[10]; - mongoc_iovec_t iov[2]; - int previous_errno; - ssize_t twenty = 20L; - - iov[0].iov_base = buf; - iov[0].iov_len = 10; - - iov[1].iov_base = buf2; - iov[1].iov_len = 10; - - client = test_framework_client_new (); - ASSERT (client); - - ASSERT_OR_PRINT (gridfs = get_test_gridfs (client, "read", &error), error); - - mongoc_gridfs_drop (gridfs, &error); - - stream = mongoc_stream_file_new_for_path ( - BINARY_DIR "/gridfs-large.dat", O_RDONLY, 0); - - file = mongoc_gridfs_create_file_from_stream (gridfs, stream, NULL); - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - - r = mongoc_gridfs_file_readv (file, iov, 2, 20, 0); - ASSERT_CMPSSIZE_T (r, ==, twenty); - ASSERT_MEMCMP (iov[0].iov_base, "Bacon ipsu", 10); - ASSERT_MEMCMP (iov[1].iov_base, "m dolor si", 10); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 1, SEEK_SET), ==, 0); - r = mongoc_gridfs_file_readv (file, iov, 2, 20, 0); - - ASSERT_CMPSSIZE_T (r, ==, twenty); - ASSERT_MEMCMP (iov[0].iov_base, "acon ipsum", 10); - ASSERT_MEMCMP (iov[1].iov_base, " dolor sit", 10); - - ASSERT_CMPINT ( - mongoc_gridfs_file_seek (file, file->chunk_size - 1, SEEK_SET), ==, 0); - r = mongoc_gridfs_file_readv (file, iov, 2, 20, 0); - - ASSERT_CMPSSIZE_T (r, ==, twenty); - ASSERT_CMPINT64 ( - mongoc_gridfs_file_tell (file), ==, (uint64_t) (file->chunk_size + 19)); - ASSERT_MEMCMP (iov[0].iov_base, "turducken ", 10); - ASSERT_MEMCMP (iov[1].iov_base, "spare ribs", 10); - - BSON_ASSERT (mongoc_gridfs_file_seek (file, 20, SEEK_END) == 0); - previous_errno = errno; - r = mongoc_gridfs_file_readv (file, iov, 2, 20, 0); - - BSON_ASSERT (errno == previous_errno); - BSON_ASSERT (r == 0); - BSON_ASSERT (mongoc_gridfs_file_tell (file) == file->length + 20); - - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - - mongoc_client_destroy (client); -} - - -static void -_check_chunk_count (mongoc_gridfs_t *gridfs, int64_t len, int64_t chunk_size) -{ - int64_t expected_chunks; - int64_t cnt; - bson_error_t error; - - /* division, rounding up */ - expected_chunks = (len + chunk_size - 1) / chunk_size; - cnt = mongoc_collection_count_documents (mongoc_gridfs_get_chunks (gridfs), - tmp_bson (NULL), - NULL, - NULL, - NULL, - &error); - - ASSERT_CMPINT64 (expected_chunks, ==, cnt); -} - -static void -_test_write (bool at_boundary) -{ - ssize_t seek_len = at_boundary ? 5 : 6; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_client_t *client; - bson_error_t error; - ssize_t r; - char buf[] = "foo bar"; - char buf2[] = " baz"; - char buf3[1000]; - char expected[1000] = {0}; - mongoc_gridfs_file_opt_t opt = {0}; - mongoc_iovec_t iov[2]; - mongoc_iovec_t riov; - ssize_t len = sizeof buf + sizeof buf2 - 2; - - iov[0].iov_base = buf; - iov[0].iov_len = sizeof (buf) - 1; - iov[1].iov_base = buf2; - iov[1].iov_len = sizeof (buf2) - 1; - - riov.iov_base = buf3; - riov.iov_len = sizeof (buf3); - - opt.chunk_size = 2; - - client = test_framework_client_new (); - ASSERT (client); - - gridfs = get_test_gridfs (client, "write", &error); - ASSERT_OR_PRINT (gridfs, error); - - mongoc_gridfs_drop (gridfs, &error); - - file = mongoc_gridfs_create_file (gridfs, &opt); - ASSERT (file); - - /* Test a write across many pages */ - r = mongoc_gridfs_file_writev (file, iov, 2, 0); - ASSERT_CMPSSIZE_T (r, ==, len); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_SET), ==, 0); - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file), ==, (uint64_t) 0); - - r = mongoc_gridfs_file_readv (file, &riov, 1, len, 0); - ASSERT_CMPSSIZE_T (r, ==, len); - ASSERT_CMPINT (memcmp (buf3, "foo bar baz", len), ==, 0); - - ASSERT_CMPINT ( - mongoc_gridfs_file_seek (file, file->chunk_size, SEEK_SET), ==, 0); - ASSERT_CMPUINT64 ( - mongoc_gridfs_file_tell (file), ==, (uint64_t) (file->chunk_size)); - - r = mongoc_gridfs_file_writev (file, iov + 1, 1, 0); - ASSERT_CMPSSIZE_T (r, ==, iov[1].iov_len); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_SET), ==, 0); - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file), ==, (uint64_t) 0); - - r = mongoc_gridfs_file_readv (file, &riov, 1, len, 0); - ASSERT_CMPSSIZE_T (r, ==, len); - ASSERT_CMPINT (memcmp (buf3, "fo bazr baz", len), ==, 0); - _check_chunk_count (gridfs, len, file->chunk_size); - - /* Test writing beyond the end of the file */ - BSON_ASSERT (mongoc_gridfs_file_seek (file, seek_len, SEEK_END) == 0); - BSON_ASSERT (mongoc_gridfs_file_tell (file) == file->length + seek_len); - - r = mongoc_gridfs_file_writev (file, iov, 2, 0); - BSON_ASSERT (r == len); - BSON_ASSERT (mongoc_gridfs_file_tell (file) == 2 * len + seek_len); - BSON_ASSERT (file->length == 2 * len + seek_len); - BSON_ASSERT (mongoc_gridfs_file_save (file)); - _check_chunk_count (gridfs, 2 * len + seek_len, file->chunk_size); - - BSON_ASSERT (mongoc_gridfs_file_seek (file, 0, SEEK_SET) == 0); - BSON_ASSERT (mongoc_gridfs_file_tell (file) == 0); - - r = mongoc_gridfs_file_readv (file, &riov, 1, 2 * len + seek_len, 0); - BSON_ASSERT (r == 2 * len + seek_len); - - /* expect file to be like "fo bazr baz\0\0\0\0\0\0foo bar baz" */ - bson_snprintf (expected, strlen ("fo bazr baz") + 1, "fo bazr baz"); - bson_snprintf (expected + strlen ("fo bazr baz") + seek_len, - strlen ("foo bar baz") + 1, - "foo bar baz"); - - BSON_ASSERT (memcmp (buf3, expected, (size_t) (2 * len + seek_len)) == 0); - BSON_ASSERT (mongoc_gridfs_file_save (file)); - - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - - mongoc_client_destroy (client); -} - - -static void -test_write (void) -{ - _test_write (false /* at_boundary */); -} - - -/* Test a write starting and ending exactly on chunk boundaries */ -static void -test_write_at_boundary (void) -{ - _test_write (true /* at_boundary */); -} - - -static void -test_write_past_end (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_client_t *client; - bson_error_t error; - ssize_t r; - char buf[] = "foo"; - char read_buf[2000]; - mongoc_gridfs_file_opt_t opt = {0}; - mongoc_iovec_t iov[1]; - mongoc_iovec_t riov; - const size_t len = sizeof (buf) - 1; - const int64_t delta = 35; - const uint32_t chunk_sz = 10; - /* division, rounding up */ - const int64_t expected_chunks = ((delta + len) + (chunk_sz - 1)) / chunk_sz; - int64_t cnt; - - iov[0].iov_base = buf; - iov[0].iov_len = sizeof (buf) - 1; - - riov.iov_base = read_buf; - riov.iov_len = sizeof (read_buf); - - opt.chunk_size = chunk_sz; - opt.filename = "foo"; - - client = test_framework_client_new (); - ASSERT (client); - - gridfs = get_test_gridfs (client, "write_past_end", &error); - ASSERT_OR_PRINT (gridfs, error); - - file = mongoc_gridfs_create_file (gridfs, &opt); - ASSERT (file); - - r = mongoc_gridfs_file_writev (file, iov, 1, 0); - ASSERT_CMPSSIZE_T (r, ==, len); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, delta, SEEK_SET), ==, 0); - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file), ==, (uint64_t) delta); - - r = mongoc_gridfs_file_writev (file, iov, 1, 0); - ASSERT_CMPSSIZE_T (r, ==, len); - mongoc_gridfs_file_save (file); - - cnt = mongoc_collection_count_documents (mongoc_gridfs_get_chunks (gridfs), - tmp_bson (NULL), - NULL, - NULL, - NULL, - &error); - - ASSERT_OR_PRINT (cnt != -1, error); - ASSERT_CMPINT64 (expected_chunks, ==, cnt); - - mongoc_gridfs_file_destroy (file); - file = mongoc_gridfs_find_one (gridfs, tmp_bson (NULL), &error); - ASSERT_OR_PRINT (file, error); - - r = mongoc_gridfs_file_readv (file, &riov, 1, delta + len, 0); - ASSERT_CMPSSIZE_T (r, ==, (ssize_t) (delta + len)); - - mongoc_gridfs_file_destroy (file); - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -static void -test_empty (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_stream_t *stream; - mongoc_client_t *client; - bson_error_t error; - ssize_t r; - char buf[2] = {'h', 'i'}; - mongoc_iovec_t iov[1]; - ssize_t two = 2L; - - iov[0].iov_base = buf; - iov[0].iov_len = 2; - - client = test_framework_client_new (); - - ASSERT_OR_PRINT (gridfs = get_test_gridfs (client, "empty", &error), error); - - stream = - mongoc_stream_file_new_for_path (BINARY_DIR "/empty.dat", O_RDONLY, 0); - ASSERT_OR_PRINT_ERRNO (stream, errno); - - file = mongoc_gridfs_create_file_from_stream (gridfs, stream, NULL); - ASSERT (file); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_SET), ==, 0); - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file), ==, (uint64_t) 0); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_CUR), ==, 0); - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file), ==, (uint64_t) 0); - - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_END), ==, 0); - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file), ==, (uint64_t) 0); - - r = mongoc_gridfs_file_writev (file, iov, 1, 0); - - ASSERT_CMPSSIZE_T (r, ==, two); - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_SET), ==, 0); - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file), ==, (uint64_t) 0); - - r = mongoc_gridfs_file_readv (file, iov, 1, 2, 0); - - ASSERT_CMPSSIZE_T (r, ==, two); - ASSERT_CMPINT (strncmp (buf, "hi", 2), ==, 0); - - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - - mongoc_client_destroy (client); -} - - -static void -test_stream (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_client_t *client; - mongoc_stream_t *stream; - mongoc_stream_t *in_stream; - bson_error_t error; - ssize_t r; - char buf[4096]; - mongoc_iovec_t iov; - - iov.iov_base = buf; - iov.iov_len = sizeof buf; - - client = test_framework_client_new (); - ASSERT (client); - - ASSERT_OR_PRINT (gridfs = get_test_gridfs (client, "fs", &error), error); - - mongoc_gridfs_drop (gridfs, &error); - - in_stream = - mongoc_stream_file_new_for_path (BINARY_DIR "/gridfs.dat", O_RDONLY, 0); - ASSERT_OR_PRINT_ERRNO (in_stream, errno); - - file = mongoc_gridfs_create_file_from_stream (gridfs, in_stream, NULL); - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - - stream = mongoc_stream_gridfs_new (file); - - r = mongoc_stream_readv (stream, &iov, 1, file->length, 0); - ASSERT_CMPINT64 ((int64_t) r, ==, file->length); - - /* cleanup */ - mongoc_stream_destroy (stream); - - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -#define ASSERT_TELL(file_, position_) \ - ASSERT_CMPUINT64 (mongoc_gridfs_file_tell (file_), ==, position_) - - -static void -test_long_seek (void *ctx) -{ - const uint64_t four_mb = 4 * 1024 * 1024; - - mongoc_client_t *client; - bson_error_t error; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - ssize_t r; - mongoc_gridfs_file_opt_t opt = {0, "filename"}; - mongoc_iovec_t iov; - char buf[16 * 1024]; /* nothing special about 16k, just a buffer */ - const ssize_t buflen = sizeof (buf); - ssize_t written; - int64_t cursor_id; - int i; - - iov.iov_base = buf; - iov.iov_len = sizeof (buf); - memset (iov.iov_base, 0, iov.iov_len); - - client = test_framework_client_new (); - gridfs = get_test_gridfs (client, "long_seek", &error); - ASSERT_OR_PRINT (gridfs, error); - file = mongoc_gridfs_create_file (gridfs, &opt); - ASSERT (file); - - /* Write 20MB, enough to ensure we need many batches, below */ - written = 0; - while (written < 20 * 1024 * 1024) { - r = mongoc_gridfs_file_writev (file, &iov, 1, 0); - ASSERT_CMPSSIZE_T (r, ==, buflen); - written += r; - } - - /* new file handle */ - mongoc_gridfs_file_save (file); - mongoc_gridfs_file_destroy (file); - file = mongoc_gridfs_find_one ( - gridfs, tmp_bson ("{'filename': 'filename'}"), &error); - - ASSERT_OR_PRINT (file, error); - - /* read the start of the file */ - r = mongoc_gridfs_file_readv (file, &iov, 1, sizeof (buf), 0); - ASSERT_CMPSSIZE_T (r, ==, buflen); - ASSERT_TELL (file, (uint64_t) buflen); - cursor_id = mongoc_cursor_get_id (file->cursor); - ASSERT_CMPINT64 ((int64_t) 0, !=, cursor_id); - - /* seek forward into next batch and read, gridfs advances cursor */ - i = mongoc_gridfs_file_seek (file, four_mb, SEEK_CUR); - ASSERT_CMPINT (i, ==, 0); - r = mongoc_gridfs_file_readv (file, &iov, 1, sizeof (buf), 0); - ASSERT_CMPSSIZE_T (r, ==, buflen); - ASSERT_TELL (file, four_mb + 2 * buflen); - - /* same as the cursor we started with */ - ASSERT_CMPINT64 ((int64_t) 0, !=, mongoc_cursor_get_id (file->cursor)); - ASSERT_CMPINT64 (cursor_id, ==, mongoc_cursor_get_id (file->cursor)); - - /* seek more than a batch forward, gridfs discards cursor */ - i = mongoc_gridfs_file_seek (file, 3 * four_mb, SEEK_CUR); - ASSERT_CMPINT (i, ==, 0); - ASSERT_TELL (file, 4 * four_mb + 2 * buflen); - r = mongoc_gridfs_file_readv (file, &iov, 1, sizeof (buf), 0); - ASSERT_CMPSSIZE_T (r, ==, buflen); - ASSERT_TELL (file, 4 * four_mb + 3 * buflen); - - /* new cursor, not the one we started with */ - ASSERT_CMPINT64 (cursor_id, !=, mongoc_cursor_get_id (file->cursor)); - - mongoc_gridfs_file_destroy (file); - ASSERT_OR_PRINT (drop_collections (gridfs, &error), error); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -static void -test_remove_by_filename (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_gridfs_file_opt_t opt = {0}; - mongoc_client_t *client; - bson_error_t error; - - client = test_framework_client_new (); - ASSERT (client); - - ASSERT_OR_PRINT ( - gridfs = get_test_gridfs (client, "fs_remove_by_filename", &error), - error); - - mongoc_gridfs_drop (gridfs, &error); - - opt.filename = "foo_file_1.txt"; - file = mongoc_gridfs_create_file (gridfs, &opt); - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - mongoc_gridfs_file_destroy (file); - - opt.filename = "foo_file_2.txt"; - file = mongoc_gridfs_create_file (gridfs, &opt); - ASSERT (file); - ASSERT (mongoc_gridfs_file_save (file)); - - ASSERT_OR_PRINT ( - mongoc_gridfs_remove_by_filename (gridfs, "foo_file_1.txt", &error), - error); - mongoc_gridfs_file_destroy (file); - - file = mongoc_gridfs_find_one_by_filename (gridfs, "foo_file_1.txt", &error); - ASSERT (!file); - - file = mongoc_gridfs_find_one_by_filename (gridfs, "foo_file_2.txt", &error); - ASSERT (file); - mongoc_gridfs_file_destroy (file); - - drop_collections (gridfs, &error); - mongoc_gridfs_destroy (gridfs); - - mongoc_client_destroy (client); -} - -static void -test_missing_chunk (void *ctx) -{ - mongoc_client_t *client; - bson_error_t error; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - mongoc_collection_t *chunks; - ssize_t r; - mongoc_gridfs_file_opt_t opt = {0, "filename"}; - mongoc_iovec_t iov; - char buf[16 * 1024]; /* nothing special about 16k, just a buffer */ - const ssize_t buflen = sizeof (buf); - ssize_t written; - bool ret; - - iov.iov_base = buf; - iov.iov_len = sizeof (buf); - memset (iov.iov_base, 0, iov.iov_len); - - client = test_framework_client_new (); - gridfs = get_test_gridfs (client, "long_seek", &error); - ASSERT_OR_PRINT (gridfs, error); - mongoc_gridfs_drop (gridfs, NULL); - file = mongoc_gridfs_create_file (gridfs, &opt); - ASSERT (file); - - /* 700k, enough to need three 255k chunks */ - written = 0; - while (written < 700 * 1024) { - r = mongoc_gridfs_file_writev (file, &iov, 1, 0); - ASSERT_CMPSSIZE_T (r, ==, buflen); - written += r; - } - - /* new file handle */ - mongoc_gridfs_file_save (file); - mongoc_gridfs_file_destroy (file); - file = mongoc_gridfs_find_one_by_filename (gridfs, "filename", &error); - ASSERT_OR_PRINT (file, error); - - /* chunks have n=0, 1, 2; remove the middle one */ - chunks = mongoc_gridfs_get_chunks (gridfs); - ret = mongoc_collection_delete_many ( - chunks, tmp_bson ("{'n': 1}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (ret, error); - - /* read the file */ - for (;;) { - r = mongoc_gridfs_file_readv (file, &iov, 1, sizeof (buf), 0); - if (r > 0) { - ASSERT_CMPSSIZE_T (r, ==, buflen); - } else { - ASSERT (mongoc_gridfs_file_error (file, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - "missing chunk number 1"); - - break; - } - } - - mongoc_gridfs_file_destroy (file); - ASSERT_OR_PRINT (drop_collections (gridfs, &error), error); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -static void -test_oversize (void) -{ - mongoc_client_t *client; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - ssize_t r; - mongoc_iovec_t iov; - char buf[2]; - bson_error_t error; - bool ret; - - client = test_framework_client_new (); - - gridfs = get_test_gridfs (client, "test_oversize", &error); - ASSERT_OR_PRINT (gridfs, error); - - /* 2-byte chunk, 'aa', but chunkSize and file size are 1 byte */ - ret = mongoc_collection_insert_one ( - gridfs->chunks, - tmp_bson ("{'files_id': 1, 'n': 0," - " 'data': {'$binary': {'subType': '0', 'base64': 'YWE='}}}"), - NULL, - NULL, - &error); - - ASSERT_OR_PRINT (ret, error); - ret = mongoc_collection_insert_one ( - gridfs->files, - tmp_bson ("{'_id': 1, 'length': 1, 'chunkSize': 1," - " 'filename': 'filename'}"), - NULL, - NULL, - &error); - - ASSERT_OR_PRINT (ret, error); - file = mongoc_gridfs_find_one_by_filename (gridfs, "filename", &error); - ASSERT_OR_PRINT (file, error); - - /* read the file */ - iov.iov_base = (void *) &buf; - iov.iov_len = 1; - r = mongoc_gridfs_file_readv (file, &iov, 1, sizeof (buf), 0); - ASSERT_CMPSSIZE_T (r, ==, (ssize_t) -1); - BSON_ASSERT (mongoc_gridfs_file_error (file, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CORRUPT, - "corrupt chunk number 0: bad size"); - - mongoc_gridfs_file_destroy (file); - ASSERT_OR_PRINT (mongoc_gridfs_drop (gridfs, &error), error); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - -static void -test_missing_file (void) -{ - mongoc_client_t *client; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - bson_error_t error; - char buf[] = "contents contents"; - mongoc_iovec_t iov; - - iov.iov_base = buf; - iov.iov_len = sizeof buf; - - client = test_framework_client_new (); - gridfs = - mongoc_client_get_gridfs (client, "test_missing_file", NULL, &error); - ASSERT_OR_PRINT (gridfs, error); - - file = mongoc_gridfs_create_file (gridfs, NULL); - ASSERT_CMPSSIZE_T ( - mongoc_gridfs_file_writev (file, &iov, 1, 0), ==, (ssize_t) sizeof buf); - ASSERT_CMPINT (mongoc_gridfs_file_seek (file, 0, SEEK_SET), ==, 0); - BSON_ASSERT (mongoc_gridfs_file_save (file)); - - /* remove the file */ - BSON_ASSERT (mongoc_gridfs_file_remove (file, &error)); - - /* readv fails */ - ASSERT_CMPSSIZE_T (mongoc_gridfs_file_readv (file, &iov, 1, sizeof buf, 0), - ==, - (ssize_t) -1); - BSON_ASSERT (mongoc_gridfs_file_error (file, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - "missing chunk number 0"); - - memset (&error, 0, sizeof error); - - /* writev fails */ - ASSERT_CMPSSIZE_T ( - mongoc_gridfs_file_writev (file, &iov, 1, 0), ==, (ssize_t) -1); - BSON_ASSERT (mongoc_gridfs_file_error (file, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_GRIDFS, - MONGOC_ERROR_GRIDFS_CHUNK_MISSING, - "missing chunk number 0"); - - mongoc_gridfs_file_destroy (file); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -/* check that user can specify _id of any type for file */ -static void -test_set_id (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_client_t *client; - bson_error_t error; - bson_value_t id; - bson_t *query; - mongoc_gridfs_file_t *file; - mongoc_gridfs_file_t *result; - mongoc_gridfs_file_opt_t opt = {0}; - - /* create new client and grab gridfs handle */ - client = test_framework_client_new (); - ASSERT (client); - gridfs = mongoc_client_get_gridfs (client, "test", "fs", &error); - ASSERT_OR_PRINT (gridfs, error); - - /* create bson */ - id.value_type = BSON_TYPE_INT32; - id.value.v_int32 = 1; - - /* query for finding file */ - query = tmp_bson ("{'_id': 1}"); - - /* create new file */ - opt.filename = "test"; - file = mongoc_gridfs_create_file (gridfs, &opt); - ASSERT (file); - - /* if we find a file with new id, then file_set_id worked */ - ASSERT_OR_PRINT (mongoc_gridfs_file_set_id (file, &id, &error), error); - ASSERT (mongoc_gridfs_file_save (file)); - result = mongoc_gridfs_find_one (gridfs, query, &error); - ASSERT_OR_PRINT (result, error); - - mongoc_gridfs_file_destroy (result); - mongoc_gridfs_file_destroy (file); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - -/* check gridfs inherits read / write concern, read prefs from the client */ -static void -test_inherit_client_config (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_write_concern_t *write_concern; - mongoc_read_concern_t *read_concern; - mongoc_read_prefs_t *secondary_pref; - future_t *future; - bson_error_t error; - request_t *request; - mongoc_gridfs_t *gridfs; - mongoc_gridfs_file_t *file; - - /* mock mongos: easiest way to test that read preference is configured */ - server = mock_mongos_new (4); - mock_server_run (server); - - /* configure read / write concern and read prefs on client */ - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - - write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_w (write_concern, 2); - mongoc_client_set_write_concern (client, write_concern); - - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, - MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_client_set_read_concern (client, read_concern); - - secondary_pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_client_set_read_prefs (client, secondary_pref); - - gridfs = _get_gridfs (server, client); - - /* test read prefs and read concern */ - future = future_gridfs_find_one (gridfs, tmp_bson ("{}"), &error); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'find': 'fs.files', 'readConcern': {'level': 'majority'}}," - " '$readPreference': {'mode': 'secondary'}}"); - - mock_server_replies_simple ( - request, - "{'ok': 1, 'cursor': {'ns': 'fs.files', 'firstBatch': [{'_id': 1}]}}"); - - file = future_get_mongoc_gridfs_file_ptr (future); - ASSERT (file); - - request_destroy (request); - future_destroy (future); - - /* test write concern */ - future = future_gridfs_file_remove (file, &error); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_NONE, - "{'delete': 'fs.files', 'writeConcern': {'w': 2}}"); - - mock_server_replies_ok_and_destroys (request); - - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_NONE, - "{'delete': 'fs.chunks', 'writeConcern': {'w': 2}}"); - - mock_server_replies_ok_and_destroys (request); - ASSERT (future_get_bool (future)); - future_destroy (future); - - mongoc_gridfs_file_destroy (file); - mongoc_gridfs_destroy (gridfs); - mongoc_write_concern_destroy (write_concern); - mongoc_read_concern_destroy (read_concern); - mongoc_read_prefs_destroy (secondary_pref); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_find_one_empty (void) -{ - mongoc_gridfs_t *gridfs; - mongoc_client_t *client; - bson_error_t error = {1, 2, "hello"}; - - client = test_framework_client_new (); - gridfs = get_test_gridfs (client, "list", &error); - ASSERT_OR_PRINT (gridfs, error); - ASSERT (!mongoc_gridfs_find_one ( - gridfs, tmp_bson ("{'x': 'doesntexist'}"), &error)); - - /* ensure "error" is cleared if we successfully find no file */ - ASSERT_CMPINT (error.domain, ==, 0); - ASSERT_CMPINT (error.code, ==, 0); - ASSERT_CMPSTR (error.message, ""); - - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); -} - - -static bool -responder (request_t *request, void *data) -{ - if (!strcasecmp (request->command_name, "createIndexes")) { - mock_server_replies_ok_and_destroys (request); - return true; - } - - return false; -} - - -static void -test_write_failure (void) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_gridfs_t *gridfs; - mongoc_stream_t *stream; - mongoc_gridfs_file_opt_t opt = {0}; - mongoc_gridfs_file_t *file; - bson_error_t error; - - server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG); - mock_server_autoresponds (server, responder, NULL, NULL); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "socketTimeoutMS", 100); - client = mongoc_client_new_from_uri (uri); - gridfs = mongoc_client_get_gridfs (client, "db", "fs", &error); - ASSERT_OR_PRINT (gridfs, error); - stream = - mongoc_stream_file_new_for_path (BINARY_DIR "/gridfs.dat", O_RDONLY, 0); - - /* times out writing first chunk */ - opt.chunk_size = 1; - capture_logs (true); - file = mongoc_gridfs_create_file_from_stream (gridfs, stream, &opt); - BSON_ASSERT (!file); - ASSERT_CAPTURED_LOG ("mongoc_gridfs_create_file_from_stream", - MONGOC_LOG_LEVEL_ERROR, - "Failed to send \"update\" command"); - - mongoc_stream_destroy (stream); - mongoc_gridfs_destroy (gridfs); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -void -test_gridfs_install (TestSuite *suite) -{ - TestSuite_AddLive (suite, "/gridfs_old/create", test_create); - TestSuite_AddLive ( - suite, "/gridfs_old/create_from_stream", test_create_from_stream); - TestSuite_AddLive (suite, "/gridfs_old/list", test_list); - TestSuite_AddLive (suite, "/gridfs_old/find_one_empty", test_find_one_empty); - TestSuite_AddLive (suite, "/gridfs_old/find_with_opts", test_find_with_opts); - TestSuite_AddMockServerTest (suite, - "/gridfs_old/find_one_with_opts/limit", - test_find_one_with_opts_limit); - TestSuite_AddLive (suite, "/gridfs_old/properties", test_properties); - TestSuite_AddLive (suite, "/gridfs_old/empty", test_empty); - TestSuite_AddLive (suite, "/gridfs_old/read", test_read); - TestSuite_AddLive (suite, "/gridfs_old/seek", test_seek); - TestSuite_AddLive (suite, "/gridfs_old/stream", test_stream); - TestSuite_AddLive (suite, "/gridfs_old/remove", test_remove); - 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_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_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); - TestSuite_AddMockServerTest ( - suite, "/gridfs_old/inherit_client_config", test_inherit_client_config); - TestSuite_AddMockServerTest ( - suite, "/gridfs_old/write_failure", test_write_failure); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-gssapi.c b/lib/mongoc/libmongoc/tests/test-mongoc-gssapi.c deleted file mode 100644 index dfffd7e1f1e3f1640e5a27c09340e2a0fceb8182..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-gssapi.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2017-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 <mongoc/mongoc.h> -#include <mongoc/mongoc-thread-private.h> - - -static const char *GSSAPI_HOST = "MONGOC_TEST_GSSAPI_HOST"; -static const char *GSSAPI_USER = "MONGOC_TEST_GSSAPI_USER"; - -#define NTHREADS 10 -#define NLOOPS 10 - - -char * -_getenv (const char *name) -{ -#ifdef _MSC_VER - char buf[1024]; - size_t buflen; - - if ((0 == getenv_s (&buflen, buf, sizeof buf, name)) && buflen) { - return bson_strdup (buf); - } else { - return NULL; - } -#else - if (getenv (name) && strlen (getenv (name))) { - return bson_strdup (getenv (name)); - } else { - return NULL; - } -#endif -} - - -struct closure_t { - mongoc_client_pool_t *pool; - int finished; - bson_mutex_t mutex; -}; - - -static void * -gssapi_kerberos_worker (void *data) -{ - struct closure_t *closure = (struct closure_t *) data; - mongoc_client_pool_t *pool = closure->pool; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - bson_t query = BSON_INITIALIZER; - int i; - - for (i = 0; i < NLOOPS; i++) { - bson_t *cmd = BCON_NEW ("ping", BCON_INT32 (1)); - - client = mongoc_client_pool_pop (pool); - if (!mongoc_client_command_with_opts ( - client, "test", cmd, NULL, NULL, NULL, &error)) { - fprintf (stderr, "ping command failed: %s\n", error.message); - abort (); - } - bson_destroy (cmd); - collection = mongoc_client_get_collection (client, "kerberos", "test"); - cursor = mongoc_collection_find ( - collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, NULL, NULL); - - if (!mongoc_cursor_next (cursor, &doc) && - mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "Cursor Failure: %s\n", error.message); - abort (); - } - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_pool_push (pool, client); - } - - bson_destroy (&query); - - bson_mutex_lock (&closure->mutex); - closure->finished++; - bson_mutex_unlock (&closure->mutex); - - return NULL; -} - - -int -main (void) -{ - char *host = _getenv (GSSAPI_HOST); - char *user = _getenv (GSSAPI_USER); - char *uri_str; - mongoc_uri_t *uri; - struct closure_t closure = {0}; - int i; - bson_thread_t threads[NTHREADS]; - - mongoc_init (); - - if (!host || !user) { - fprintf (stderr, - "%s and %s must be defined in environment\n", - GSSAPI_HOST, - GSSAPI_USER); - return 1; - } - - bson_mutex_init (&closure.mutex); - - uri_str = bson_strdup_printf ( - "mongodb://%s@%s/?authMechanism=GSSAPI&connectTimeoutMS=30000", - user, - host); - - uri = mongoc_uri_new (uri_str); - closure.pool = mongoc_client_pool_new (uri); - - for (i = 0; i < NTHREADS; i++) { - bson_thread_create ( - &threads[i], gssapi_kerberos_worker, (void *) &closure); - } - - for (i = 0; i < NTHREADS; i++) { - bson_thread_join (threads[i]); - } - - bson_mutex_lock (&closure.mutex); - BSON_ASSERT (NTHREADS == closure.finished); - bson_mutex_unlock (&closure.mutex); - - mongoc_client_pool_destroy (closure.pool); - bson_mutex_destroy (&closure.mutex); - mongoc_uri_destroy (uri); - bson_free (uri_str); - bson_free (host); - bson_free (user); - - mongoc_cleanup (); - - return 0; -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-handshake.c b/lib/mongoc/libmongoc/tests/test-mongoc-handshake.c deleted file mode 100644 index fbe79b08fdcef472a1d3e9ffa58a169ff58aef5d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-handshake.c +++ /dev/null @@ -1,869 +0,0 @@ -/* - * Copyright 2016 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 <mongoc/mongoc.h> -#ifdef _POSIX_VERSION -#include <sys/utsname.h> -#endif - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-handshake.h" -#include "mongoc/mongoc-handshake-private.h" - -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "test-conveniences.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" - -/* - * Call this before any test which uses mongoc_handshake_data_append, to - * reset the global state and unfreeze the handshake struct. Call it - * after a test so later tests don't have a weird handshake document - * - * This is not safe to call while we have any clients or client pools running! - */ -static void -_reset_handshake (void) -{ - _mongoc_handshake_cleanup (); - _mongoc_handshake_init (); -} - -static void -test_mongoc_handshake_appname_in_uri (void) -{ - char long_string[MONGOC_HANDSHAKE_APPNAME_MAX + 2]; - char *uri_str; - const char *good_uri = "mongodb://host/?" MONGOC_URI_APPNAME "=mongodump"; - mongoc_uri_t *uri; - const char *appname = "mongodump"; - const char *value; - - memset (long_string, 'a', MONGOC_HANDSHAKE_APPNAME_MAX + 1); - long_string[MONGOC_HANDSHAKE_APPNAME_MAX + 1] = '\0'; - - /* Shouldn't be able to set with appname really long */ - capture_logs (true); - uri_str = bson_strdup_printf ("mongodb://a/?" MONGOC_URI_APPNAME "=%s", - long_string); - ASSERT (!mongoc_client_new (uri_str)); - ASSERT_CAPTURED_LOG ("_mongoc_topology_scanner_set_appname", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported value"); - capture_logs (false); - - uri = mongoc_uri_new (good_uri); - ASSERT (uri); - value = mongoc_uri_get_appname (uri); - ASSERT (value); - ASSERT_CMPSTR (appname, value); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new (NULL); - ASSERT (uri); - ASSERT (!mongoc_uri_set_appname (uri, long_string)); - ASSERT (mongoc_uri_set_appname (uri, appname)); - value = mongoc_uri_get_appname (uri); - ASSERT (value); - ASSERT_CMPSTR (appname, value); - mongoc_uri_destroy (uri); - - bson_free (uri_str); -} - -static void -test_mongoc_handshake_appname_frozen_single (void) -{ - mongoc_client_t *client; - const char *good_uri = "mongodb://host/?" MONGOC_URI_APPNAME "=mongodump"; - - client = mongoc_client_new (good_uri); - - /* Shouldn't be able to set appname again */ - capture_logs (true); - ASSERT (!mongoc_client_set_appname (client, "a")); - ASSERT_CAPTURED_LOG ("_mongoc_topology_scanner_set_appname", - MONGOC_LOG_LEVEL_ERROR, - "Cannot set appname more than once"); - capture_logs (false); - - mongoc_client_destroy (client); -} - -static void -test_mongoc_handshake_appname_frozen_pooled (void) -{ - mongoc_client_pool_t *pool; - const char *good_uri = "mongodb://host/?" MONGOC_URI_APPNAME "=mongodump"; - mongoc_uri_t *uri; - - uri = mongoc_uri_new (good_uri); - - pool = mongoc_client_pool_new (uri); - capture_logs (true); - ASSERT (!mongoc_client_pool_set_appname (pool, "test")); - ASSERT_CAPTURED_LOG ("_mongoc_topology_scanner_set_appname", - MONGOC_LOG_LEVEL_ERROR, - "Cannot set appname more than once"); - capture_logs (false); - - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); -} - -static void -_check_arch_string_valid (const char *arch) -{ -#ifdef _POSIX_VERSION - struct utsname system_info; - - ASSERT (uname (&system_info) >= 0); - ASSERT_CMPSTR (system_info.machine, arch); -#endif - ASSERT (strlen (arch) > 0); -} - -static void -_check_os_version_valid (const char *os_version) -{ -#if defined(__linux__) || defined(_WIN32) - /* On linux we search the filesystem for os version or use uname. - * On windows we call GetSystemInfo(). */ - ASSERT (os_version); - ASSERT (strlen (os_version) > 0); -#elif defined(_POSIX_VERSION) - /* On a non linux posix systems, we just call uname() */ - struct utsname system_info; - - ASSERT (uname (&system_info) >= 0); - ASSERT (os_version); - ASSERT_CMPSTR (system_info.release, os_version); -#endif -} - -static void -test_mongoc_handshake_data_append_success (void) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_client_pool_t *pool; - request_t *request; - const bson_t *request_doc; - bson_iter_t iter; - bson_iter_t md_iter; - bson_iter_t inner_iter; - const char *val; - - const char *driver_name = "php driver"; - const char *driver_version = "version abc"; - const char *platform = "./configure -nottoomanyflags"; - - char big_string[HANDSHAKE_MAX_SIZE]; - - memset (big_string, 'a', HANDSHAKE_MAX_SIZE - 1); - big_string[HANDSHAKE_MAX_SIZE - 1] = '\0'; - - _reset_handshake (); - /* Make sure setting the handshake works */ - ASSERT ( - mongoc_handshake_data_append (driver_name, driver_version, platform)); - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 500); - mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_APPNAME, "testapp"); - pool = mongoc_client_pool_new (uri); - - /* Force topology scanner to start */ - client = mongoc_client_pool_pop (pool); - - request = mock_server_receives_ismaster (server); - ASSERT (request); - request_doc = request_get_doc (request, 0); - ASSERT (request_doc); - ASSERT (bson_has_field (request_doc, "isMaster")); - ASSERT (bson_has_field (request_doc, HANDSHAKE_FIELD)); - - ASSERT (bson_iter_init_find (&iter, request_doc, HANDSHAKE_FIELD)); - ASSERT (bson_iter_recurse (&iter, &md_iter)); - - ASSERT (bson_iter_find (&md_iter, "application")); - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter)); - ASSERT (bson_iter_recurse (&md_iter, &inner_iter)); - ASSERT (bson_iter_find (&inner_iter, "name")); - val = bson_iter_utf8 (&inner_iter, NULL); - ASSERT (val); - ASSERT_CMPSTR (val, "testapp"); - - /* Make sure driver.name and driver.version and platform are all right */ - ASSERT (bson_iter_find (&md_iter, "driver")); - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter)); - ASSERT (bson_iter_recurse (&md_iter, &inner_iter)); - ASSERT (bson_iter_find (&inner_iter, "name")); - ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter)); - val = bson_iter_utf8 (&inner_iter, NULL); - ASSERT (val); - ASSERT (strstr (val, driver_name) != NULL); - - ASSERT (bson_iter_find (&inner_iter, "version")); - ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter)); - val = bson_iter_utf8 (&inner_iter, NULL); - ASSERT (val); - ASSERT (strstr (val, driver_version)); - - /* Check os type not empty */ - ASSERT (bson_iter_find (&md_iter, "os")); - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter)); - ASSERT (bson_iter_recurse (&md_iter, &inner_iter)); - - ASSERT (bson_iter_find (&inner_iter, "type")); - ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter)); - val = bson_iter_utf8 (&inner_iter, NULL); - ASSERT (val); - ASSERT (strlen (val) > 0); - - /* Check os version valid */ - ASSERT (bson_iter_find (&inner_iter, "version")); - ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter)); - val = bson_iter_utf8 (&inner_iter, NULL); - _check_os_version_valid (val); - - /* Check os arch is valid */ - ASSERT (bson_iter_find (&inner_iter, "architecture")); - ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter)); - val = bson_iter_utf8 (&inner_iter, NULL); - ASSERT (val); - _check_arch_string_valid (val); - - /* Not checking os_name, as the spec says it can be NULL. */ - - /* Check platform field ok */ - ASSERT (bson_iter_find (&md_iter, "platform")); - ASSERT (BSON_ITER_HOLDS_UTF8 (&md_iter)); - val = bson_iter_utf8 (&md_iter, NULL); - ASSERT (val); - if (strlen (val) < - 250) { /* standard val are < 100, may be truncated on some platform */ - ASSERT (strstr (val, platform) != NULL); - } - - mock_server_replies_simple (request, "{'ok': 1, 'ismaster': true}"); - request_destroy (request); - - /* Cleanup */ - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); - mock_server_destroy (server); - - _reset_handshake (); -} - - -static void -_test_platform (bool platform_oversized) -{ - mongoc_handshake_t *md; - size_t platform_len; - const char *platform_suffix = "b"; - bson_t doc = BSON_INITIALIZER; - - _mongoc_handshake_cleanup (); - _mongoc_handshake_init (); - - md = _mongoc_handshake_get (); - - bson_free (md->os_type); - md->os_type = bson_strdup ("foo"); - bson_free (md->os_name); - md->os_name = bson_strdup ("foo"); - bson_free (md->os_version); - md->os_version = bson_strdup ("foo"); - bson_free (md->os_architecture); - md->os_architecture = bson_strdup ("foo"); - bson_free (md->driver_name); - md->driver_name = bson_strdup ("foo"); - bson_free (md->driver_version); - md->driver_version = bson_strdup ("foo"); - - platform_len = HANDSHAKE_MAX_SIZE; - if (platform_oversized) { - platform_len += 100; - } - - bson_free (md->platform); - md->platform = bson_malloc (platform_len); - memset (md->platform, 'a', platform_len - 1); - md->platform[platform_len - 1] = '\0'; - - /* returns true, but ignores the suffix; there's no room */ - ASSERT (mongoc_handshake_data_append (NULL, NULL, platform_suffix)); - ASSERT (!strstr (md->platform, "b")); - ASSERT (_mongoc_handshake_build_doc_with_application (&doc, "my app")); - ASSERT_CMPUINT32 (doc.len, ==, (uint32_t) HANDSHAKE_MAX_SIZE); - - bson_destroy (&doc); - _reset_handshake (); /* frees the strings created above */ -} - - -static void -test_mongoc_handshake_big_platform (void) -{ - _test_platform (false); -} - - -static void -test_mongoc_handshake_oversized_platform (void) -{ - _test_platform (true); -} - - -static void -test_mongoc_handshake_data_append_after_cmd (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client; - mongoc_uri_t *uri; - - _reset_handshake (); - - uri = mongoc_uri_new ("mongodb://127.0.0.1/?" MONGOC_URI_MAXPOOLSIZE "=1"); - - /* Make sure that after we pop a client we can't set global handshake */ - pool = mongoc_client_pool_new (uri); - - client = mongoc_client_pool_pop (pool); - - capture_logs (true); - ASSERT (!mongoc_handshake_data_append ("a", "a", "a")); - capture_logs (false); - - mongoc_client_pool_push (pool, client); - - mongoc_uri_destroy (uri); - mongoc_client_pool_destroy (pool); - - _reset_handshake (); -} - -/* - * Append to the platform field a huge string - * Make sure that it gets truncated - */ -static void -test_mongoc_handshake_too_big (void) -{ - mongoc_client_t *client; - mock_server_t *server; - mongoc_uri_t *uri; - future_t *future; - request_t *request; - const bson_t *ismaster_doc; - bson_iter_t iter; - - enum { BUFFER_SIZE = HANDSHAKE_MAX_SIZE }; - char big_string[BUFFER_SIZE]; - uint32_t len; - const uint8_t *dummy; - - server = mock_server_new (); - mock_server_run (server); - - _reset_handshake (); - - memset (big_string, 'a', BUFFER_SIZE - 1); - big_string[BUFFER_SIZE - 1] = '\0'; - ASSERT (mongoc_handshake_data_append (NULL, NULL, big_string)); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - /* avoid rare test timeouts */ - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_CONNECTTIMEOUTMS, 20000); - client = mongoc_client_new_from_uri (uri); - - ASSERT (mongoc_client_set_appname (client, "my app")); - - /* Send a ping, mock server deals with it */ - future = future_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL); - request = mock_server_receives_ismaster (server); - - /* Make sure the isMaster request has a handshake field, and it's not huge */ - ASSERT (request); - ismaster_doc = request_get_doc (request, 0); - ASSERT (ismaster_doc); - ASSERT (bson_has_field (ismaster_doc, "isMaster")); - ASSERT (bson_has_field (ismaster_doc, HANDSHAKE_FIELD)); - - /* isMaster with handshake isn't too big */ - bson_iter_init_find (&iter, ismaster_doc, HANDSHAKE_FIELD); - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - bson_iter_document (&iter, &len, &dummy); - - /* Should have truncated the platform field so it fits exactly */ - ASSERT (len == HANDSHAKE_MAX_SIZE); - - mock_server_replies_simple ( - request, "{'ok': 1, 'minWireVersion': 2, 'maxWireVersion': 5}"); - request_destroy (request); - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - - mock_server_replies_simple (request, "{'ok': 1}"); - ASSERT (future_get_bool (future)); - - future_destroy (future); - request_destroy (request); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); - - /* So later tests don't have "aaaaa..." as the md platform string */ - _reset_handshake (); -} - -/* - * Testing whether platform string data is truncated/dropped appropriately - * drop specifies what case should be tested for - */ -static void -test_mongoc_platform_truncate (int drop) -{ - mongoc_handshake_t *md; - bson_t doc = BSON_INITIALIZER; - bson_iter_t iter; - - char *undropped; - char *expected; - char big_string[HANDSHAKE_MAX_SIZE]; - int handshake_remaining_space; - - /* Need to know how much space storing fields in our BSON will take - * so that we can make our platform string the correct length here */ - int handshake_bson_size = 163; - _reset_handshake (); - - md = _mongoc_handshake_get (); - - /* we manually bypass the defaults of the handshake to ensure an exceedingly - * long field does not cause our test to incorrectly fail */ - bson_free (md->os_type); - md->os_type = bson_strdup ("test_a"); - bson_free (md->os_name); - md->os_name = bson_strdup ("test_b"); - bson_free (md->os_version); - md->os_version = bson_strdup ("test_c"); - bson_free (md->os_architecture); - md->os_architecture = bson_strdup ("test_d"); - bson_free (md->driver_name); - md->driver_name = bson_strdup ("test_e"); - bson_free (md->driver_version); - md->driver_version = bson_strdup ("test_f"); - bson_free (md->compiler_info); - md->compiler_info = bson_strdup ("test_g"); - bson_free (md->flags); - md->flags = bson_strdup ("test_h"); - - handshake_remaining_space = - HANDSHAKE_MAX_SIZE - - (strlen (md->os_type) + strlen (md->os_name) + strlen (md->os_version) + - strlen (md->os_architecture) + strlen (md->driver_name) + - strlen (md->driver_version) + strlen (md->compiler_info) + - strlen (md->flags) + handshake_bson_size); - - /* adjust remaining space depending on which combination of - * flags/compiler_info we want to test dropping */ - if (drop == 2) { - handshake_remaining_space += - strlen (md->flags) + strlen (md->compiler_info); - undropped = bson_strdup_printf ("%s", ""); - } else if (drop == 1) { - handshake_remaining_space += strlen (md->flags); - undropped = bson_strdup_printf ("%s", md->compiler_info); - } else { - undropped = bson_strdup_printf ("%s%s", md->compiler_info, md->flags); - } - - memset (big_string, 'a', handshake_remaining_space + 1); - big_string[handshake_remaining_space + 1] = '\0'; - - ASSERT (mongoc_handshake_data_append (NULL, NULL, big_string)); - ASSERT (_mongoc_handshake_build_doc_with_application (&doc, "my app")); - - /* doc.len being strictly less than HANDSHAKE_MAX_SIZE proves that we have - * dropped the flags correctly, instead of truncating anything - */ - ASSERT_CMPUINT32 (doc.len, <, (uint32_t) HANDSHAKE_MAX_SIZE); - bson_iter_init_find (&iter, &doc, "platform"); - expected = bson_strdup_printf ("%s%s", big_string, undropped); - ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL), expected); - - bson_free (expected); - bson_free (undropped); - bson_destroy (&doc); - /* So later tests don't have "aaaaa..." as the md platform string */ - _reset_handshake (); -} - -/* - * Test dropping neither compiler_info/flags, dropping just flags, and dropping - * both - */ -static void -test_mongoc_oversized_flags (void) -{ - test_mongoc_platform_truncate (0); - test_mongoc_platform_truncate (1); - test_mongoc_platform_truncate (2); -} - -/* Test the case where we can't prevent the handshake doc being too big - * and so we just don't send it */ -static void -test_mongoc_handshake_cannot_send (void) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_client_pool_t *pool; - request_t *request; - const char *const server_reply = "{'ok': 1, 'ismaster': true}"; - const bson_t *request_doc; - char big_string[HANDSHAKE_MAX_SIZE]; - mongoc_handshake_t *md; - - _reset_handshake (); - capture_logs (true); - - /* Mess with our global handshake struct so the handshake doc will be - * way too big */ - memset (big_string, 'a', HANDSHAKE_MAX_SIZE - 1); - big_string[HANDSHAKE_MAX_SIZE - 1] = '\0'; - - md = _mongoc_handshake_get (); - bson_free (md->os_name); - md->os_name = bson_strdup (big_string); - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 500); - pool = mongoc_client_pool_new (uri); - - /* Pop a client to trigger the topology scanner */ - client = mongoc_client_pool_pop (pool); - request = mock_server_receives_ismaster (server); - - /* Make sure the isMaster request DOESN'T have a handshake field: */ - ASSERT (request); - request_doc = request_get_doc (request, 0); - ASSERT (request_doc); - ASSERT (bson_has_field (request_doc, "isMaster")); - ASSERT (!bson_has_field (request_doc, HANDSHAKE_FIELD)); - - mock_server_replies_simple (request, server_reply); - request_destroy (request); - - /* Cause failure on client side */ - request = mock_server_receives_ismaster (server); - ASSERT (request); - mock_server_hangs_up (request); - request_destroy (request); - - /* Make sure the isMaster request still DOESN'T have a handshake field - * on subsequent heartbeats. */ - request = mock_server_receives_ismaster (server); - ASSERT (request); - request_doc = request_get_doc (request, 0); - ASSERT (request_doc); - ASSERT (bson_has_field (request_doc, "isMaster")); - ASSERT (!bson_has_field (request_doc, HANDSHAKE_FIELD)); - - mock_server_replies_simple (request, server_reply); - request_destroy (request); - - /* cleanup */ - mongoc_client_pool_push (pool, client); - - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); - mock_server_destroy (server); - - /* Reset again so the next tests don't have a handshake doc which - * is too big */ - _reset_handshake (); -} - -extern char * -_mongoc_handshake_get_config_hex_string (void); - -static bool -_get_bit (char *config_str, uint32_t bit) -{ - /* get the location of the two byte chars for this bit. */ - uint32_t byte = bit / 8; - uint32_t bit_of_byte = bit % 8; - uint32_t char_loc; - uint32_t as_num; - char byte_str[3]; - - /* byte 0 is represented at the last two characters. */ - char_loc = (uint32_t) strlen (config_str) - 2 - (byte * 2); - /* index should be past the prefixed "0x" */ - ASSERT_CMPINT32 (char_loc, >, 1); - /* get the number representation of the byte. */ - byte_str[0] = config_str[char_loc]; - byte_str[1] = config_str[char_loc + 1]; - byte_str[2] = '\0'; - as_num = (uint8_t) strtol (byte_str, NULL, 16); - return (as_num & (1u << bit_of_byte)) > 0u; -} - -void -test_handshake_platform_config () -{ - /* Parse the config string, and check that it matches the defined flags. */ - char *config_str = _mongoc_handshake_get_config_hex_string (); - uint32_t total_bytes = (LAST_MONGOC_MD_FLAG + 7) / 8; - uint32_t total_bits = 8 * total_bytes; - uint32_t i; - /* config_str should have the form 0x?????. */ - ASSERT_CMPINT ((int) strlen (config_str), ==, 2 + (2 * total_bytes)); - BSON_ASSERT (strncmp (config_str, "0x", 2) == 0); - -/* go through all flags. */ -#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL - BSON_ASSERT (_get_bit (config_str, MONGOC_ENABLE_SSL_SECURE_CHANNEL)); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO_CNG - BSON_ASSERT (_get_bit (config_str, MONGOC_ENABLE_CRYPTO_CNG)); -#endif - -#ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT - BSON_ASSERT ( - _get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT)); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO - BSON_ASSERT ( - _get_bit (config_str, MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO)); -#endif - -#ifdef MONGOC_ENABLE_SSL_OPENSSL - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL)); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO)); -#endif - -#ifdef MONGOC_ENABLE_SSL - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SSL)); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_CRYPTO)); -#endif - -#ifdef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE - BSON_ASSERT ( - _get_bit (config_str, MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE)); -#endif - -#ifdef MONGOC_ENABLE_SASL - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SASL)); -#endif - -#ifdef MONGOC_HAVE_SASL_CLIENT_DONE - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE)); -#endif - -#ifdef MONGOC_NO_AUTOMATIC_GLOBALS - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS)); -#endif - -#ifdef MONGOC_EXPERIMENTAL_FEATURES - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES)); -#endif - -#ifdef MONGOC_ENABLE_SSL_LIBRESSL - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL)); -#endif - -#ifdef MONGOC_ENABLE_SASL_CYRUS - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SASL_CYRUS)); -#endif - -#ifdef MONGOC_ENABLE_SASL_SSPI - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SASL_SSPI)); -#endif - -#ifdef MONGOC_HAVE_SOCKLEN - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_HAVE_SOCKLEN)); -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_COMPRESSION)); -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - BSON_ASSERT ( - _get_bit (config_str, MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY)); -#endif - -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB)); -#endif - -#ifdef MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI)); -#endif - -#ifdef MONGOC_HAVE_RES_NSEARCH - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_RES_NSEARCH)); -#endif - -#ifdef MONGOC_HAVE_RES_NDESTROY - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_RES_NDESTROY)); -#endif - -#ifdef MONGOC_HAVE_RES_NCLOSE - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_RES_NCLOSE)); -#endif - -#ifdef MONGOC_HAVE_RES_SEARCH - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_RES_SEARCH)); -#endif - -#ifdef MONGOC_HAVE_DNSAPI - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_DNSAPI)); -#endif - -#ifdef MONGOC_HAVE_RDTSCP - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_RDTSCP)); -#endif - -#ifdef MONGOC_HAVE_SCHED_GETCPU - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_HAVE_SCHED_GETCPU)); -#endif - -#ifdef MONGOC_ENABLE_SHM_COUNTERS - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS)); -#endif - -#ifdef MONGOC_TRACE - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_TRACE)); -#endif - -#ifdef MONGOC_ENABLE_ICU - BSON_ASSERT (_get_bit (config_str, MONGOC_MD_FLAG_ENABLE_ICU)); -#endif - -#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION - BSON_ASSERT ( - _get_bit (config_str, MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION)); -#endif - - /* any excess bits should all be zero. */ - for (i = LAST_MONGOC_MD_FLAG; i < total_bits; i++) { - BSON_ASSERT (!_get_bit (config_str, i)); - } - bson_free (config_str); -} - -/* Called by a single thread in test_mongoc_handshake_race_condition */ -static void * -handshake_append_worker (void *data) -{ - const char *driver_name = "php driver"; - const char *driver_version = "version abc"; - const char *platform = "./configure -nottoomanyflags"; - - mongoc_handshake_data_append (driver_name, driver_version, platform); - - return NULL; -} - -/* Run 1000 iterations of mongoc_handshake_data_append() using 4 threads */ -static void -test_mongoc_handshake_race_condition (void) -{ - unsigned i, j; - bson_thread_t threads[4]; - - for (i = 0; i < 1000; ++i) { - _reset_handshake (); - - for (j = 0; j < 4; ++j) { - BSON_ASSERT ( - !bson_thread_create (&threads[j], &handshake_append_worker, NULL)); - } - - for (j = 0; j < 4; ++j) { - bson_thread_join (threads[j]); - } - } - - _reset_handshake (); -} - -void -test_handshake_install (TestSuite *suite) -{ - TestSuite_Add (suite, - "/MongoDB/handshake/appname_in_uri", - test_mongoc_handshake_appname_in_uri); - TestSuite_Add (suite, - "/MongoDB/handshake/appname_frozen_single", - test_mongoc_handshake_appname_frozen_single); - TestSuite_Add (suite, - "/MongoDB/handshake/appname_frozen_pooled", - test_mongoc_handshake_appname_frozen_pooled); - - TestSuite_AddMockServerTest (suite, - "/MongoDB/handshake/success", - test_mongoc_handshake_data_append_success); - TestSuite_Add (suite, - "/MongoDB/handshake/big_platform", - test_mongoc_handshake_big_platform); - TestSuite_Add (suite, - "/MongoDB/handshake/oversized_platform", - test_mongoc_handshake_oversized_platform); - TestSuite_Add (suite, - "/MongoDB/handshake/failure", - test_mongoc_handshake_data_append_after_cmd); - TestSuite_AddMockServerTest ( - suite, "/MongoDB/handshake/too_big", test_mongoc_handshake_too_big); - TestSuite_Add ( - suite, "/MongoDB/handshake/oversized_flags", test_mongoc_oversized_flags); - TestSuite_AddMockServerTest (suite, - "/MongoDB/handshake/cannot_send", - test_mongoc_handshake_cannot_send); - TestSuite_Add (suite, - "/MongoDB/handshake/platform_config", - test_handshake_platform_config); - TestSuite_Add (suite, - "/MongoDB/handshake/race_condition", - test_mongoc_handshake_race_condition); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-linux-distro-scanner.c b/lib/mongoc/libmongoc/tests/test-mongoc-linux-distro-scanner.c deleted file mode 100644 index b3c725a47b963c20f7d2a9ef636f2a57af1ccc0a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-linux-distro-scanner.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright 2016 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 <mongoc/mongoc.h> -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-linux-distro-scanner-private.h" -#include "mongoc/mongoc-handshake-os-private.h" - -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "test-conveniences.h" - -#ifdef MONGOC_OS_IS_LINUX -static void -test_read_generic_release_file (void) -{ - char *name; - char *version; - const char *paths[] = { - OS_RELEASE_FILE_DIR "/lol-im-not-here.txt", - OS_RELEASE_FILE_DIR "/also-not-here.txt", - OS_RELEASE_FILE_DIR "/example-etc-fedora-release.txt", - NULL, - }; - - const char *paths2[] = { - OS_RELEASE_FILE_DIR "/example-etc-xyz-release-no-delimiter.txt", NULL, - }; - - const char *paths3[] = { - OS_RELEASE_FILE_DIR "/empty-file.txt", NULL, - }; - - _mongoc_linux_distro_scanner_read_generic_release_file ( - paths, &name, &version); - ASSERT (name); - ASSERT (version); - ASSERT_CMPSTR ("Fedora", name); - ASSERT_CMPSTR ("8 (Werewolf)", version); - bson_free (name); - bson_free (version); - - _mongoc_linux_distro_scanner_read_generic_release_file ( - paths2, &name, &version); - ASSERT (name); - ASSERT_CMPSTR ("This one just has name, not that R word", name); - ASSERT (version == NULL); - bson_free (name); - - _mongoc_linux_distro_scanner_read_generic_release_file ( - paths3, &name, &version); - ASSERT (name == NULL); - ASSERT (version == NULL); - - _mongoc_linux_distro_scanner_split_line_by_release ( - " release ", -1, &name, &version); - ASSERT (name == NULL); - ASSERT (version == NULL); - - _mongoc_linux_distro_scanner_split_line_by_release ( - "ends with release ", -1, &name, &version); - ASSERT_CMPSTR ("ends with", name); - ASSERT (version == NULL); - bson_free (name); - - _mongoc_linux_distro_scanner_split_line_by_release ("", -1, &name, &version); - ASSERT_CMPSTR (name, ""); - ASSERT (version == NULL); - bson_free (name); -} - - -static void -test_read_key_value_file (void) -{ - char *name = NULL; - char *version = NULL; - - _mongoc_linux_distro_scanner_read_key_value_file (OS_RELEASE_FILE_DIR - "/example-lsb-file.txt", - "DISTRIB_ID", - -1, - &name, - "DISTRIB_RELEASE", - -1, - &version); - - ASSERT (name); - ASSERT_CMPSTR (name, "Ubuntu"); - ASSERT (version); - ASSERT_CMPSTR (version, "12.04"); - - bson_free (name); - bson_free (version); - - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-lsb-file-with-super-long-line.txt", - "DISTRIB_ID", - -1, - &name, - "DISTRIB_RELEASE", - -1, - &version); - ASSERT (!name); - ASSERT (version); - ASSERT_CMPSTR (version, "12.04"); - bson_free (version); - - - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-etc-os-release.txt", - "NAME", - -1, - &name, - "VERSION_ID", - -1, - &version); - - ASSERT_CMPSTR (name, "Fedora"); - ASSERT_CMPSTR (version, "17"); - - bson_free (name); - bson_free (version); - - /* Now try some weird inputs */ - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-etc-os-release.txt", - "ID=", - -1, - &name, - "VERSION_ID=", - -1, - &version); - - ASSERT (name == NULL); - ASSERT (version == NULL); - - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-etc-os-release.txt", - "", - -1, - &name, - "", - -1, - &version); - - ASSERT (name == NULL); - ASSERT (version == NULL); - - /* Test case where we get one but not the other */ - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-etc-os-release.txt", - "NAME", - -1, - &name, - "VERSION_", - -1, - &version); - - ASSERT_CMPSTR (name, "Fedora"); - ASSERT (version == NULL); - bson_free (name); - - /* Case where we say the key is the whole line */ - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-etc-os-release.txt", - "NAME", - -1, - &name, - "VERSION_ID=17", - -1, - &version); - ASSERT_CMPSTR (name, "Fedora"); - ASSERT (version == NULL); - bson_free (name); - - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-etc-os-release-ubuntu1604.txt", - "NAME", - -1, - &name, - "VERSION_ID", - -1, - &version); - ASSERT_CMPSTR ("Ubuntu", name); - ASSERT_CMPSTR ("16.04", version); - bson_free (name); - bson_free (version); - - - /* Case where the key is duplicated, make sure we keep first version */ - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-key-value-file.txt", - "key", - -1, - &name, - "normalkey", - -1, - &version); - ASSERT_CMPSTR (name, "first value"); - ASSERT_CMPSTR (version, "normalval"); - bson_free (name); - bson_free (version); - - /* Case where the key is duplicated, make sure we keep first version */ - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-key-value-file.txt", - "a-key-without-a-value", - -1, - &name, - "normalkey", - -1, - &version); - ASSERT_CMPSTR (name, ""); - ASSERT_CMPSTR (version, "normalval"); - bson_free (name); - bson_free (version); - - /* Try to get value from a line like: - * just-a-key - * (No equals, no value) */ - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-key-value-file.txt", - "just-a-key", - -1, - &name, - "normalkey", - -1, - &version); - ASSERT (name == NULL); - ASSERT_CMPSTR (version, "normalval"); - bson_free (name); - bson_free (version); - - /* Try to get a key which is on line 101 of the file - * (we stop reading at line 100) */ - _mongoc_linux_distro_scanner_read_key_value_file ( - OS_RELEASE_FILE_DIR "/example-key-value-file.txt", - "lastkey", - -1, - &name, - "normalkey", - -1, - &version); - ASSERT (name == NULL); - ASSERT_CMPSTR (version, "normalval"); - bson_free (version); -} - -/* We only expect this function to actually read anything on linux platforms */ -static void -test_distro_scanner_reads (void) -{ - char *name; - char *version; - - _mongoc_linux_distro_scanner_get_distro (&name, &version); - -#ifdef __linux__ - ASSERT (name); - ASSERT (strlen (name) > 0); - - /* Some linux distros don't have a version (like arch) but we should always - * return a version (at the very least, we'll return the kernel version) */ - ASSERT (version); - ASSERT (strlen (version)); -#endif - bson_free (name); - bson_free (version); -} -#endif - -void -test_linux_distro_scanner_install (TestSuite *suite) -{ -#ifdef MONGOC_OS_IS_LINUX - TestSuite_Add (suite, - "/LinuxDistroScanner/test_read_generic_release_file", - test_read_generic_release_file); - TestSuite_Add (suite, - "/LinuxDistroScanner/test_read_key_value_file", - test_read_key_value_file); - TestSuite_Add (suite, - "/LinuxDistroScanner/test_distro_scanner_reads", - test_distro_scanner_reads); -#endif -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-list.c b/lib/mongoc/libmongoc/tests/test-mongoc-list.c deleted file mode 100644 index 9ac2116bc830ca0d0bfeb60b4aa2a186d1e42b23..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-list.c +++ /dev/null @@ -1,53 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-list-private.h> - -#include "TestSuite.h" - - -static void -test_mongoc_list_basic (void) -{ - mongoc_list_t *l; - - l = _mongoc_list_append (NULL, (void *) 1ULL); - l = _mongoc_list_append (l, (void *) 2ULL); - l = _mongoc_list_append (l, (void *) 3ULL); - l = _mongoc_list_prepend (l, (void *) 4ULL); - - ASSERT (l); - ASSERT (l->next); - ASSERT (l->next->next); - ASSERT (l->next->next->next); - ASSERT (!l->next->next->next->next); - - ASSERT (l->data == (void *) 4ULL); - ASSERT (l->next->data == (void *) 1ULL); - ASSERT (l->next->next->data == (void *) 2ULL); - ASSERT (l->next->next->next->data == (void *) 3ULL); - - l = _mongoc_list_remove (l, (void *) 4ULL); - ASSERT (l->data == (void *) 1ULL); - ASSERT (l->next->data == (void *) 2ULL); - ASSERT (l->next->next->data == (void *) 3ULL); - - l = _mongoc_list_remove (l, (void *) 2ULL); - ASSERT (l->data == (void *) 1ULL); - ASSERT (l->next->data == (void *) 3ULL); - ASSERT (!l->next->next); - - l = _mongoc_list_remove (l, (void *) 1ULL); - ASSERT (l->data == (void *) 3ULL); - ASSERT (!l->next); - - l = _mongoc_list_remove (l, (void *) 3ULL); - ASSERT (!l); - - _mongoc_list_destroy (l); -} - - -void -test_list_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/List/Basic", test_mongoc_list_basic); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-log.c b/lib/mongoc/libmongoc/tests/test-mongoc-log.c deleted file mode 100644 index 36808d9a57a0e8485c4f48b3d3632d8fd8a08d2d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-log.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2015 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 <mongoc/mongoc.h> - -#include "mongoc/mongoc-log-private.h" -#include "mongoc/mongoc-trace-private.h" -#include "TestSuite.h" - - -struct log_state { - mongoc_log_func_t handler; - void *data; - bool trace_enabled; -}; - - -static void -save_state (struct log_state *state) -{ - _mongoc_log_get_handler (&state->handler, &state->data); - state->trace_enabled = _mongoc_log_trace_is_enabled (); -} - - -static void -restore_state (const struct log_state *state) -{ - mongoc_log_set_handler (state->handler, state->data); - - if (state->trace_enabled) { - mongoc_log_trace_enable (); - } else { - mongoc_log_trace_disable (); - } -} - - -struct log_func_data { - mongoc_log_level_t log_level; - char *log_domain; - char *message; -}; - - -void -log_func (mongoc_log_level_t log_level, - const char *log_domain, - const char *message, - void *user_data) -{ - struct log_func_data *data = (struct log_func_data *) user_data; - - data->log_level = log_level; - data->log_domain = bson_strdup (log_domain); - data->message = bson_strdup (message); -} - - -static void -test_mongoc_log_handler (void) -{ - struct log_state old_state; - struct log_func_data data; - - save_state (&old_state); - mongoc_log_set_handler (log_func, &data); - -#pragma push_macro("MONGOC_LOG_DOMAIN") -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "my-custom-domain" - - MONGOC_WARNING ("warning!"); - -#pragma pop_macro("MONGOC_LOG_DOMAIN") - - ASSERT_CMPINT (data.log_level, ==, MONGOC_LOG_LEVEL_WARNING); - ASSERT_CMPSTR (data.log_domain, "my-custom-domain"); - ASSERT_CMPSTR (data.message, "warning!"); - - restore_state (&old_state); - - bson_free (data.log_domain); - bson_free (data.message); -} - - -static void -test_mongoc_log_null (void) -{ - struct log_state old_state; - - save_state (&old_state); - mongoc_log_set_handler (NULL, NULL); - - /* doesn't seg fault */ - MONGOC_ERROR ("error!"); - MONGOC_DEBUG ("debug!"); - - restore_state (&old_state); -} - -static int -should_run_trace_tests (void) -{ -#ifdef MONGOC_TRACE - return 1; -#else - return 0; -#endif -} -static int -should_not_run_trace_tests (void) -{ - return !should_run_trace_tests (); -} - -static void -test_mongoc_log_trace_enabled (void *context) -{ - struct log_state old_state; - struct log_func_data data; - - save_state (&old_state); - mongoc_log_set_handler (log_func, &data); - - mongoc_log_trace_enable (); - TRACE ("%s", "Conscript reporting!"); - ASSERT_CMPINT (data.log_level, ==, MONGOC_LOG_LEVEL_TRACE); - ASSERT_CONTAINS (data.message, " Conscript reporting!"); - bson_free (data.log_domain); - bson_free (data.message); - - TRACE ("%s", "Awaiting orders"); - ASSERT_CMPINT (data.log_level, ==, MONGOC_LOG_LEVEL_TRACE); - ASSERT_CONTAINS (data.message, "Awaiting orders"); - - mongoc_log_trace_disable (); - TRACE ("%s", "For the Union"); - ASSERT_CMPINT (data.log_level, ==, MONGOC_LOG_LEVEL_TRACE); - ASSERT_CONTAINS (data.message, "Awaiting orders"); - bson_free (data.log_domain); - bson_free (data.message); - - - mongoc_log_trace_enable (); - TRACE ("%s", "For home country"); - ASSERT_CMPINT (data.log_level, ==, MONGOC_LOG_LEVEL_TRACE); - ASSERT_CONTAINS (data.message, "For home country"); - - restore_state (&old_state); - - bson_free (data.log_domain); - bson_free (data.message); -} - -static void -test_mongoc_log_trace_disabled (void *context) -{ - struct log_state old_state; - struct log_func_data data = {(mongoc_log_level_t) -1, 0, NULL}; - - save_state (&old_state); - mongoc_log_set_handler (log_func, &data); - - TRACE ("%s", "Conscript reporting!"); - ASSERT_CMPINT (data.log_level, ==, (mongoc_log_level_t) -1); - - restore_state (&old_state); -} - -void -test_log_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Log/basic", test_mongoc_log_handler); - TestSuite_AddFull (suite, - "/Log/trace/enabled", - test_mongoc_log_trace_enabled, - NULL, - NULL, - should_run_trace_tests); - TestSuite_AddFull (suite, - "/Log/trace/disabled", - test_mongoc_log_trace_disabled, - NULL, - NULL, - should_not_run_trace_tests); - TestSuite_Add (suite, "/Log/null", test_mongoc_log_null); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-matcher.c b/lib/mongoc/libmongoc/tests/test-mongoc-matcher.c deleted file mode 100644 index 194641dcbc33309e468481db0a9d24f8c20f9f78..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-matcher.c +++ /dev/null @@ -1,566 +0,0 @@ - -#include <bson/bcon.h> -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-matcher-private.h> -#include <mongoc/mongoc-util-private.h> - -#include "TestSuite.h" - -BEGIN_IGNORE_DEPRECATIONS; - -static void -test_mongoc_matcher_basic (void) -{ - bson_t matcher_query; - bson_t *query; - bson_t *to_match; - bson_t *should_fail; - bson_error_t error; - mongoc_matcher_t *matcher; - - bson_init (&matcher_query); - - query = BCON_NEW ("city", - "New York", - "state", - "New York", - "favorite color", - "blue", - "name", - "{", - "$not", - "invalid", - "}", - /* "zip", "{", "$in", "[", BCON_INT32(11201), */ - /* BCON_INT32(90210), "]", "}", */ - "$or", - "[", - "{", - "age", - "{", - "$lt", - BCON_INT32 (18), - "}", - "}", - "{", - "age", - "{", - "$gt", - BCON_INT32 (45), - "}", - "}", - "]"); - - matcher = mongoc_matcher_new (query, &error); - - BSON_ASSERT (matcher); - - _mongoc_matcher_op_to_bson (matcher->optree, &matcher_query); - -#if 0 - { - char *out = bson_as_canonical_extended_json(&matcher_query, NULL); - fprintf(stderr, "bson: %s\n", out); - free(out); - } -#endif - - to_match = BCON_NEW ("city", - "New York", - "state", - "New York", - "favorite color", - "blue", - "zip", - BCON_INT32 (11201), - "age", - BCON_INT32 (65)); - - BSON_ASSERT (mongoc_matcher_match (matcher, to_match)); - - should_fail = BCON_NEW ("city", - "New York", - "state", - "New York", - "favorite color", - "blue", - "zip", - BCON_INT32 (99999), - "age", - BCON_INT32 (30)); - - BSON_ASSERT (!mongoc_matcher_match (matcher, should_fail)); - - bson_destroy (query); - bson_destroy (to_match); - bson_destroy (should_fail); - bson_destroy (&matcher_query); - - mongoc_matcher_destroy (matcher); -} - -static void -test_mongoc_matcher_array (void) -{ - bson_t *query; - bson_t *to_match; - bson_t *should_fail; - bson_error_t error; - mongoc_matcher_t *matcher; - - query = BCON_NEW ("a", "[", BCON_INT32 (1), BCON_INT32 (2), "]"); - matcher = mongoc_matcher_new (query, &error); - BSON_ASSERT (matcher); - - /* query matches itself */ - BSON_ASSERT (mongoc_matcher_match (matcher, query)); - - to_match = - BCON_NEW ("a", "[", BCON_INT32 (1), BCON_INT32 (2), "]", "b", "whatever"); - BSON_ASSERT (mongoc_matcher_match (matcher, to_match)); - - /* query {a: [1, 2]} doesn't match {a: 1} */ - should_fail = BCON_NEW ("a", BCON_INT32 (1)); - BSON_ASSERT (!mongoc_matcher_match (matcher, should_fail)); - bson_destroy (should_fail); - - /* query {a: [1, 2]} doesn't match {a: [2, 1]} */ - should_fail = BCON_NEW ("a", "[", BCON_INT32 (2), BCON_INT32 (1), "]"); - BSON_ASSERT (!mongoc_matcher_match (matcher, should_fail)); - bson_destroy (should_fail); - - /* query {a: [1, 2]} doesn't match {a: [1, 2, 3]} */ - should_fail = - BCON_NEW ("a", "[", BCON_INT32 (1), BCON_INT32 (2), BCON_INT32 (3), "]"); - BSON_ASSERT (!mongoc_matcher_match (matcher, should_fail)); - bson_destroy (should_fail); - - /* query {a: [1, 2]} doesn't match {a: [1]} */ - should_fail = BCON_NEW ("a", "[", BCON_INT32 (1), "]"); - BSON_ASSERT (!mongoc_matcher_match (matcher, should_fail)); - - bson_destroy (to_match); - mongoc_matcher_destroy (matcher); - bson_destroy (query); - - /* empty array */ - query = BCON_NEW ("a", "[", "]"); - - /* {a: []} matches itself */ - matcher = mongoc_matcher_new (query, &error); - BSON_ASSERT (matcher); - - /* query {a: []} matches {a: [], b: "whatever"} */ - to_match = BCON_NEW ("a", "[", "]", "b", "whatever"); - BSON_ASSERT (mongoc_matcher_match (matcher, query)); - BSON_ASSERT (mongoc_matcher_match (matcher, to_match)); - - /* query {a: []} doesn't match {a: [1]} */ - BSON_ASSERT (!mongoc_matcher_match (matcher, should_fail)); - bson_destroy (should_fail); - - /* query {a: []} doesn't match empty document */ - should_fail = bson_new (); - BSON_ASSERT (!mongoc_matcher_match (matcher, should_fail)); - - bson_destroy (should_fail); - - /* query {a: []} doesn't match {a: null} */ - should_fail = BCON_NEW ("a", BCON_NULL); - BSON_ASSERT (!mongoc_matcher_match (matcher, should_fail)); - - bson_destroy (should_fail); - bson_destroy (query); - bson_destroy (to_match); - mongoc_matcher_destroy (matcher); -} - - -typedef struct compare_check { - const char *op; - int32_t doc; - int32_t query; - bool expected; -} compare_check; - - -static void -test_mongoc_matcher_compare (void) -{ - mongoc_matcher_t *matcher; - compare_check checks[] = {{"$gt", 2, 2, false}, - {"$gte", 2, 2, true}, - {"$lt", 2, 2, false}, - {"$lte", 2, 2, true}, - {"$ne", 2, 2, false}, - {NULL}}; - bson_t *doc; - bson_t *q; - int i; - - for (i = 0; checks[i].op; i++) { - doc = BCON_NEW ("a", BCON_INT32 (checks[i].doc)); - q = BCON_NEW ("a", "{", checks[i].op, BCON_INT32 (checks[i].query), "}"); - matcher = mongoc_matcher_new (q, NULL); - BSON_ASSERT (matcher); - BSON_ASSERT (mongoc_matcher_match (matcher, doc) == checks[i].expected); - bson_destroy (q); - bson_destroy (doc); - mongoc_matcher_destroy (matcher); - } -} - - -typedef struct { - const char *spec; - const char *doc; - bool match; -} logic_op_test_t; - - -static void -test_mongoc_matcher_logic_ops (void) -{ - logic_op_test_t tests[] = { - {"{\"$or\": [{\"a\": 1}, {\"b\": 2}]}", "{\"a\": 1}", true}, - {"{\"$or\": [{\"a\": 1}, {\"b\": 2}]}", "{\"b\": 2}", true}, - {"{\"$or\": [{\"a\": 1}, {\"b\": 2}]}", "{\"a\": 3}", false}, - {"{\"$or\": [{\"a\": {\"$gt\": 1}}, {\"a\": {\"$lt\": -1}}]}", - "{\"a\": 3}", - true}, - {"{\"$or\": [{\"a\": {\"$gt\": 1}}, {\"a\": {\"$lt\": -1}}]}", - "{\"a\": -2}", - true}, - {"{\"$or\": [{\"a\": {\"$gt\": 1}}, {\"a\": {\"$lt\": -1}}]}", - "{\"a\": 0}", - false}, - {"{\"$and\": [{\"a\": 1}, {\"b\": 2}]}", "{\"a\": 1, \"b\": 2}", true}, - {"{\"$and\": [{\"a\": 1}, {\"b\": 2}]}", "{\"a\": 1, \"b\": 1}", false}, - {"{\"$and\": [{\"a\": 1}, {\"b\": 2}]}", "{\"a\": 1}", false}, - {"{\"$and\": [{\"a\": 1}, {\"b\": 2}]}", "{\"b\": 2}", false}, - {"{\"$and\": [{\"a\": {\"$gt\": -1}}, {\"a\": {\"$lt\": 1}}]}", - "{\"a\": 0}", - true}, - {"{\"$and\": [{\"a\": {\"$gt\": -1}}, {\"a\": {\"$lt\": 1}}]}", - "{\"a\": -2}", - false}, - {"{\"$and\": [{\"a\": {\"$gt\": -1}}, {\"a\": {\"$lt\": 1}}]}", - "{\"a\": 1}", - false}, - }; - - int n_tests = sizeof tests / sizeof (logic_op_test_t); - int i; - logic_op_test_t test; - bson_t *spec; - bson_error_t error; - mongoc_matcher_t *matcher; - bson_t *doc; - bool r; - - for (i = 0; i < n_tests; i++) { - test = tests[i]; - spec = bson_new_from_json ((uint8_t *) test.spec, -1, &error); - if (!spec) { - fprintf (stderr, - "couldn't parse JSON query:\n\n%s\n\n%s\n", - test.spec, - error.message); - abort (); - } - - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - - doc = bson_new_from_json ((uint8_t *) test.doc, -1, &error); - if (!doc) { - fprintf (stderr, - "couldn't parse JSON document:\n\n%s\n\n%s\n", - test.doc, - error.message); - abort (); - } - - r = mongoc_matcher_match (matcher, doc); - if (test.match != r) { - fprintf (stderr, - "query:\n\n%s\n\nshould %shave matched:\n\n%s\n", - test.match ? "" : "not ", - test.spec, - test.doc); - abort (); - } - - mongoc_matcher_destroy (matcher); - bson_destroy (doc); - bson_destroy (spec); - } -} - - -static void -test_mongoc_matcher_bad_spec (void) -{ - bson_t *spec; - bson_error_t error; - mongoc_matcher_t *matcher; - - spec = BCON_NEW ("name", "{", "$abc", "invalid", "}"); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (!matcher); - BSON_ASSERT (error.domain == MONGOC_ERROR_MATCHER); - BSON_ASSERT (error.code == MONGOC_ERROR_MATCHER_INVALID); - bson_destroy (spec); - - spec = BCON_NEW ("name", "{", "$or", "", "}"); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (!matcher); - BSON_ASSERT (error.domain == MONGOC_ERROR_MATCHER); - BSON_ASSERT (error.code == MONGOC_ERROR_MATCHER_INVALID); - bson_destroy (spec); -} - - -static void -test_mongoc_matcher_eq_utf8 (void) -{ - bson_t *doc; - bson_t *spec; - bson_error_t error; - mongoc_matcher_t *matcher; - bool r; - - spec = BCON_NEW ("hello", "world"); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, spec); - BSON_ASSERT (r); - bson_destroy (spec); - mongoc_matcher_destroy (matcher); - - spec = BCON_NEW ("hello", "world"); - doc = BCON_NEW ("hello", BCON_NULL); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, doc); - BSON_ASSERT (!r); - bson_destroy (spec); - bson_destroy (doc); - mongoc_matcher_destroy (matcher); - - spec = BCON_NEW ("hello", "world"); - doc = BCON_NEW ("hello", BCON_UNDEFINED); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, doc); - BSON_ASSERT (!r); - bson_destroy (spec); - bson_destroy (doc); - mongoc_matcher_destroy (matcher); -} - - -static void -test_mongoc_matcher_eq_int32 (void) -{ - bson_t *spec; - bson_t *doc; - bson_error_t error; - mongoc_matcher_t *matcher; - bool r; - - spec = BCON_NEW ("hello", BCON_INT32 (1234)); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, spec); - BSON_ASSERT (r); - bson_destroy (spec); - mongoc_matcher_destroy (matcher); - - spec = BCON_NEW ("hello", BCON_INT32 (1234)); - doc = BCON_NEW ("hello", BCON_INT64 (1234)); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, doc); - BSON_ASSERT (r); - bson_destroy (spec); - bson_destroy (doc); - mongoc_matcher_destroy (matcher); - - spec = BCON_NEW ("hello", BCON_INT32 (1234)); - doc = BCON_NEW ("hello", BCON_INT64 (4321)); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, doc); - BSON_ASSERT (!r); - bson_destroy (spec); - bson_destroy (doc); - mongoc_matcher_destroy (matcher); -} - - -static void -test_mongoc_matcher_eq_int64 (void) -{ - bson_t *spec; - bson_t *doc; - bson_error_t error; - mongoc_matcher_t *matcher; - bool r; - - spec = BCON_NEW ("hello", BCON_INT64 (1234)); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, spec); - BSON_ASSERT (r); - bson_destroy (spec); - mongoc_matcher_destroy (matcher); - - spec = BCON_NEW ("hello", BCON_INT64 (1234)); - doc = BCON_NEW ("hello", BCON_INT64 (1234)); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, doc); - BSON_ASSERT (r); - bson_destroy (spec); - bson_destroy (doc); - mongoc_matcher_destroy (matcher); - - spec = BCON_NEW ("hello", BCON_INT64 (1234)); - doc = BCON_NEW ("hello", BCON_INT32 (4321)); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - r = mongoc_matcher_match (matcher, doc); - BSON_ASSERT (!r); - bson_destroy (spec); - bson_destroy (doc); - mongoc_matcher_destroy (matcher); -} - - -static void -test_mongoc_matcher_eq_doc (void) -{ - bson_t *spec; - bson_t *doc; - bson_error_t error; - mongoc_matcher_t *matcher; - - /* {doc: {a: 1}} matches itself */ - spec = BCON_NEW ("doc", "{", "a", BCON_INT32 (1), "}"); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - BSON_ASSERT (mongoc_matcher_match (matcher, spec)); - - /* {doc: {a: 1}} matches {doc: {a: 1}, foo: "whatever"} */ - doc = BCON_NEW ( - "doc", "{", "a", BCON_INT32 (1), "}", "foo", BCON_UTF8 ("whatever")); - BSON_ASSERT (mongoc_matcher_match (matcher, doc)); - bson_destroy (doc); - - /* {doc: {a: 1}} doesn't match {doc: 1} */ - doc = BCON_NEW ("doc", BCON_INT32 (1)); - BSON_ASSERT (!mongoc_matcher_match (matcher, doc)); - bson_destroy (doc); - - /* {doc: {a: 1}} doesn't match {doc: {}} */ - doc = BCON_NEW ("doc", "{", "}"); - BSON_ASSERT (!mongoc_matcher_match (matcher, doc)); - bson_destroy (doc); - - /* {doc: {a: 1}} doesn't match {doc: {a: 2}} */ - doc = BCON_NEW ("doc", "{", "a", BCON_INT32 (2), "}"); - BSON_ASSERT (!mongoc_matcher_match (matcher, doc)); - bson_destroy (doc); - - /* {doc: {a: 1}} doesn't match {doc: {b: 1}} */ - doc = BCON_NEW ("doc", "{", "b", BCON_INT32 (1), "}"); - BSON_ASSERT (!mongoc_matcher_match (matcher, doc)); - bson_destroy (doc); - - /* {doc: {a: 1}} doesn't match {doc: {a: 1, b: 1}} */ - doc = BCON_NEW ("doc", "{", "a", BCON_INT32 (1), "b", BCON_INT32 (1), "}"); - BSON_ASSERT (!mongoc_matcher_match (matcher, doc)); - bson_destroy (doc); - - /* {doc: {a: 1, b:1}} matches itself */ - bson_destroy (spec); - mongoc_matcher_destroy (matcher); - spec = BCON_NEW ("doc", "{", "a", BCON_INT32 (1), "b", BCON_INT32 (1), "}"); - matcher = mongoc_matcher_new (spec, &error); - BSON_ASSERT (matcher); - BSON_ASSERT (mongoc_matcher_match (matcher, spec)); - - /* {doc: {a: 1, b:1}} doesn't match {doc: {a: 1}} */ - doc = BCON_NEW ("doc", "{", "a", BCON_INT32 (1), "}"); - BSON_ASSERT (!mongoc_matcher_match (matcher, doc)); - bson_destroy (spec); - bson_destroy (doc); - mongoc_matcher_destroy (matcher); -} - - -static void -test_mongoc_matcher_in_basic (void) -{ - mongoc_matcher_t *matcher; - bson_error_t error; - bool r; - bson_t *spec; - bson_t doc = BSON_INITIALIZER; - - spec = BCON_NEW ("key", - "{", - "$in", - "[", - BCON_INT32 (1), - BCON_INT32 (2), - BCON_INT32 (3), - "]", - "}"); - - matcher = mongoc_matcher_new (spec, &error); - r = mongoc_matcher_match (matcher, &doc); - ASSERT (!r); - - bson_reinit (&doc); - bson_append_int32 (&doc, "key", 3, 1); - r = mongoc_matcher_match (matcher, &doc); - ASSERT (r); - - bson_reinit (&doc); - bson_append_int32 (&doc, "key", 3, 2); - r = mongoc_matcher_match (matcher, &doc); - ASSERT (r); - - bson_reinit (&doc); - bson_append_int32 (&doc, "key", 3, 3); - r = mongoc_matcher_match (matcher, &doc); - ASSERT (r); - - bson_reinit (&doc); - bson_append_int32 (&doc, "key", 3, 4); - r = mongoc_matcher_match (matcher, &doc); - ASSERT (!r); - - bson_destroy (&doc); - bson_destroy (spec); - mongoc_matcher_destroy (matcher); -} - -END_IGNORE_DEPRECATIONS; - -void -test_matcher_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Matcher/basic", test_mongoc_matcher_basic); - TestSuite_Add (suite, "/Matcher/array", test_mongoc_matcher_array); - TestSuite_Add (suite, "/Matcher/compare", test_mongoc_matcher_compare); - TestSuite_Add (suite, "/Matcher/logic", test_mongoc_matcher_logic_ops); - TestSuite_Add (suite, "/Matcher/bad_spec", test_mongoc_matcher_bad_spec); - TestSuite_Add (suite, "/Matcher/eq/utf8", test_mongoc_matcher_eq_utf8); - TestSuite_Add (suite, "/Matcher/eq/int32", test_mongoc_matcher_eq_int32); - TestSuite_Add (suite, "/Matcher/eq/int64", test_mongoc_matcher_eq_int64); - TestSuite_Add (suite, "/Matcher/eq/doc", test_mongoc_matcher_eq_doc); - TestSuite_Add (suite, "/Matcher/in/basic", test_mongoc_matcher_in_basic); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-max-staleness.c b/lib/mongoc/libmongoc/tests/test-mongoc-max-staleness.c deleted file mode 100644 index 9fe64844184708adebc3e8351181b5b60d181d8a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-max-staleness.c +++ /dev/null @@ -1,337 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-util-private.h> - -#include "mongoc/mongoc-client-private.h" - -#include "TestSuite.h" -#include "json-test.h" -#include "test-libmongoc.h" -#include "mock_server/mock-server.h" -#include "mock_server/future-functions.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "client-test-max-staleness" - - -static int64_t -get_max_staleness (const mongoc_client_t *client) -{ - const mongoc_read_prefs_t *prefs; - - prefs = mongoc_client_get_read_prefs (client); - - return mongoc_read_prefs_get_max_staleness_seconds (prefs); -} - - -/* the next few tests are from max-staleness-tests.rst */ -static void -test_mongoc_client_max_staleness (void) -{ - mongoc_client_t *client; - - client = mongoc_client_new (NULL); - ASSERT_CMPINT64 (get_max_staleness (client), ==, (int64_t) -1); - mongoc_client_destroy (client); - - client = mongoc_client_new ("mongodb://a/?" MONGOC_URI_READPREFERENCE - "=secondary"); - ASSERT_CMPINT64 (get_max_staleness (client), ==, (int64_t) -1); - mongoc_client_destroy (client); - - /* -1 is the default, means "no max staleness" */ - client = - mongoc_client_new ("mongodb://a/?" MONGOC_URI_MAXSTALENESSSECONDS "=-1"); - ASSERT_CMPINT64 (get_max_staleness (client), ==, (int64_t) -1); - mongoc_client_destroy (client); - - client = - mongoc_client_new ("mongodb://a/?" MONGOC_URI_READPREFERENCE - "=primary&" MONGOC_URI_MAXSTALENESSSECONDS "=-1"); - - ASSERT_CMPINT64 (get_max_staleness (client), ==, (int64_t) -1); - mongoc_client_destroy (client); - - /* no " MONGOC_URI_MAXSTALENESSSECONDS " with primary mode */ - capture_logs (true); - ASSERT (!mongoc_client_new ("mongodb://a/?" MONGOC_URI_MAXSTALENESSSECONDS - "=120")); - ASSERT (!mongoc_client_new ("mongodb://a/?" MONGOC_URI_READPREFERENCE - "=primary&" MONGOC_URI_MAXSTALENESSSECONDS - "=120")); - ASSERT_CAPTURED_LOG (MONGOC_URI_MAXSTALENESSSECONDS "=120", - MONGOC_LOG_LEVEL_WARNING, - "Invalid readPreferences"); - - capture_logs (true); - - /* zero is prohibited */ - client = mongoc_client_new ("mongodb://a/?" MONGOC_URI_READPREFERENCE - "=nearest&" MONGOC_URI_MAXSTALENESSSECONDS "=0"); - - ASSERT_CAPTURED_LOG ( - MONGOC_URI_MAXSTALENESSSECONDS "=0", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported value for \"" MONGOC_URI_MAXSTALENESSSECONDS "\": \"0\""); - - ASSERT_CMPINT64 (get_max_staleness (client), ==, (int64_t) -1); - mongoc_client_destroy (client); - - client = mongoc_client_new ("mongodb://a/?" MONGOC_URI_MAXSTALENESSSECONDS - "=120&" MONGOC_URI_READPREFERENCE "=secondary"); - - ASSERT_CMPINT64 (get_max_staleness (client), ==, (int64_t) 120); - mongoc_client_destroy (client); - - /* float is ignored */ - capture_logs (true); - ASSERT (!mongoc_client_new ("mongodb://a/?" MONGOC_URI_READPREFERENCE - "=secondary&" MONGOC_URI_MAXSTALENESSSECONDS - "=10.5")); - - ASSERT_CAPTURED_LOG (MONGOC_URI_MAXSTALENESSSECONDS "=10.5", - MONGOC_LOG_LEVEL_WARNING, - "Invalid " MONGOC_URI_MAXSTALENESSSECONDS); - - /* 1 is allowed, it'll be rejected once we begin server selection */ - client = - mongoc_client_new ("mongodb://a/?" MONGOC_URI_READPREFERENCE - "=secondary&" MONGOC_URI_MAXSTALENESSSECONDS "=1"); - - ASSERT_EQUAL_DOUBLE (get_max_staleness (client), 1); - mongoc_client_destroy (client); -} - - -static void -test_mongos_max_staleness_read_pref (void) -{ - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_read_prefs_t *prefs; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (5 /* maxWireVersion */); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - /* count command with mode "secondary", no " MONGOC_URI_MAXSTALENESSSECONDS " - */ - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_collection_set_read_prefs (collection, prefs); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, NULL, 0, 0, NULL, &error); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$" MONGOC_URI_READPREFERENCE "': {'mode': 'secondary', " - " 'maxStalenessSeconds': {'$exists': false}}}"); - - mock_server_replies_simple (request, "{'ok': 1, 'n': 1}"); - ASSERT_OR_PRINT (1 == future_get_int64_t (future), error); - - request_destroy (request); - future_destroy (future); - - /* count command with mode "secondary". " MONGOC_URI_MAXSTALENESSSECONDS "=1 - * is allowed by - * client, although in real life mongos will reject it */ - mongoc_read_prefs_set_max_staleness_seconds (prefs, 1); - mongoc_collection_set_read_prefs (collection, prefs); - - mongoc_collection_set_read_prefs (collection, prefs); - future = future_collection_count ( - collection, MONGOC_QUERY_NONE, NULL, 0, 0, NULL, &error); - request = mock_server_receives_command ( - server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'$readPreference': {'mode': 'secondary', 'maxStalenessSeconds': 1}}", - NULL); - - mock_server_replies_simple (request, "{'ok': 1, 'n': 1}"); - ASSERT_OR_PRINT (1 == future_get_int64_t (future), error); - - request_destroy (request); - future_destroy (future); - - mongoc_read_prefs_destroy (prefs); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -_test_last_write_date (bool pooled) -{ - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - bool r; - mongoc_server_description_t *s0, *s1; - int64_t delta; - - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - test_framework_set_pool_ssl_opts (pool); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - } - mongoc_uri_destroy (uri); - - collection = get_test_collection (client, "test_last_write_date"); - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - _mongoc_usleep (2000 * 1000); - s0 = mongoc_topology_select (client->topology, MONGOC_SS_READ, NULL, &error); - ASSERT_OR_PRINT (s0, error); - - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - _mongoc_usleep (2000 * 1000); - s1 = mongoc_topology_select (client->topology, MONGOC_SS_READ, NULL, &error); - ASSERT_OR_PRINT (s1, error); - ASSERT_CMPINT64 (s1->last_write_date_ms, !=, (int64_t) -1); - - /* lastWriteDate increased by roughly one second - be lenient, just check - * it increased by less than 10 seconds */ - delta = s1->last_write_date_ms - s0->last_write_date_ms; - ASSERT_CMPINT64 (delta, >, (int64_t) 0); - ASSERT_CMPINT64 (delta, <, (int64_t) 10 * 1000); - - mongoc_server_description_destroy (s0); - mongoc_server_description_destroy (s1); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - - -static void -test_last_write_date (void *ctx) -{ - _test_last_write_date (false); -} - - -static void -test_last_write_date_pooled (void *ctx) -{ - _test_last_write_date (true); -} - - -/* run only if wire version is older than 5 */ -static void -_test_last_write_date_absent (bool pooled) -{ - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - mongoc_server_description_t *sd; - - if (pooled) { - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - } - - sd = mongoc_topology_select (client->topology, MONGOC_SS_READ, NULL, &error); - ASSERT_OR_PRINT (sd, error); - - /* lastWriteDate absent */ - ASSERT_CMPINT64 (sd->last_write_date_ms, ==, (int64_t) -1); - - mongoc_server_description_destroy (sd); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - - -static void -test_last_write_date_absent (void *ctx) -{ - _test_last_write_date_absent (false); -} - - -static void -test_last_write_date_absent_pooled (void *ctx) -{ - _test_last_write_date_absent (true); -} - - -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - test_framework_resolve_path (JSON_DIR "/max_staleness", resolved); - install_json_test_suite (suite, resolved, &test_server_selection_logic_cb); -} - -void -test_client_max_staleness_install (TestSuite *suite) -{ - test_all_spec_tests (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", - test_last_write_date, - NULL, - NULL, - test_framework_skip_if_not_rs_version_5, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Client/last_write_date/pooled", - test_last_write_date_pooled, - NULL, - NULL, - test_framework_skip_if_not_rs_version_5, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Client/last_write_date_absent", - test_last_write_date_absent, - NULL, - NULL, - test_framework_skip_if_rs_version_5); - TestSuite_AddFull (suite, - "/Client/last_write_date_absent/pooled", - test_last_write_date_absent_pooled, - NULL, - NULL, - test_framework_skip_if_rs_version_5); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-mongos-pinning.c b/lib/mongoc/libmongoc/tests/test-mongoc-mongos-pinning.c deleted file mode 100644 index 79348152de06fb980f9a0e5b99634543a8425b40..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-mongos-pinning.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2019-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 <mongoc/mongoc.h> -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-host-list-private.h" - -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "test-conveniences.h" - -static void -add_multiple_mongoses (mongoc_uri_t *uri) -{ - bson_error_t error; - - /* TODO CDRIVER-3285, fix this to be dynamic */ - ASSERT_OR_PRINT ( - mongoc_uri_upsert_host_and_port (uri, "localhost:27017", &error), error); - ASSERT_OR_PRINT ( - mongoc_uri_upsert_host_and_port (uri, "localhost:27018", &error), error); -} - -static void -test_new_transaction_unpins (void *ctx) -{ - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_collection_t *coll; - bson_error_t error; - mongoc_client_session_t *session; - mongoc_host_list_t *servers = NULL; - mongoc_cursor_t *cursor; - bson_t *opts; - int i; - - uri = test_framework_get_uri (); - add_multiple_mongoses (uri); - - /* Increase localThresholdMS to avoid false positives. Nodes - will be discovered with the first call to server selection. */ - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_LOCALTHRESHOLDMS, 1000); - client = mongoc_client_new_from_uri (uri); - - /* Create a collection. */ - coll = mongoc_client_get_collection (client, "test", "test"); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson ("{}"), NULL, NULL, &error), - error); - - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session != NULL, error); - - opts = bson_new (); - ASSERT_OR_PRINT (mongoc_client_session_append (session, opts, &error), error); - - /* Under one transaction, insert a document. */ - ASSERT_OR_PRINT ( - mongoc_client_session_start_transaction (session, NULL, &error), error); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson ("{}"), opts, NULL, &error), - error); - ASSERT_OR_PRINT ( - mongoc_client_session_commit_transaction (session, NULL, &error), error); - - /* Then, 50 times, start new transactions. Each time we start a new - transaction, the session should be un-pinned, so by statistics, - we should balance the new transactions across both mongos. */ - for (i = 0; i < 50; i++) { - mongoc_host_list_t cursor_host; - const bson_t *doc; - - ASSERT_OR_PRINT ( - mongoc_client_session_start_transaction (session, NULL, &error), - error); - - cursor = - mongoc_collection_find_with_opts (coll, tmp_bson ("{}"), opts, NULL); - ASSERT (mongoc_cursor_next (cursor, &doc)); - mongoc_cursor_get_host (cursor, &cursor_host); - _mongoc_host_list_upsert (&servers, &cursor_host); - - ASSERT_OR_PRINT ( - mongoc_client_session_commit_transaction (session, NULL, &error), - error); - - mongoc_cursor_destroy (cursor); - } - - ASSERT (_mongoc_host_list_length (servers) == 2); - - bson_destroy (opts); - _mongoc_host_list_destroy_all (servers); - mongoc_uri_destroy (uri); - mongoc_client_session_destroy (session); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -static void -test_non_transaction_unpins (void *ctx) -{ - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_collection_t *coll; - bson_error_t error; - mongoc_client_session_t *session; - mongoc_host_list_t *servers = NULL; - mongoc_cursor_t *cursor; - bson_t *opts; - int i; - - uri = test_framework_get_uri (); - add_multiple_mongoses (uri); - - /* Increase localThresholdMS to avoid false positives. Nodes - will be discovered with the first call to server selection. */ - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_LOCALTHRESHOLDMS, 1000); - client = mongoc_client_new_from_uri (uri); - - /* Create a collection. */ - coll = mongoc_client_get_collection (client, "test", "test"); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson ("{}"), NULL, NULL, &error), - error); - - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session != NULL, error); - - opts = bson_new (); - ASSERT_OR_PRINT (mongoc_client_session_append (session, opts, &error), error); - - /* Under one transaction, insert a document. */ - ASSERT_OR_PRINT ( - mongoc_client_session_start_transaction (session, NULL, &error), error); - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson ("{}"), opts, NULL, &error), - error); - ASSERT_OR_PRINT ( - mongoc_client_session_commit_transaction (session, NULL, &error), error); - - /* After our initial transaction, the session should become un-pinned - if we run further operations on the session. By statistics, - new operations should balance across both mongos. */ - for (i = 0; i < 50; i++) { - mongoc_host_list_t cursor_host; - const bson_t *doc; - - cursor = - mongoc_collection_find_with_opts (coll, tmp_bson ("{}"), opts, NULL); - ASSERT (mongoc_cursor_next (cursor, &doc)); - mongoc_cursor_get_host (cursor, &cursor_host); - _mongoc_host_list_upsert (&servers, &cursor_host); - - mongoc_cursor_destroy (cursor); - } - - ASSERT (_mongoc_host_list_length (servers) == 2); - - bson_destroy (opts); - _mongoc_host_list_destroy_all (servers); - mongoc_uri_destroy (uri); - mongoc_client_session_destroy (session); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); -} - -void -test_mongos_pinning_install (TestSuite *suite) -{ - TestSuite_AddFull (suite, - "/mongos_pinning/new_transaction_unpins", - test_new_transaction_unpins, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto, - test_framework_skip_if_max_wire_version_less_than_8, - test_framework_skip_if_not_mongos); - - TestSuite_AddFull (suite, - "/mongos_pinning/non_transaction_unpins", - test_non_transaction_unpins, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto, - test_framework_skip_if_max_wire_version_less_than_8, - test_framework_skip_if_not_mongos); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-opts.c b/lib/mongoc/libmongoc/tests/test-mongoc-opts.c deleted file mode 100644 index 5141ad80ff49a59f6a07662a884756f5bf688a41..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-opts.c +++ /dev/null @@ -1,1022 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-find-and-modify-private.h> -#include <mock_server/future.h> -#include <mock_server/future-value.h> - -#include "TestSuite.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" -#include "mock_server/mock-rs.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - - -/* - * Test that all "with_opts" functions that accept readConcern, writeConcern, - * and/or readPreference properly implement inheritance. For each of these - * options, test that the function inherits the option from its source object - * (e.g., mongoc_collection_watch inherits readConcern from the collection), - * that the function uses the option from "opts" if present, and that "opts" - * overrides the option from the source object. - * - * listDatabases, listCollections, and listIndexes don't use any of these - * options, so don't test their helpers: - * - * mongoc_client_find_databases_with_opts - * mongoc_client_get_database_names_with_opts - * mongoc_database_find_collections_with_opts - * mongoc_database_get_collection_names_with_opts - * mongoc_collection_find_indexes_with_opts - */ - -/* kinds of options */ -typedef enum { - OPT_READ_CONCERN, - OPT_WRITE_CONCERN, - OPT_READ_PREFS, -} opt_type_t; - - -/* objects on which options can be set */ -typedef enum { - OPT_SOURCE_NONE = 0, - OPT_SOURCE_FUNC = 1 << 0, - OPT_SOURCE_COLL = 1 << 1, - OPT_SOURCE_DB = 1 << 2, - OPT_SOURCE_CLIENT = 1 << 3, -} opt_source_t; - - -/* for mongoc_bulk_operation_t tests */ -typedef bool (*bulk_op_t) (mongoc_bulk_operation_t *bulk, - bson_error_t *error, - bson_t *cmd /* OUT */); - - -struct _opt_inheritance_test_t; - - -typedef struct { - struct _opt_inheritance_test_t *test; - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_collection_t *collection; - const mongoc_read_prefs_t *prefs; - const bson_t *opts; - /* find, aggregate, etc. store the cursor here while running */ - mongoc_cursor_t *cursor; - bson_error_t error; - /* allow func_with_opts_t functions to store data and destroy it later */ - void *data; - void (*destructor) (void *data); -} func_ctx_t; - - -typedef future_t *(func_with_opts_t) (func_ctx_t *ctx, bson_t *cmd); - - -typedef struct _opt_inheritance_test_t { - opt_source_t opt_source; - func_with_opts_t *func_with_opts; - const char *func_name; - opt_type_t opt_type; - int n_sections; - /* for mongoc_bulk_operation_t tests */ - bulk_op_t bulk_op; -} opt_inheritance_test_t; - - -static void -func_ctx_init (func_ctx_t *ctx, - opt_inheritance_test_t *test, - mongoc_client_t *client, - mongoc_database_t *db, - mongoc_collection_t *collection, - const mongoc_read_prefs_t *prefs, - const bson_t *opts) -{ - ctx->test = test; - ctx->client = client; - ctx->db = db; - ctx->collection = collection; - ctx->prefs = prefs; - ctx->opts = opts; - ctx->cursor = NULL; - memset (&ctx->error, 0, sizeof (ctx->error)); - ctx->data = NULL; - ctx->destructor = NULL; -} - - -static void -func_ctx_cleanup (func_ctx_t *ctx) -{ - mongoc_cursor_destroy (ctx->cursor); - if (ctx->destructor) { - ctx->destructor (ctx->data); - } -} - - -/* if type is e.g. "collection", set readConcern level collection, writeConcern - * w=collection, readPreference tags [{collection: "yes"}] */ -#define SET_OPT_PREAMBLE(_type) \ - mongoc_read_concern_t *rc = mongoc_read_concern_new (); \ - mongoc_write_concern_t *wc = mongoc_write_concern_new (); \ - mongoc_read_prefs_t *prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); \ - \ - mongoc_read_concern_set_level (rc, #_type); \ - mongoc_write_concern_set_wtag (wc, #_type); \ - mongoc_read_prefs_set_tags (prefs, tmp_bson ("[{'%s': 'yes'}]", #_type)) - -#define SET_OPT_CLEANUP \ - mongoc_read_concern_destroy (rc); \ - mongoc_write_concern_destroy (wc); \ - mongoc_read_prefs_destroy (prefs); - -#define SET_OPT(_type) \ - static void set_##_type##_opt (mongoc_##_type##_t *obj, \ - opt_type_t opt_type) \ - { \ - SET_OPT_PREAMBLE (_type); \ - \ - switch (opt_type) { \ - case OPT_READ_CONCERN: \ - mongoc_##_type##_set_read_concern (obj, rc); \ - break; \ - case OPT_WRITE_CONCERN: \ - mongoc_##_type##_set_write_concern (obj, wc); \ - break; \ - case OPT_READ_PREFS: \ - mongoc_##_type##_set_read_prefs (obj, prefs); \ - break; \ - default: \ - abort (); \ - } \ - \ - SET_OPT_CLEANUP; \ - } - -SET_OPT (client) -SET_OPT (database) -SET_OPT (collection) - - -static void -set_func_opt (bson_t *opts, - mongoc_read_prefs_t **prefs_ptr, - opt_type_t opt_type) -{ - SET_OPT_PREAMBLE (function); - - switch (opt_type) { - case OPT_READ_CONCERN: - BSON_ASSERT (mongoc_read_concern_append (rc, opts)); - break; - case OPT_WRITE_CONCERN: - BSON_ASSERT (mongoc_write_concern_append (wc, opts)); - break; - case OPT_READ_PREFS: - *prefs_ptr = mongoc_read_prefs_copy (prefs); - break; - default: - abort (); - } - - SET_OPT_CLEANUP; -} - - -/* add BSON we expect to be included in a command due to an inherited option. - * e.g., when "count" inherits readConcern from the DB, it should include - * readConcern: {level: 'database'} in the command body. */ -void -add_expected_opt (opt_source_t opt_source, opt_type_t opt_type, bson_t *cmd) -{ - const char *source_name; - bson_t *opt; - - if (opt_source & OPT_SOURCE_FUNC) { - source_name = "function"; - } else if (opt_source & OPT_SOURCE_COLL) { - source_name = "collection"; - } else if (opt_source & OPT_SOURCE_DB) { - source_name = "database"; - } else if (opt_source & OPT_SOURCE_CLIENT) { - source_name = "client"; - } else { - MONGOC_ERROR ("opt_json called with OPT_SOURCE_NONE"); - abort (); - } - - switch (opt_type) { - case OPT_READ_CONCERN: - opt = tmp_bson ("{'readConcern': {'level': '%s'}}", source_name); - break; - case OPT_WRITE_CONCERN: - opt = tmp_bson ("{'writeConcern': {'w': '%s'}}", source_name); - break; - case OPT_READ_PREFS: - opt = tmp_bson ( - "{'$readPreference': {'mode': 'secondary', 'tags': [{'%s': 'yes'}]}}", - source_name); - break; - default: - abort (); - } - - bson_concat (cmd, opt); -} - - -static const char * -opt_type_name (opt_type_t opt_type) -{ - switch (opt_type) { - case OPT_READ_CONCERN: - return "readConcern"; - case OPT_WRITE_CONCERN: - return "writeConcern"; - case OPT_READ_PREFS: - return "readPrefs"; - default: - abort (); - } -} - - -static void -cleanup_future (future_t *future) -{ - future_value_t v; - - BSON_ASSERT (future_wait (future)); - - v = future->return_value; - if (v.type == future_value_mongoc_change_stream_ptr_type) { - mongoc_change_stream_destroy (v.value.mongoc_change_stream_ptr_value); - } else if (v.type == future_value_char_ptr_ptr_type) { - bson_strfreev (v.value.char_ptr_ptr_value); - } - - future_destroy (future); -} - - -/********************************************************************** - * - * func_with_opts_t implementations for client - * - **********************************************************************/ - -static future_t * -client_read_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_INT32 (cmd, "foo", 1); - return future_client_read_command_with_opts (ctx->client, - "db", - tmp_bson ("{'foo': 1}"), - ctx->prefs, - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -client_write_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "foo", "collection"); - return future_client_write_command_with_opts ( - ctx->client, - "db", - tmp_bson ("{'foo': 'collection'}"), - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -client_read_write_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "foo", "collection"); - return future_client_read_write_command_with_opts ( - ctx->client, - "db", - tmp_bson ("{'foo': 'collection'}"), - ctx->prefs, - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -client_watch (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_INT32 (cmd, "aggregate", 1); - return future_client_watch (ctx->client, tmp_bson ("{}"), ctx->opts); -} - - -/********************************************************************** - * - * func_with_opts_t implementations for database - * - **********************************************************************/ - -static future_t * -db_drop (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_INT32 (cmd, "dropDatabase", 1); - return future_database_drop_with_opts (ctx->db, ctx->opts, &ctx->error); -} - - -static future_t * -db_read_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "foo", "db"); - return future_database_read_command_with_opts (ctx->db, - tmp_bson ("{'foo': 'db'}"), - ctx->prefs, - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -db_write_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "foo", "db"); - return future_database_write_command_with_opts ( - ctx->db, tmp_bson ("{'foo': 'db'}"), ctx->opts, NULL, &ctx->error); -} - - -static future_t * -db_read_write_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "foo", "db"); - return future_database_read_write_command_with_opts ( - ctx->db, - tmp_bson ("{'foo': 'db'}"), - ctx->prefs, - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -db_watch (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_INT32 (cmd, "aggregate", 1); - return future_database_watch (ctx->db, tmp_bson ("{}"), ctx->opts); -} - - -/********************************************************************** - * - * func_with_opts_t implementations for collection - * - **********************************************************************/ - -static future_t * -aggregate (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "aggregate", "collection"); - ctx->cursor = - mongoc_collection_aggregate (ctx->collection, - MONGOC_QUERY_NONE, - tmp_bson ("{'pipeline': [{'$out': 'foo'}]}"), - ctx->opts, - ctx->prefs); - - /* use ctx->data as the bson_t** out-param to mongoc_cursor_next () */ - return future_cursor_next (ctx->cursor, (const bson_t **) &ctx->data); -} - - -static future_t * -aggregate_raw_pipeline (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "aggregate", "collection"); - ctx->cursor = mongoc_collection_aggregate (ctx->collection, - MONGOC_QUERY_NONE, - tmp_bson ("[{'$out': 'foo'}]"), - ctx->opts, - ctx->prefs); - - /* use ctx->data as the bson_t** out-param to mongoc_cursor_next () */ - return future_cursor_next (ctx->cursor, (const bson_t **) &ctx->data); -} - - -static future_t * -collection_drop (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "drop", "collection"); - return future_collection_drop_with_opts ( - ctx->collection, ctx->opts, &ctx->error); -} - - -static future_t * -collection_read_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "foo", "collection"); - return future_collection_read_command_with_opts ( - ctx->collection, - tmp_bson ("{'foo': 'collection'}"), - ctx->prefs, - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -collection_read_write_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "foo", "collection"); - return future_collection_read_write_command_with_opts ( - ctx->collection, - tmp_bson ("{'foo': 'collection'}"), - NULL, - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -collection_write_cmd (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "foo", "collection"); - return future_collection_write_command_with_opts ( - ctx->collection, - tmp_bson ("{'foo': 'collection'}"), - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -collection_watch (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "aggregate", "collection"); - return future_collection_watch (ctx->collection, tmp_bson ("{}"), ctx->opts); -} - - -static future_t * -count (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "count", "collection"); - return future_collection_count_with_opts (ctx->collection, - MONGOC_QUERY_NONE, - NULL, - 0, - 0, - ctx->opts, - ctx->prefs, - &ctx->error); -} - - -static future_t * -count_documents (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "aggregate", "collection"); - return future_collection_count_documents (ctx->collection, - tmp_bson ("{}"), - ctx->opts, - ctx->prefs, - NULL, - &ctx->error); -} - - -static future_t * -create_index (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "createIndexes", "collection"); - return future_collection_create_index_with_opts ( - ctx->collection, tmp_bson ("{}"), NULL, ctx->opts, NULL, &ctx->error); -} - - -static future_t * -drop_index (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "dropIndexes", "collection"); - return future_collection_drop_index_with_opts ( - ctx->collection, "index name", ctx->opts, &ctx->error); -} - - -static future_t * -estimated_document_count (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "count", "collection"); - return future_collection_estimated_document_count ( - ctx->collection, ctx->opts, ctx->prefs, NULL, &ctx->error); -} - - -static future_t * -find (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "find", "collection"); - ctx->cursor = mongoc_collection_find_with_opts ( - ctx->collection, tmp_bson ("{}"), ctx->opts, ctx->prefs); - - /* use ctx->data as the bson_t** out-param to mongoc_cursor_next () */ - return future_cursor_next (ctx->cursor, (const bson_t **) &ctx->data); -} - - -static void -find_and_modify_cleanup (void *data) -{ - mongoc_find_and_modify_opts_destroy ((mongoc_find_and_modify_opts_t *) data); -} - - -static future_t * -find_and_modify (func_ctx_t *ctx, bson_t *cmd) -{ - mongoc_find_and_modify_opts_t *fam; - - BSON_APPEND_UTF8 (cmd, "findAndModify", "collection"); - fam = mongoc_find_and_modify_opts_new (); - bson_concat (&fam->extra, ctx->opts); - - /* destroy the mongoc_find_and_modify_opts_t later */ - ctx->data = fam; - ctx->destructor = find_and_modify_cleanup; - - return future_collection_find_and_modify_with_opts ( - ctx->collection, tmp_bson ("{}"), fam, NULL, &ctx->error); -} - - -/********************************************************************** - * - * func_with_opts_t implementations for collection write helpers - * - **********************************************************************/ - -static future_t * -delete_many (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "delete", "collection"); - BSON_ASSERT (!ctx->prefs); - return future_collection_delete_many ( - ctx->collection, tmp_bson ("{}"), ctx->opts, NULL, &ctx->error); -} - - -static future_t * -delete_one (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "delete", "collection"); - BSON_ASSERT (!ctx->prefs); - return future_collection_delete_one ( - ctx->collection, tmp_bson ("{}"), ctx->opts, NULL, &ctx->error); -} - - -static future_t * -insert_many (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "insert", "collection"); - BSON_ASSERT (!ctx->prefs); - /* the "array" of input documents must be a valid pointer, stage it here */ - ctx->data = tmp_bson ("{}"); - return future_collection_insert_many (ctx->collection, - (const bson_t **) &ctx->data, - 1, - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -insert_one (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "insert", "collection"); - BSON_ASSERT (!ctx->prefs); - return future_collection_insert_one ( - ctx->collection, tmp_bson ("{}"), ctx->opts, NULL, &ctx->error); -} - - -static future_t * -replace_one (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "update", "collection"); - BSON_ASSERT (!ctx->prefs); - return future_collection_replace_one (ctx->collection, - tmp_bson ("{}"), - tmp_bson ("{}"), - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -update_many (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "update", "collection"); - BSON_ASSERT (!ctx->prefs); - return future_collection_update_many (ctx->collection, - tmp_bson ("{}"), - tmp_bson ("{}"), - ctx->opts, - NULL, - &ctx->error); -} - - -static future_t * -update_one (func_ctx_t *ctx, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "update", "collection"); - BSON_ASSERT (!ctx->prefs); - return future_collection_update_one (ctx->collection, - tmp_bson ("{}"), - tmp_bson ("{}"), - ctx->opts, - NULL, - &ctx->error); -} - - -/********************************************************************** - * - * mongoc_bulk_operation_t test functions - * - **********************************************************************/ - -static void -bulk_operation_cleanup (void *data) -{ - mongoc_bulk_operation_destroy ((mongoc_bulk_operation_t *) data); -} - - -static future_t * -bulk_exec (func_ctx_t *ctx, bson_t *cmd) -{ - mongoc_bulk_operation_t *bulk; - bson_error_t error; - bool r; - - bulk = mongoc_collection_create_bulk_operation_with_opts (ctx->collection, - ctx->opts); - - ctx->data = bulk; - ctx->destructor = bulk_operation_cleanup; - - r = ctx->test->bulk_op (bulk, &error, cmd); - ASSERT_OR_PRINT (r, error); - - return future_bulk_operation_execute (bulk, NULL /* reply */, &ctx->error); -} - - -static bool -bulk_insert (mongoc_bulk_operation_t *bulk, bson_error_t *error, bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "insert", "collection"); - return mongoc_bulk_operation_insert_with_opts ( - bulk, tmp_bson ("{}"), NULL, error); -} - - -static bool -bulk_remove_many (mongoc_bulk_operation_t *bulk, - bson_error_t *error, - bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "delete", "collection"); - return mongoc_bulk_operation_remove_many_with_opts ( - bulk, tmp_bson ("{}"), NULL, error); -} - - -static bool -bulk_remove_one (mongoc_bulk_operation_t *bulk, - bson_error_t *error, - bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "delete", "collection"); - return mongoc_bulk_operation_remove_one_with_opts ( - bulk, tmp_bson ("{}"), NULL, error); -} - -static bool -bulk_replace_one (mongoc_bulk_operation_t *bulk, - bson_error_t *error, - bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "update", "collection"); - return mongoc_bulk_operation_replace_one_with_opts ( - bulk, tmp_bson ("{}"), tmp_bson ("{}"), NULL, error); -} - - -static bool -bulk_update_many (mongoc_bulk_operation_t *bulk, - bson_error_t *error, - bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "update", "collection"); - return mongoc_bulk_operation_update_many_with_opts ( - bulk, tmp_bson ("{}"), tmp_bson ("{}"), NULL, error); -} - - -static bool -bulk_update_one (mongoc_bulk_operation_t *bulk, - bson_error_t *error, - bson_t *cmd) -{ - BSON_APPEND_UTF8 (cmd, "update", "collection"); - return mongoc_bulk_operation_update_one_with_opts ( - bulk, tmp_bson ("{}"), tmp_bson ("{}"), NULL, error); -} - - -static void -test_func_inherits_opts (void *ctx) -{ - opt_inheritance_test_t *test = (opt_inheritance_test_t *) ctx; - - /* for example, test mongoc_collection_find_with_opts with no read pref, - * with a read pref set on the collection (OPT_SOURCE_COLL), with an explicit - * read pref (OPT_SOURCE_FUNC), or with one read pref on the collection and - * a different one passed explicitly */ - opt_source_t source_matrix[] = {OPT_SOURCE_NONE, - test->opt_source, - OPT_SOURCE_FUNC, - test->opt_source | OPT_SOURCE_FUNC}; - - size_t i; - func_ctx_t func_ctx; - mock_rs_t *rs; - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_collection_t *collection; - bson_t opts = BSON_INITIALIZER; - mongoc_read_prefs_t *func_prefs = NULL; - future_t *future; - request_t *request; - bson_t cmd = BSON_INITIALIZER; - bool expect_secondary; - bson_error_t error; - - /* one primary, one secondary */ - rs = mock_rs_with_autoismaster (WIRE_VERSION_OP_MSG, true, 1, 0); - /* we use read pref tags like "collection": "yes" to verify where the - * pref was inherited from; ensure all secondaries match all tags */ - mock_rs_tag_secondary (rs, - 0, - tmp_bson ("{'client': 'yes'," - " 'database': 'yes'," - " 'collection': 'yes'," - " 'function': 'yes'}")); - - mock_rs_run (rs); - - /* iterate over all combinations of options sources: e.g., an option set on - * collection and not function, on function not collection, both, neither */ - for (i = 0; i < sizeof (source_matrix) / (sizeof (opt_source_t)); i++) { - expect_secondary = false; - func_prefs = NULL; - bson_reinit (&cmd); - bson_reinit (&opts); - - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - if (source_matrix[i] & OPT_SOURCE_CLIENT) { - set_client_opt (client, test->opt_type); - } - - db = mongoc_client_get_database (client, "database"); - if (source_matrix[i] & OPT_SOURCE_DB) { - set_database_opt (db, test->opt_type); - } - - collection = mongoc_database_get_collection (db, "collection"); - if (source_matrix[i] & OPT_SOURCE_COLL) { - set_collection_opt (collection, test->opt_type); - } - - if (source_matrix[i] & OPT_SOURCE_FUNC) { - set_func_opt (&opts, &func_prefs, test->opt_type); - } - - func_ctx_init ( - &func_ctx, test, client, db, collection, func_prefs, &opts); - - /* A warning is thrown if an aggregate command with $out attempts to write - * to a secondary */ - capture_logs (true); - /* func_with_opts creates expected "cmd", like {insert: 'collection'} */ - future = test->func_with_opts (&func_ctx, &cmd); - capture_logs (false); - - if (source_matrix[i] != OPT_SOURCE_NONE) { - if (strstr (test->func_name, "aggregate")) { - if (test->opt_type != OPT_READ_PREFS) { - add_expected_opt (source_matrix[i], test->opt_type, &cmd); - } - } else { - add_expected_opt (source_matrix[i], test->opt_type, &cmd); - expect_secondary = test->opt_type == OPT_READ_PREFS; - } - } - - /* write commands send two OP_MSG sections */ - if (test->n_sections == 2) { - request = mock_rs_receives_msg (rs, 0, &cmd, tmp_bson ("{}")); - } else { - request = mock_rs_receives_msg (rs, 0, &cmd); - } - - if (expect_secondary) { - BSON_ASSERT (mock_rs_request_is_to_secondary (rs, request)); - } else { - BSON_ASSERT (mock_rs_request_is_to_primary (rs, request)); - } - - if (func_ctx.cursor) { - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': []}}"); - - BSON_ASSERT (!future_get_bool (future)); - future_destroy (future); - ASSERT_OR_PRINT (!mongoc_cursor_error (func_ctx.cursor, &error), - error); - } else { - mock_server_replies_simple (request, "{'ok': 1}"); - cleanup_future (future); - } - - request_destroy (request); - mongoc_read_prefs_destroy (func_prefs); - func_ctx_cleanup (&func_ctx); - mongoc_collection_destroy (collection); - mongoc_database_destroy (db); - mongoc_client_destroy (client); - } - - bson_destroy (&cmd); - bson_destroy (&opts); - mock_rs_destroy (rs); -} - - -/* commands that send one OP_MSG section */ -#define OPT_TEST(_opt_source, _func, _opt_type) \ - { \ - OPT_SOURCE_##_opt_source, _func, #_func, OPT_##_opt_type, 1 \ - } - - -/* write commands commands that send two OP_MSG sections */ -#define OPT_WRITE_TEST(_func) \ - { \ - OPT_SOURCE_COLL, _func, #_func, OPT_WRITE_CONCERN, 2 \ - } - - -/* mongoc_bulk_operation_t functions */ -#define OPT_BULK_TEST(_bulk_op) \ - { \ - OPT_SOURCE_COLL, bulk_exec, #_bulk_op, OPT_WRITE_CONCERN, 2, _bulk_op \ - } - - -static opt_inheritance_test_t gInheritanceTests[] = { - /* - * client functions - */ - OPT_TEST (CLIENT, client_read_cmd, READ_CONCERN), - OPT_TEST (CLIENT, client_read_cmd, READ_PREFS), - /* read_write_command functions deliberately ignore read prefs */ - OPT_TEST (CLIENT, client_read_write_cmd, READ_CONCERN), - OPT_TEST (CLIENT, client_read_write_cmd, WRITE_CONCERN), - /* watch helpers don't take explicit readPref */ - OPT_TEST (CLIENT, client_watch, READ_CONCERN), - OPT_TEST (CLIENT, client_write_cmd, WRITE_CONCERN), - - /* - * database functions - */ - OPT_TEST (DB, db_drop, WRITE_CONCERN), - OPT_TEST (DB, db_read_cmd, READ_CONCERN), - OPT_TEST (DB, db_read_cmd, READ_PREFS), - OPT_TEST (DB, db_read_write_cmd, READ_CONCERN), - OPT_TEST (DB, db_read_write_cmd, WRITE_CONCERN), - OPT_TEST (DB, db_watch, READ_CONCERN), - OPT_TEST (DB, db_write_cmd, WRITE_CONCERN), - - /* - * collection functions - */ - OPT_TEST (COLL, aggregate, READ_CONCERN), - OPT_TEST (COLL, aggregate, READ_PREFS), - OPT_TEST (COLL, aggregate, WRITE_CONCERN), - OPT_TEST (COLL, aggregate_raw_pipeline, READ_CONCERN), - OPT_TEST (COLL, aggregate_raw_pipeline, READ_PREFS), - OPT_TEST (COLL, aggregate_raw_pipeline, WRITE_CONCERN), - OPT_TEST (COLL, collection_drop, WRITE_CONCERN), - OPT_TEST (COLL, collection_read_cmd, READ_CONCERN), - OPT_TEST (COLL, collection_read_cmd, READ_PREFS), - OPT_TEST (COLL, collection_read_write_cmd, READ_CONCERN), - OPT_TEST (COLL, collection_read_write_cmd, WRITE_CONCERN), - OPT_TEST (COLL, collection_watch, READ_CONCERN), - OPT_TEST (COLL, collection_write_cmd, WRITE_CONCERN), - OPT_TEST (COLL, count, READ_CONCERN), - OPT_TEST (COLL, count, READ_PREFS), - OPT_TEST (COLL, count_documents, READ_CONCERN), - OPT_TEST (COLL, count_documents, READ_PREFS), - OPT_TEST (COLL, create_index, WRITE_CONCERN), - OPT_TEST (COLL, drop_index, WRITE_CONCERN), - OPT_TEST (COLL, estimated_document_count, READ_CONCERN), - OPT_TEST (COLL, estimated_document_count, READ_PREFS), - OPT_TEST (COLL, find, READ_CONCERN), - OPT_TEST (COLL, find, READ_PREFS), - /* find_and_modify deliberately ignores collection read concern */ - OPT_TEST (COLL, find_and_modify, WRITE_CONCERN), - - /* - * collection write functions - */ - OPT_WRITE_TEST (delete_many), - OPT_WRITE_TEST (delete_one), - OPT_WRITE_TEST (insert_many), - OPT_WRITE_TEST (insert_one), - OPT_WRITE_TEST (replace_one), - OPT_WRITE_TEST (update_many), - OPT_WRITE_TEST (update_one), - - /* - * bulk operations - */ - OPT_BULK_TEST (bulk_insert), - OPT_BULK_TEST (bulk_remove_many), - OPT_BULK_TEST (bulk_remove_one), - OPT_BULK_TEST (bulk_replace_one), - OPT_BULK_TEST (bulk_update_many), - OPT_BULK_TEST (bulk_update_one), -}; - - -static void -install_inheritance_tests (TestSuite *suite, - opt_inheritance_test_t *tests, - size_t n) -{ - size_t i; - opt_inheritance_test_t *test; - char *name; - - for (i = 0; i < n; i++) { - test = &tests[i]; - name = bson_strdup_printf ( - "/inheritance/%s/%s", test->func_name, opt_type_name (test->opt_type)); - - TestSuite_AddFull (suite, - name, - test_func_inherits_opts, - NULL, - test, - TestSuite_CheckMockServerAllowed); - - bson_free (name); - } -} - - -void -test_opts_install (TestSuite *suite) -{ - install_inheritance_tests (suite, - gInheritanceTests, - sizeof (gInheritanceTests) / - sizeof (opt_inheritance_test_t)); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-primary-stepdown.c b/lib/mongoc/libmongoc/tests/test-mongoc-primary-stepdown.c deleted file mode 100644 index e7321cc50b89a39e4c1347e64642c0216c42681d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-primary-stepdown.c +++ /dev/null @@ -1,466 +0,0 @@ -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-util-private.h" - -#include "json-test.h" -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - - -static mongoc_uri_t * -_get_test_uri (void) -{ - mongoc_uri_t *uri; - - /* Use a URI with retryWrites off */ - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_bool (uri, "retryWrites", false); - - return uri; -} - -static void -_setup_test_with_client (mongoc_client_t *client) -{ - mongoc_write_concern_t *wc; - mongoc_database_t *db; - mongoc_collection_t *coll; - bson_error_t error; - bson_t *opts; - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_wmajority (wc, -1); - opts = bson_new (); - ASSERT (mongoc_write_concern_append (wc, opts)); - - /* Drop the "step-down.step-down" collection and re-create it */ - coll = mongoc_client_get_collection (client, "step-down", "step-down"); - if (!mongoc_collection_drop (coll, &error)) { - if (strcmp (error.message, "ns not found")) { - ASSERT_OR_PRINT (false, error); - } - } - - db = mongoc_client_get_database (client, "step-down"); - mongoc_collection_destroy (coll); - coll = mongoc_database_create_collection (db, "step-down", opts, &error); - ASSERT_OR_PRINT (coll, error); - - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); - mongoc_write_concern_destroy (wc); - bson_destroy (opts); -} - -static int -_connection_count (mongoc_database_t *db) -{ - mongoc_read_prefs_t *read_prefs; - bson_error_t error; - bson_iter_t iter; - bson_iter_t child; - bson_t cmd = BSON_INITIALIZER; - bson_t reply; - bool res; - int conns; - - ASSERT (db); - - BSON_APPEND_INT32 (&cmd, "serverStatus", 1); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - res = mongoc_database_command_simple (db, &cmd, read_prefs, &reply, &error); - ASSERT_OR_PRINT (res, error); - - ASSERT (bson_iter_init (&iter, &reply)); - ASSERT ( - bson_iter_find_descendant (&iter, "connections.totalCreated", &child)); - conns = bson_iter_int32 (&child); - - bson_destroy (&cmd); - bson_destroy (&reply); - mongoc_read_prefs_destroy (read_prefs); - - return conns; -} - -typedef void (*_test_fn_t) (mongoc_client_t *); - -static void -_run_test_single_and_pooled (_test_fn_t test) -{ - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_client_pool_t *pool; - - uri = _get_test_uri (); - - /* Run in single-threaded mode */ - client = mongoc_client_new_from_uri (uri); - _setup_test_with_client (client); - test (client); - mongoc_client_destroy (client); - - /* Run in pooled mode */ - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - _setup_test_with_client (client); - test (client); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - - mongoc_uri_destroy (uri); -} - -static void -test_getmore_iteration (mongoc_client_t *client) -{ - mongoc_write_concern_t *wc; - mongoc_database_t *db; - mongoc_collection_t *coll; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - bson_t *insert; - bson_t *opts; - bool res; - int conn_count; - int i; - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_wmajority (wc, -1); - opts = bson_new (); - ASSERT (mongoc_write_concern_append (wc, opts)); - - coll = mongoc_client_get_collection (client, "step-down", "step-down"); - - db = mongoc_client_get_database (client, "admin"); - conn_count = _connection_count (db); - - /* Insert 5 documents */ - for (i = 0; i < 5; i++) { - insert = bson_new (); - - bson_append_int32 (insert, "a", -1, i); - ASSERT (mongoc_collection_insert_one (coll, insert, opts, NULL, NULL)); - - bson_destroy (insert); - } - - /* Retrieve the first batch of 2 documents */ - cursor = - mongoc_collection_find_with_opts (coll, tmp_bson ("{}"), NULL, NULL); - - ASSERT (cursor); - ASSERT (mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_next (cursor, &doc)); - - /* Send a stepdown to the primary, ensure it succeeds */ - res = mongoc_database_command_simple ( - db, - tmp_bson ("{ 'replSetStepDown': 5, 'force': true}"), - NULL, - NULL, - &error); - ASSERT_OR_PRINT (res, error); - - /* Retrieve the next results from the cursor, - ensure it succeeds */ - ASSERT (mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_next (cursor, &doc)); - - /* Verify that no new connections have been created */ - ASSERT (conn_count == _connection_count (db)); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); - mongoc_write_concern_destroy (wc); - bson_destroy (opts); -} - -static void -test_getmore_iteration_runner (void *ctx) -{ - /* Only run on 4.2 or higher */ - if (!test_framework_max_wire_version_at_least (8)) { - return; - } - - _run_test_single_and_pooled (test_getmore_iteration); -} - -static void -test_not_master_keep_pool (mongoc_client_t *client) -{ - mongoc_database_t *db; - mongoc_collection_t *coll; - bson_error_t error; - bool res; - int conn_count; - - /* Configure fail points */ - db = mongoc_client_get_database (client, "admin"); - conn_count = _connection_count (db); - res = mongoc_database_command_simple ( - db, - tmp_bson ("{'configureFailPoint': 'failCommand', " - "'mode': {'times': 1}, " - "'data': {'failCommands': ['insert'], 'errorCode': 10107}}"), - NULL, - NULL, - &error); - ASSERT_OR_PRINT (res, error); - - /* Capture logs to swallow warnings about endSessions */ - capture_logs (true); - - coll = mongoc_client_get_collection (client, "step-down", "step-down"); - - /* Execute an insert, verify that it fails with 10107 */ - res = mongoc_collection_insert_one ( - coll, tmp_bson ("{'test': 1}"), NULL, NULL, &error); - ASSERT (!res); - ASSERT (error.code == 10107); - ASSERT_CONTAINS (error.message, - "Failing command due to 'failCommand' failpoint"); - - /* Execute a second insert, verify that it succeeds */ - res = mongoc_collection_insert_one ( - coll, tmp_bson ("{'test': 1}"), NULL, NULL, &error); - ASSERT (res); - - /* Verify that the connection pool has not been cleared */ - ASSERT (conn_count == _connection_count (db)); - - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); -} - -static void -test_not_master_keep_pool_runner (void *ctx) -{ - /* Only run on 4.2 and higher */ - if (!test_framework_max_wire_version_at_least (8)) { - return; - } - - _run_test_single_and_pooled (test_not_master_keep_pool); -} - -static void -test_not_master_reset_pool (mongoc_client_t *client) -{ - mongoc_database_t *db; - mongoc_collection_t *coll; - mongoc_read_prefs_t *read_prefs; - bson_error_t error; - bool res; - int conn_count; - - /* Configure fail points */ - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - db = mongoc_client_get_database (client, "admin"); - conn_count = _connection_count (db); - res = mongoc_database_command_simple ( - db, - tmp_bson ("{'configureFailPoint': 'failCommand', " - "'mode': {'times': 1}, " - "'data': {'failCommands': ['insert'], 'errorCode': 10107}}"), - read_prefs, - NULL, - &error); - ASSERT_OR_PRINT (res, error); - - /* Capture logs to swallow warnings about endSessions */ - capture_logs (true); - - coll = mongoc_client_get_collection (client, "step-down", "step-down"); - - /* Execute an insert, verify that it fails with 10107 */ - res = mongoc_collection_insert_one ( - coll, tmp_bson ("{'test': 1}"), NULL, NULL, &error); - ASSERT (!res); - ASSERT (error.code == 10107); - ASSERT_CONTAINS (error.message, - "Failing command due to 'failCommand' failpoint"); - - /* Verify that the pool has been cleared */ - ASSERT ((conn_count + 1) == _connection_count (db)); - - mongoc_read_prefs_destroy (read_prefs); - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); -} - -static void -test_not_master_reset_pool_runner (void *ctx) -{ - int64_t max_wire_version; - - /* Only run if version 4.0 */ - test_framework_get_max_wire_version (&max_wire_version); - if (max_wire_version != 7) { - return; - } - - _run_test_single_and_pooled (test_not_master_reset_pool); -} - -static void -test_shutdown_reset_pool (mongoc_client_t *client) -{ - mongoc_database_t *db; - mongoc_collection_t *coll; - mongoc_read_prefs_t *read_prefs; - bson_error_t error; - bool res; - int conn_count; - - /* Configure fail points */ - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - db = mongoc_client_get_database (client, "admin"); - conn_count = _connection_count (db); - res = mongoc_database_command_simple ( - db, - tmp_bson ("{'configureFailPoint': 'failCommand', " - "'mode': {'times': 1}, " - "'data': {'failCommands': ['insert'], 'errorCode': 91}}"), - read_prefs, - NULL, - &error); - ASSERT_OR_PRINT (res, error); - - coll = mongoc_client_get_collection (client, "step-down", "step-down"); - - /* Execute an insert, verify that it fails with 91 */ - res = mongoc_collection_insert_one ( - coll, tmp_bson ("{'test': 1}"), NULL, NULL, &error); - ASSERT (!res); - ASSERT (error.code == 91); - ASSERT_CONTAINS (error.message, - "Failing command due to 'failCommand' failpoint"); - - /* Verify that the pool has been cleared */ - ASSERT ((conn_count + 1) == _connection_count (db)); - - mongoc_read_prefs_destroy (read_prefs); - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); -} - -static void -test_shutdown_reset_pool_runner (void *ctx) -{ - int64_t max_wire_version; - - /* Only run if version >= 4.0 */ - test_framework_get_max_wire_version (&max_wire_version); - if (max_wire_version < 7) { - return; - } - - _run_test_single_and_pooled (test_shutdown_reset_pool); -} - -static void -test_interrupted_shutdown_reset_pool (mongoc_client_t *client) -{ - mongoc_database_t *db; - mongoc_collection_t *coll; - mongoc_read_prefs_t *read_prefs; - bson_error_t error; - bool res; - int conn_count; - - /* Configure fail points */ - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - db = mongoc_client_get_database (client, "admin"); - conn_count = _connection_count (db); - res = mongoc_database_command_simple ( - db, - tmp_bson ("{'configureFailPoint': 'failCommand', " - "'mode': {'times': 1}, " - "'data': {'failCommands': ['insert'], 'errorCode': 11600}}"), - read_prefs, - NULL, - &error); - ASSERT_OR_PRINT (res, error); - - coll = mongoc_client_get_collection (client, "step-down", "step-down"); - - /* Execute an insert, verify that it fails with 11600 */ - res = mongoc_collection_insert_one ( - coll, tmp_bson ("{'test': 1}"), NULL, NULL, &error); - ASSERT (!res); - ASSERT (error.code == 11600); - ASSERT_CONTAINS (error.message, - "Failing command due to 'failCommand' failpoint"); - - /* Verify that the pool has been cleared */ - ASSERT ((conn_count + 1) == _connection_count (db)); - - mongoc_read_prefs_destroy (read_prefs); - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); -} - -static void -test_interrupted_shutdown_reset_pool_runner (void *ctx) -{ - int64_t max_wire_version; - - /* Only run if version >= 4.0 */ - test_framework_get_max_wire_version (&max_wire_version); - if (max_wire_version < 7) { - return; - } - - _run_test_single_and_pooled (test_interrupted_shutdown_reset_pool); -} - -void -test_primary_stepdown_install (TestSuite *suite) -{ - TestSuite_AddFull (suite, - "/Stepdown/getmore", - test_getmore_iteration_runner, - NULL, - NULL, - test_framework_skip_if_auth, - test_framework_skip_if_not_replset); - - TestSuite_AddFull (suite, - "/Stepdown/not_master_keep", - test_not_master_keep_pool_runner, - NULL, - NULL, - test_framework_skip_if_auth, - test_framework_skip_if_not_replset); - - TestSuite_AddFull (suite, - "/Stepdown/not_master_reset", - test_not_master_reset_pool_runner, - NULL, - NULL, - test_framework_skip_if_auth, - test_framework_skip_if_not_replset); - - TestSuite_AddFull (suite, - "/Stepdown/shutdown_reset_pool", - test_shutdown_reset_pool_runner, - NULL, - NULL, - test_framework_skip_if_auth, - test_framework_skip_if_not_replset); - - TestSuite_AddFull (suite, - "/Stepdown/interrupt_shutdown", - test_interrupted_shutdown_reset_pool_runner, - NULL, - NULL, - test_framework_skip_if_auth, - test_framework_skip_if_not_replset); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-queue.c b/lib/mongoc/libmongoc/tests/test-mongoc-queue.c deleted file mode 100644 index 02ee288cb4de214c1b326413bdbcd09fb55bed46..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-queue.c +++ /dev/null @@ -1,57 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-queue-private.h> - -#include "TestSuite.h" - - -static void -test_mongoc_queue_basic (void) -{ - mongoc_queue_t q = MONGOC_QUEUE_INITIALIZER; - - _mongoc_queue_push_head (&q, (void *) 1); - _mongoc_queue_push_tail (&q, (void *) 2); - _mongoc_queue_push_head (&q, (void *) 3); - _mongoc_queue_push_tail (&q, (void *) 4); - _mongoc_queue_push_head (&q, (void *) 5); - - ASSERT_CMPINT (_mongoc_queue_get_length (&q), ==, 5); - - ASSERT (_mongoc_queue_pop_head (&q) == (void *) 5); - ASSERT (_mongoc_queue_pop_head (&q) == (void *) 3); - ASSERT (_mongoc_queue_pop_head (&q) == (void *) 1); - ASSERT (_mongoc_queue_pop_head (&q) == (void *) 2); - ASSERT (_mongoc_queue_pop_head (&q) == (void *) 4); - ASSERT (!_mongoc_queue_pop_head (&q)); -} - - -static void -test_mongoc_queue_pop_tail (void) -{ - mongoc_queue_t q = MONGOC_QUEUE_INITIALIZER; - - _mongoc_queue_push_head (&q, (void *) 1); - ASSERT_CMPUINT32 (_mongoc_queue_get_length (&q), ==, (uint32_t) 1); - ASSERT_CMPVOID (_mongoc_queue_pop_tail (&q), ==, (void *) 1); - - ASSERT_CMPUINT32 (_mongoc_queue_get_length (&q), ==, (uint32_t) 0); - ASSERT_CMPVOID (_mongoc_queue_pop_tail (&q), ==, (void *) NULL); - - _mongoc_queue_push_tail (&q, (void *) 2); - _mongoc_queue_push_head (&q, (void *) 3); - ASSERT_CMPUINT32 (_mongoc_queue_get_length (&q), ==, (uint32_t) 2); - ASSERT_CMPVOID (_mongoc_queue_pop_tail (&q), ==, (void *) 2); - ASSERT_CMPUINT32 (_mongoc_queue_get_length (&q), ==, (uint32_t) 1); - ASSERT_CMPVOID (_mongoc_queue_pop_tail (&q), ==, (void *) 3); - ASSERT_CMPUINT32 (_mongoc_queue_get_length (&q), ==, (uint32_t) 0); - ASSERT_CMPVOID (_mongoc_queue_pop_tail (&q), ==, (void *) NULL); -} - - -void -test_queue_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Queue/basic", test_mongoc_queue_basic); - TestSuite_Add (suite, "/Queue/pop_tail", test_mongoc_queue_pop_tail); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-read-concern.c b/lib/mongoc/libmongoc/tests/test-mongoc-read-concern.c deleted file mode 100644 index 2d0d0cc533cf438b2dd2ce3901dc91b40c5510c0..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-read-concern.c +++ /dev/null @@ -1,290 +0,0 @@ -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-util-private.h" - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "mock_server/future.h" -#include "mock_server/mock-server.h" -#include "mock_server/future-functions.h" - - -static void -test_read_concern_append (void) -{ - mongoc_read_concern_t *rc; - bson_t *cmd; - - cmd = tmp_bson ("{'foo': 1}"); - - /* append default readConcern */ - rc = mongoc_read_concern_new (); - ASSERT (mongoc_read_concern_is_default (rc)); - ASSERT_MATCH (cmd, "{'foo': 1, 'readConcern': {'$exists': false}}"); - - /* append readConcern with level */ - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_LOCAL); - ASSERT (mongoc_read_concern_append (rc, cmd)); - - ASSERT_MATCH (cmd, "{'foo': 1, 'readConcern': {'level': 'local'}}"); - - mongoc_read_concern_destroy (rc); -} - -static void -test_read_concern_basic (void) -{ - mongoc_read_concern_t *read_concern; - - read_concern = mongoc_read_concern_new (); - - BEGIN_IGNORE_DEPRECATIONS; - - /* - * Test defaults. - */ - ASSERT (read_concern); - ASSERT (mongoc_read_concern_is_default (read_concern)); - ASSERT (!mongoc_read_concern_get_level (read_concern)); - - /* - * Test changes to level. - */ - mongoc_read_concern_set_level (read_concern, - MONGOC_READ_CONCERN_LEVEL_LOCAL); - ASSERT (!mongoc_read_concern_is_default (read_concern)); - ASSERT_CMPSTR (mongoc_read_concern_get_level (read_concern), - MONGOC_READ_CONCERN_LEVEL_LOCAL); - - /* - * Check generated bson. - */ - ASSERT_MATCH (_mongoc_read_concern_get_bson (read_concern), - "{'level': 'local'}"); - - mongoc_read_concern_destroy (read_concern); -} - - -static void -test_read_concern_bson_omits_defaults (void) -{ - mongoc_read_concern_t *read_concern; - const bson_t *bson; - bson_iter_t iter; - - read_concern = mongoc_read_concern_new (); - - /* - * Check generated bson. - */ - ASSERT (read_concern); - - bson = _mongoc_read_concern_get_bson (read_concern); - ASSERT (bson); - ASSERT (!bson_iter_init_find (&iter, bson, "level")); - - mongoc_read_concern_destroy (read_concern); -} - - -static void -test_read_concern_always_mutable (void) -{ - mongoc_read_concern_t *read_concern; - - read_concern = mongoc_read_concern_new (); - - ASSERT (read_concern); - - mongoc_read_concern_set_level (read_concern, - MONGOC_READ_CONCERN_LEVEL_LOCAL); - ASSERT_MATCH (_mongoc_read_concern_get_bson (read_concern), - "{'level': 'local'}"); - - mongoc_read_concern_set_level (read_concern, - MONGOC_READ_CONCERN_LEVEL_MAJORITY); - ASSERT_MATCH (_mongoc_read_concern_get_bson (read_concern), - "{'level': 'majority'}"); - - mongoc_read_concern_set_level (read_concern, - MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE); - ASSERT_MATCH (_mongoc_read_concern_get_bson (read_concern), - "{'level': 'linearizable'}"); - - mongoc_read_concern_destroy (read_concern); -} - - -static void -_test_read_concern_wire_version (bool allow, bool explicit) -{ - mongoc_read_concern_t *rc; - bson_t opts = BSON_INITIALIZER; - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - bson_error_t error; - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, "foo"); - - server = mock_server_with_autoismaster ( - allow ? WIRE_VERSION_READ_CONCERN : WIRE_VERSION_READ_CONCERN - 1); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - if (explicit) { - mongoc_read_concern_append (rc, &opts); - } else { - mongoc_client_set_read_concern (client, rc); - mongoc_collection_set_read_concern (collection, rc); - } - - /* - * aggregate - */ - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson (NULL), &opts, NULL); - - future = future_cursor_next (cursor, &doc); - if (allow) { - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'readConcern': {'level': 'foo'}}"); - mock_server_replies_simple ( - request, "{'ok': 1, 'cursor': {'id': 0, 'firstBatch': []}}"); - request_destroy (request); - BSON_ASSERT (future_wait (future)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - } else { - BSON_ASSERT (!future_get_bool (future)); - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "does not support readConcern"); - } - - future_destroy (future); - - /* - * generic mongoc_client_write_command_with_opts - */ - future = future_client_read_command_with_opts ( - client, "db", tmp_bson ("{'foo': 1}"), NULL, &opts, NULL, &error); - if (allow) { - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'readConcern': {'level': 'foo'}}"); - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - } else { - BSON_ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "does not support readConcern"); - } - - future_destroy (future); - - /* - * count - */ - future = future_collection_count_with_opts (collection, - MONGOC_QUERY_NONE, - tmp_bson ("{}"), - 0, - 0, - &opts, - NULL, - &error); - if (allow) { - request = - mock_server_receives_command (server, - "db", - MONGOC_QUERY_SLAVE_OK, - "{'readConcern': {'level': 'foo'}}"); - mock_server_replies_simple (request, "{'ok': 1, 'n': 1}"); - request_destroy (request); - ASSERT_CMPINT64 (future_get_int64_t (future), ==, (int64_t) 1); - } else { - ASSERT_CMPINT64 (future_get_int64_t (future), ==, (int64_t) -1); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "does not support readConcern"); - } - - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); - mongoc_read_concern_destroy (rc); - bson_destroy (&opts); -} - - -static void -test_inherited_read_concern_allowed (void) -{ - _test_read_concern_wire_version (true, false); -} - - -static void -test_explicit_read_concern_allowed (void) -{ - _test_read_concern_wire_version (true, true); -} - - -static void -test_inherited_read_concern_prohibited (void) -{ - _test_read_concern_wire_version (false, false); -} - - -static void -test_explicit_read_concern_prohibited (void) -{ - _test_read_concern_wire_version (false, true); -} - - -void -test_read_concern_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/ReadConcern/append", test_read_concern_append); - TestSuite_Add (suite, "/ReadConcern/basic", test_read_concern_basic); - TestSuite_Add (suite, - "/ReadConcern/bson_omits_defaults", - test_read_concern_bson_omits_defaults); - TestSuite_Add ( - suite, "/ReadConcern/always_mutable", test_read_concern_always_mutable); - TestSuite_AddMockServerTest (suite, - "/ReadConcern/allowed/inherited", - test_inherited_read_concern_allowed); - TestSuite_AddMockServerTest (suite, - "/ReadConcern/allowed/explicit", - test_explicit_read_concern_allowed); - TestSuite_AddMockServerTest (suite, - "/ReadConcern/prohibited/inherited", - test_inherited_read_concern_prohibited); - TestSuite_AddMockServerTest (suite, - "/ReadConcern/prohibited/explicit", - test_explicit_read_concern_prohibited); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-read-prefs.c b/lib/mongoc/libmongoc/tests/test-mongoc-read-prefs.c deleted file mode 100644 index f0f19d147fc4bc01a75741fddd5e661fbab147e9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-read-prefs.c +++ /dev/null @@ -1,1009 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-uri-private.h> - -#include "TestSuite.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" -#include "mock_server/mock-rs.h" -#include "test-conveniences.h" - - -static bool -_can_be_command (const char *query) -{ - return (!bson_empty (tmp_bson (query))); -} - -static void -_test_op_query (const mongoc_uri_t *uri, - mock_server_t *server, - const char *query_in, - mongoc_read_prefs_t *read_prefs, - mongoc_query_flags_t expected_query_flags, - const char *expected_query) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t b = BSON_INITIALIZER; - future_t *future; - request_t *request; - - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "test", "test"); - - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0, - 1, - 0, - tmp_bson (query_in), - NULL, - read_prefs); - - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_query ( - server, "test.test", expected_query_flags, 0, 1, expected_query, NULL); - - mock_server_replies (request, - MONGOC_REPLY_NONE, /* flags */ - 0, /* cursorId */ - 0, /* startingFrom */ - 1, /* numberReturned */ - "{'a': 1}"); - - /* mongoc_cursor_next returned true */ - BSON_ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&b); -} - - -static void -_test_find_command (const mongoc_uri_t *uri, - mock_server_t *server, - const char *query_in, - mongoc_read_prefs_t *read_prefs, - mongoc_query_flags_t expected_find_cmd_query_flags, - const char *expected_find_cmd) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t b = BSON_INITIALIZER; - future_t *future; - request_t *request; - - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "test", "test"); - - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0, - 1, - 0, - tmp_bson (query_in), - NULL, - read_prefs); - - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_command ( - server, "test", expected_find_cmd_query_flags, expected_find_cmd); - - mock_server_replies (request, - MONGOC_REPLY_NONE, /* flags */ - 0, /* cursorId */ - 0, /* startingFrom */ - 1, /* numberReturned */ - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{'a': 1}]}}"); - - /* mongoc_cursor_next returned true */ - BSON_ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&b); -} - - -static void -_test_op_msg (const mongoc_uri_t *uri, - mock_server_t *server, - const char *query_in, - mongoc_read_prefs_t *read_prefs, - const char *expected_op_msg) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t b = BSON_INITIALIZER; - future_t *future; - request_t *request; - - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "test", "test"); - - cursor = mongoc_collection_find (collection, - MONGOC_QUERY_NONE, - 0, - 1, - 0, - tmp_bson (query_in), - NULL, - read_prefs); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_msg (server, 0, tmp_bson (expected_op_msg)); - mock_server_replies_simple (request, - "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{'a': 1}]}}"); - - /* mongoc_cursor_next returned true */ - BSON_ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&b); -} - - -static void -_test_command (const mongoc_uri_t *uri, - mock_server_t *server, - const char *command, - mongoc_read_prefs_t *read_prefs, - mongoc_query_flags_t expected_query_flags, - const char *expected_query) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t b = BSON_INITIALIZER; - future_t *future; - request_t *request; - - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "test", "test"); - mongoc_collection_set_read_prefs (collection, read_prefs); - - cursor = mongoc_collection_command (collection, - MONGOC_QUERY_NONE, - 0, - 1, - 0, - tmp_bson (command), - NULL, - read_prefs); - - future = future_cursor_next (cursor, &doc); - - request = mock_server_receives_command ( - server, "test", expected_query_flags, expected_query); - - mock_server_replies (request, - MONGOC_REPLY_NONE, /* flags */ - 0, /* cursorId */ - 0, /* startingFrom */ - 1, /* numberReturned */ - "{'ok': 1}"); - - /* mongoc_cursor_next returned true */ - BSON_ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - bson_destroy (&b); -} - -static void -_test_command_simple (const mongoc_uri_t *uri, - mock_server_t *server, - const char *command, - mongoc_read_prefs_t *read_prefs, - mongoc_query_flags_t expected_query_flags, - const char *expected_query) -{ - mongoc_client_t *client; - mongoc_collection_t *collection; - future_t *future; - request_t *request; - - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "test", "test"); - mongoc_collection_set_read_prefs (collection, read_prefs); - - future = future_client_command_simple ( - client, "test", tmp_bson (command), read_prefs, NULL, NULL); - - request = mock_server_receives_command ( - server, "test", expected_query_flags, expected_query); - - mock_server_replies (request, - MONGOC_REPLY_NONE, /* flags */ - 0, /* cursorId */ - 0, /* startingFrom */ - 1, /* numberReturned */ - "{'ok': 1}"); - - /* mongoc_cursor_next returned true */ - BSON_ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -typedef enum { - READ_PREF_TEST_STANDALONE, - READ_PREF_TEST_MONGOS, - READ_PREF_TEST_PRIMARY, - READ_PREF_TEST_SECONDARY, -} read_pref_test_type_t; - - -static mock_server_t * -_run_server (read_pref_test_type_t test_type, int32_t max_wire_version) -{ - mock_server_t *server; - - server = mock_server_new (); - mock_server_run (server); - - BSON_ASSERT (max_wire_version > 0); - switch (test_type) { - case READ_PREF_TEST_STANDALONE: - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'maxWireVersion': %d," - " 'ismaster': true}", - max_wire_version); - break; - case READ_PREF_TEST_MONGOS: - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'maxWireVersion': %d," - " 'ismaster': true," - " 'msg': 'isdbgrid'}", - max_wire_version); - break; - case READ_PREF_TEST_PRIMARY: - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'maxWireVersion': %d," - " 'ismaster': true," - " 'setName': 'rs'," - " 'hosts': ['%s']}", - max_wire_version, - mock_server_get_host_and_port (server)); - break; - case READ_PREF_TEST_SECONDARY: - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'maxWireVersion': %d," - " 'ismaster': false," - " 'secondary': true," - " 'setName': 'rs'," - " 'hosts': ['%s']}", - max_wire_version, - mock_server_get_host_and_port (server)); - break; - default: - fprintf (stderr, "Invalid test_type: : %d\n", test_type); - abort (); - } - - return server; -} - - -static mongoc_uri_t * -_get_uri (mock_server_t *server, read_pref_test_type_t test_type) -{ - mongoc_uri_t *uri; - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - - switch (test_type) { - case READ_PREF_TEST_PRIMARY: - case READ_PREF_TEST_SECONDARY: - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - break; - case READ_PREF_TEST_STANDALONE: - case READ_PREF_TEST_MONGOS: - default: - break; - } - - return uri; -} - - -static void -_test_read_prefs_op_msg (read_pref_test_type_t test_type, - mongoc_read_prefs_t *read_prefs, - const char *query_in, - const char *expected_query, - mongoc_query_flags_t expected_query_flags, - const char *expected_find_cmd, - mongoc_query_flags_t expected_find_cmd_query_flags, - const char *expected_op_msg) -{ - mock_server_t *server; - mongoc_uri_t *uri; - - server = _run_server (test_type, 3); - uri = _get_uri (server, test_type); - - _test_op_query ( - uri, server, query_in, read_prefs, expected_query_flags, expected_query); - - if (_can_be_command (query_in)) { - _test_command (uri, - server, - query_in, - read_prefs, - expected_query_flags, - expected_query); - - _test_command_simple (uri, - server, - query_in, - read_prefs, - expected_query_flags, - expected_query); - } - - mock_server_destroy (server); - mongoc_uri_destroy (uri); - - server = _run_server (test_type, 4); - uri = _get_uri (server, test_type); - - _test_find_command (uri, - server, - query_in, - read_prefs, - expected_find_cmd_query_flags, - expected_find_cmd); - - mock_server_destroy (server); - server = _run_server (test_type, WIRE_VERSION_OP_MSG); - mongoc_uri_destroy (uri); - uri = _get_uri (server, test_type); - - _test_op_msg (uri, server, query_in, read_prefs, expected_op_msg); - - mock_server_destroy (server); - mongoc_uri_destroy (uri); -} - - -static void -_test_read_prefs (read_pref_test_type_t test_type, - mongoc_read_prefs_t *read_prefs, - const char *query_in, - const char *expected_query, - mongoc_query_flags_t expected_query_flags, - const char *expected_find_cmd, - mongoc_query_flags_t expected_find_cmd_query_flags) -{ - _test_read_prefs_op_msg (test_type, - read_prefs, - query_in, - expected_query, - expected_query_flags, - expected_find_cmd, - expected_find_cmd_query_flags, - /* expect same op_msg as find */ - expected_find_cmd); -} - - -/* test that a NULL read pref is the same as PRIMARY */ -static void -test_read_prefs_standalone_null (void) -{ - _test_read_prefs_op_msg (READ_PREF_TEST_STANDALONE, - NULL, - "{}", - "{}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK, - "{ 'find': 'test', 'filter': {}, " - "'$readPreference': { '$exists': false } }"); - - _test_read_prefs_op_msg (READ_PREF_TEST_STANDALONE, - NULL, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK, - "{ 'find': 'test', 'filter': {'a': 1}, " - "'$readPreference': { '$exists': false } }"); -} - -static void -test_read_prefs_standalone_primary (void) -{ - mongoc_read_prefs_t *read_prefs; - - /* Server Selection Spec: for topology type single and server types other - * than mongos, "clients MUST always set the slaveOK wire protocol flag on - * reads to ensure that any server type can handle the request." - * */ - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - _test_read_prefs_op_msg (READ_PREF_TEST_STANDALONE, - read_prefs, - "{}", - "{}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK, - "{ 'find': 'test', 'filter': {}, " - "'$readPreference': { '$exists': false } }"); - - _test_read_prefs_op_msg (READ_PREF_TEST_STANDALONE, - read_prefs, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK, - "{ 'find': 'test', 'filter': {'a': 1}, " - "'$readPreference': { '$exists': false } }"); - - mongoc_read_prefs_destroy (read_prefs); -} - - -static void -test_read_prefs_standalone_secondary (void) -{ - mongoc_read_prefs_t *read_prefs; - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - _test_read_prefs_op_msg (READ_PREF_TEST_STANDALONE, - read_prefs, - "{}", - "{}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK, - "{ 'find': 'test', 'filter': {}, " - "'$readPreference': { '$exists': false } }"); - - _test_read_prefs_op_msg (READ_PREF_TEST_STANDALONE, - read_prefs, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK, - "{ 'find': 'test', 'filter': {'a': 1}, " - "'$readPreference': { '$exists': false } }"); - - mongoc_read_prefs_destroy (read_prefs); -} - - -static void -test_read_prefs_standalone_tags (void) -{ - bson_t b = BSON_INITIALIZER; - mongoc_read_prefs_t *read_prefs; - - bson_append_utf8 (&b, "dc", 2, "ny", 2); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY_PREFERRED); - mongoc_read_prefs_add_tag (read_prefs, &b); - mongoc_read_prefs_add_tag (read_prefs, NULL); - - _test_read_prefs_op_msg (READ_PREF_TEST_STANDALONE, - read_prefs, - "{}", - "{}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK, - "{ 'find': 'test', 'filter': {}, " - "'$readPreference': { '$exists': false } }"); - - _test_read_prefs_op_msg (READ_PREF_TEST_STANDALONE, - read_prefs, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK, - "{ 'find': 'test', 'filter': {'a': 1}, " - "'$readPreference': { '$exists': false } }"); - - bson_destroy (&b); - mongoc_read_prefs_destroy (read_prefs); -} - - -static void -test_read_prefs_primary_rsprimary (void) -{ - mongoc_read_prefs_t *read_prefs; - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - _test_read_prefs (READ_PREF_TEST_PRIMARY, - read_prefs, - "{}", - "{}", - MONGOC_QUERY_NONE, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_NONE); - - _test_read_prefs (READ_PREF_TEST_PRIMARY, - read_prefs, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_NONE, - "{'find': 'test', 'filter': {'a': 1}}", - MONGOC_QUERY_NONE); - - mongoc_read_prefs_destroy (read_prefs); -} - - -static void -test_read_prefs_secondary_rssecondary (void) -{ - mongoc_read_prefs_t *read_prefs; - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - _test_read_prefs (READ_PREF_TEST_SECONDARY, - read_prefs, - "{}", - "{}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK); - - _test_read_prefs (READ_PREF_TEST_SECONDARY, - read_prefs, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {'a': 1}}", - MONGOC_QUERY_SLAVE_OK); - - mongoc_read_prefs_destroy (read_prefs); -} - - -/* test that a NULL read pref is the same as PRIMARY */ -static void -test_read_prefs_mongos_null (void) -{ - _test_read_prefs (READ_PREF_TEST_MONGOS, - NULL, - "{}", - "{}", - MONGOC_QUERY_NONE, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_NONE); - - _test_read_prefs (READ_PREF_TEST_MONGOS, - NULL, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_NONE, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_NONE); -} - - -static void -test_read_prefs_mongos_primary (void) -{ - mongoc_read_prefs_t *read_prefs; - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - _test_read_prefs (READ_PREF_TEST_MONGOS, - read_prefs, - "{}", - "{}", - MONGOC_QUERY_NONE, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_NONE); - - _test_read_prefs (READ_PREF_TEST_MONGOS, - read_prefs, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_NONE, - "{'find': 'test', 'filter': {'a': 1}}", - MONGOC_QUERY_NONE); - - mongoc_read_prefs_destroy (read_prefs); -} - - -static void -test_read_prefs_mongos_secondary (void) -{ - mongoc_read_prefs_t *read_prefs; - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - _test_read_prefs_op_msg ( - READ_PREF_TEST_MONGOS, - read_prefs, - "{}", - "{'$query': {}, '$readPreference': {'mode': 'secondary'}}", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'find': 'test', 'filter': {}}," - " '$readPreference': {'mode': 'secondary'}}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}," - " '$readPreference': {'mode': 'secondary'}}"); - - _test_read_prefs_op_msg ( - READ_PREF_TEST_MONGOS, - read_prefs, - "{'a': 1}", - "{'$query': {'a': 1}, '$readPreference': {'mode': 'secondary'}}", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'find': 'test', 'filter': {'a': 1}}," - " '$readPreference': {'mode': 'secondary'}}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {'a': 1}," - " '$readPreference': {'mode': 'secondary'}}"); - - _test_read_prefs_op_msg ( - READ_PREF_TEST_MONGOS, - read_prefs, - "{'$query': {'a': 1}}", - "{'$query': {'a': 1}, '$readPreference': {'mode': 'secondary'}}", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'find': 'test', 'filter': {'a': 1}}," - " '$readPreference': {'mode': 'secondary'}}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {'a': 1}," - " '$readPreference': {'mode': 'secondary'}}"); - - mongoc_read_prefs_destroy (read_prefs); -} - - -static void -test_read_prefs_mongos_secondary_preferred (void) -{ - mongoc_read_prefs_t *read_prefs; - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY_PREFERRED); - - /* $readPreference not sent, only slaveOk */ - _test_read_prefs (READ_PREF_TEST_MONGOS, - read_prefs, - "{}", - "{}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}}", - MONGOC_QUERY_SLAVE_OK); - - _test_read_prefs (READ_PREF_TEST_MONGOS, - read_prefs, - "{'a': 1}", - "{'a': 1}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {'a': 1}}", - MONGOC_QUERY_SLAVE_OK); - - mongoc_read_prefs_destroy (read_prefs); -} - - -static void -test_read_prefs_mongos_tags (void) -{ - bson_t b = BSON_INITIALIZER; - mongoc_read_prefs_t *read_prefs; - - bson_append_utf8 (&b, "dc", 2, "ny", 2); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY_PREFERRED); - mongoc_read_prefs_add_tag (read_prefs, &b); - mongoc_read_prefs_add_tag (read_prefs, NULL); - - _test_read_prefs_op_msg ( - READ_PREF_TEST_MONGOS, - read_prefs, - "{}", - "{'$query': {}, '$readPreference': {'mode': 'secondaryPreferred'," - " 'tags': [{'dc': 'ny'}, {}]}}", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'find': 'test', 'filter': {}}," - " '$readPreference': {'mode': 'secondaryPreferred'," - " 'tags': [{'dc': 'ny'}, {}]}}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}," - " '$readPreference': {'mode': 'secondaryPreferred'," - " 'tags': [{'dc': 'ny'}, {}]}}"); - - _test_read_prefs_op_msg ( - READ_PREF_TEST_MONGOS, - read_prefs, - "{'a': 1}", - "{'$query': {'a': 1}," - " '$readPreference': {'mode': 'secondaryPreferred'," - " 'tags': [{'dc': 'ny'}, {}]}}", - MONGOC_QUERY_SLAVE_OK, - "{'$query': {'find': 'test', 'filter': {}}," - " '$readPreference': {'mode': 'secondaryPreferred'," - " 'tags': [{'dc': 'ny'}, {}]}}", - MONGOC_QUERY_SLAVE_OK, - "{'find': 'test', 'filter': {}," - " '$readPreference': {'mode': 'secondaryPreferred'," - " 'tags': [{'dc': 'ny'}, {}]}}"); - - mongoc_read_prefs_destroy (read_prefs); - bson_destroy (&b); -} - - -/* test that we add readConcern only inside $query, not outside it too */ -static void -test_mongos_read_concern (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_read_prefs_t *prefs; - mongoc_cursor_t *cursor; - const bson_t *doc; - future_t *future; - request_t *request; - - server = mock_mongos_new (WIRE_VERSION_READ_CONCERN); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "test", "test"); - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - cursor = mongoc_collection_find_with_opts ( - collection, - tmp_bson ("{'a': 1}"), - tmp_bson ("{'readConcern': {'level': 'foo'}}"), - prefs); - - future = future_cursor_next (cursor, &doc); - request = mock_server_receives_command ( - server, - "test", - MONGOC_QUERY_SLAVE_OK, - "{" - " '$query': {" - " 'find': 'test', 'filter': {}, 'readConcern': {'level': 'foo'}" - " }," - " '$readPreference': {" - " 'mode': 'secondary'" - " }," - " 'readConcern': {'$exists': false}" - "}"); - - mock_server_replies_to_find ( - request, MONGOC_QUERY_SLAVE_OK, 0, 1, "db.collection", "{}", true); - - /* mongoc_cursor_next returned true */ - BSON_ASSERT (future_get_bool (future)); - - request_destroy (request); - future_destroy (future); - mongoc_cursor_destroy (cursor); - mongoc_read_prefs_destroy (prefs); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -typedef mongoc_cursor_t *(*test_op_msg_direct_fn_t) (mongoc_collection_t *, - mongoc_read_prefs_t *); - - -/* direct connection to a secondary requires read pref primaryPreferred to - * avoid "not master" error from server */ -static void -_test_op_msg_direct_connection (bool is_mongos, - test_op_msg_direct_fn_t fn, - const char *expected_cmd) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_read_prefs_t *prefs = NULL; - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_t *cmd; - future_t *future; - request_t *request; - const char *reply; - int i; - - if (is_mongos) { - server = mock_mongos_new (WIRE_VERSION_OP_MSG); - } else { - char* ismaster = bson_strdup_printf ("{'ok': 1.0," - " 'ismaster': true," - " 'setName': 'rs0'," - " 'secondary': true," - " 'minWireVersion': 0," - " 'maxWireVersion': %d}", - WIRE_VERSION_OP_MSG); - server = mock_server_new (); - mock_server_auto_ismaster (server, ismaster); - bson_free (ismaster); - } - - mock_server_auto_endsessions (server); - - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - for (i = 0; i < 2; i++) { - if (i == 1) { - /* user-supplied read preference primary makes no difference */ - prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - } - - cursor = fn (collection, prefs); - future = future_cursor_next (cursor, &doc); - cmd = tmp_bson (expected_cmd); - request = mock_server_receives_msg (server, 0, cmd); - reply = "{'ok': 1," - " 'cursor': {" - " 'id': 0," - " 'ns': 'db.collection'," - " 'firstBatch': [{'a': 1}]}}"; - - mock_server_replies_simple (request, reply); - BSON_ASSERT (future_get_bool (future)); - future_destroy (future); - request_destroy (request); - mongoc_cursor_destroy (cursor); - mongoc_read_prefs_destroy (prefs); /* null ok */ - } - - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static mongoc_cursor_t * -find (mongoc_collection_t *collection, mongoc_read_prefs_t *prefs) -{ - return mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), NULL /* opts */, prefs); -} - - -static mongoc_cursor_t * -aggregate (mongoc_collection_t *collection, mongoc_read_prefs_t *prefs) -{ - return mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson ("{}"), NULL /* opts */, prefs); -} - - -/* direct connection to a secondary requires read pref primaryPreferred to - * avoid "not master" error from server */ -static void -test_op_msg_direct_secondary () -{ - _test_op_msg_direct_connection ( - false /* is_mongos */, - find, - "{" - " 'find': 'collection'," - " '$readPreference': {'mode': 'primaryPreferred'}" - "}"); - - _test_op_msg_direct_connection ( - false /* is_mongos */, - aggregate, - "{" - " 'aggregate': 'collection'," - " '$readPreference': {'mode': 'primaryPreferred'}" - "}"); -} - - -/* direct connection to mongos must not auto-add read pref primaryPreferred */ -static void -test_op_msg_direct_mongos () -{ - _test_op_msg_direct_connection (true /* is_mongos */, - find, - "{" - " 'find': 'collection'," - " '$readPreference': {'$exists': false}" - "}"); - - _test_op_msg_direct_connection (true /* is_mongos */, - aggregate, - "{" - " 'aggregate': 'collection'," - " '$readPreference': {'$exists': false}" - "}"); -} - - -void -test_read_prefs_install (TestSuite *suite) -{ - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/standalone/null", test_read_prefs_standalone_null); - TestSuite_AddMockServerTest (suite, - "/ReadPrefs/standalone/primary", - test_read_prefs_standalone_primary); - TestSuite_AddMockServerTest (suite, - "/ReadPrefs/standalone/secondary", - test_read_prefs_standalone_secondary); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/standalone/tags", test_read_prefs_standalone_tags); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/rsprimary/primary", test_read_prefs_primary_rsprimary); - TestSuite_AddMockServerTest (suite, - "/ReadPrefs/rssecondary/secondary", - test_read_prefs_secondary_rssecondary); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/mongos/null", test_read_prefs_mongos_null); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/mongos/primary", test_read_prefs_mongos_primary); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/mongos/secondary", test_read_prefs_mongos_secondary); - TestSuite_AddMockServerTest (suite, - "/ReadPrefs/mongos/secondaryPreferred", - test_read_prefs_mongos_secondary_preferred); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/mongos/tags", test_read_prefs_mongos_tags); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/mongos/readConcern", test_mongos_read_concern); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/OP_MSG/secondary", test_op_msg_direct_secondary); - TestSuite_AddMockServerTest ( - suite, "/ReadPrefs/OP_MSG/mongos", test_op_msg_direct_mongos); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-read-write-concern.c b/lib/mongoc/libmongoc/tests/test-mongoc-read-write-concern.c deleted file mode 100644 index 9664c8ae6e830a6426a8eb0685cdaff5efc917a5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-read-write-concern.c +++ /dev/null @@ -1,246 +0,0 @@ -#include <mongoc/mongoc.h> -#include <bson/bson-types.h> - -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-write-concern-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-opts-helpers-private.h" -#include "json-test.h" -#include "test-libmongoc.h" - - -static void -compare_write_concern (const mongoc_write_concern_t *wc_correct, - const mongoc_write_concern_t *wc) -{ - ASSERT_CMPINT32 (wc_correct->w, ==, wc->w); - ASSERT_CMPINT32 (wc_correct->wtimeout, ==, wc->wtimeout); - ASSERT_CMPINT (wc_correct->journal, ==, wc->journal); -} - - -static void -compare_read_concern (const mongoc_read_concern_t *rc_correct, - const mongoc_read_concern_t *rc) -{ - ASSERT_CMPSTR (rc_correct->level, rc->level); -} - -mongoc_write_concern_t * -convert_write_concern (const bson_t *wc_doc) -{ - mongoc_write_concern_t *wc; - bson_iter_t iter; - const char *key; - - wc = mongoc_write_concern_new (); - BSON_ASSERT (bson_iter_init (&iter, wc_doc)); - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - - if (strcmp (key, "w") == 0) { - if (BSON_ITER_HOLDS_UTF8 (&iter)) { - if (strcmp (bson_lookup_utf8 (wc_doc, "w"), "majority") == 0) { - mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_MAJORITY); - } else { - mongoc_write_concern_set_wtag (wc, - bson_lookup_utf8 (wc_doc, "w")); - } - } else { - if (bson_lookup_int32 (wc_doc, "w") < 0) { - goto invalid; - } - mongoc_write_concern_set_w (wc, bson_lookup_int32 (wc_doc, "w")); - } - } else if (strcmp (key, "wtimeoutMS") == 0) { - if (bson_lookup_int32 (wc_doc, "wtimeoutMS") < 0) { - goto invalid; - } - mongoc_write_concern_set_wtimeout_int64 ( - wc, bson_lookup_int32 (wc_doc, "wtimeoutMS")); - } else if (strcmp (key, "journal") == 0) { - mongoc_write_concern_set_journal ( - wc, bson_iter_value (&iter)->value.v_bool); - } - } - - if (wc->w == 0 && wc->journal == 1) { - goto invalid; - } - - return wc; - -invalid: - mongoc_write_concern_destroy (wc); - return NULL; -} - -mongoc_read_concern_t * -convert_read_concern (const bson_t *rc_doc) -{ - mongoc_read_concern_t *rc; - bson_iter_t iter; - const char *key; - - rc = mongoc_read_concern_new (); - BSON_ASSERT (bson_iter_init (&iter, rc_doc)); - - while (bson_iter_next (&iter)) { - key = bson_iter_key (&iter); - - if (strcmp (key, "level") == 0) { - if (BSON_ITER_HOLDS_UTF8 (&iter)) { - mongoc_read_concern_set_level (rc, - bson_lookup_utf8 (rc_doc, "level")); - } else { - goto invalid; - } - } - } - - return rc; - -invalid: - mongoc_read_concern_destroy (rc); - return NULL; -} - - -static void -test_rw_concern_uri (bson_t *scenario) -{ - bson_iter_t scenario_iter; - bson_iter_t test_iter; - bson_t test; - const char *description; - const char *uri_str; - bool valid; - mongoc_uri_t *uri; - bson_t rc_doc; - bson_t wc_doc; - const mongoc_read_concern_t *rc; - const mongoc_write_concern_t *wc; - mongoc_write_concern_t *wc_correct; - mongoc_read_concern_t *rc_correct; - - /* initialize tests with the scenario */ - BSON_ASSERT (bson_iter_init_find (&scenario_iter, scenario, "tests")); - BSON_ASSERT (bson_iter_recurse (&scenario_iter, &test_iter)); - - while (bson_iter_next (&test_iter)) { - bson_iter_bson (&test_iter, &test); - - description = bson_lookup_utf8 (&test, "description"); - uri_str = bson_lookup_utf8 (&test, "uri"); - valid = _mongoc_lookup_bool (&test, "valid", true); - - if (_mongoc_lookup_bool (&test, "warning", false)) { - MONGOC_ERROR ("update the \"%s\" test to handle warning: true", - description); - abort (); - } - - uri = mongoc_uri_new_with_error (uri_str, NULL); - if (!valid) { - BSON_ASSERT (!uri); - continue; - } - - BSON_ASSERT (uri); - - if (bson_has_field (&test, "readConcern")) { - rc = mongoc_uri_get_read_concern (uri); - bson_lookup_doc (&test, "readConcern", &rc_doc); - rc_correct = convert_read_concern (&rc_doc); - compare_read_concern (rc_correct, rc); - mongoc_read_concern_destroy (rc_correct); - } - - if (bson_has_field (&test, "writeConcern")) { - wc = mongoc_uri_get_write_concern (uri); - bson_lookup_doc (&test, "writeConcern", &wc_doc); - wc_correct = convert_write_concern (&wc_doc); - compare_write_concern (wc_correct, wc); - mongoc_write_concern_destroy (wc_correct); - } - - mongoc_uri_destroy (uri); - } -} - -static void -test_rw_concern_document (bson_t *scenario) -{ - bson_iter_t scenario_iter; - bson_iter_t test_iter; - bson_t test; - bool valid; - bson_t rc_doc; - bson_t wc_doc; - mongoc_write_concern_t *wc; - mongoc_read_concern_t *rc; - const bson_t *wc_doc_result; - const bson_t *rc_doc_result; - bson_t rc_doc_correct; - bson_t wc_doc_correct; - - BSON_ASSERT (bson_iter_init_find (&scenario_iter, scenario, "tests")); - BSON_ASSERT (bson_iter_recurse (&scenario_iter, &test_iter)); - - while (bson_iter_next (&test_iter)) { - bson_iter_bson (&test_iter, &test); - valid = _mongoc_lookup_bool (&test, "valid", true); - - if (bson_has_field (&test, "readConcern")) { - bson_lookup_doc (&test, "readConcern", &rc_doc); - rc = convert_read_concern (&rc_doc); - } else { - rc = mongoc_read_concern_new (); - } - - if (bson_has_field (&test, "writeConcern")) { - bson_lookup_doc (&test, "writeConcern", &wc_doc); - wc = convert_write_concern (&wc_doc); - } else { - wc = mongoc_write_concern_new (); - } - - if (!valid) { - BSON_ASSERT (rc == NULL || wc == NULL); - mongoc_write_concern_destroy (wc); - mongoc_read_concern_destroy (rc); - continue; - } - - if (bson_has_field (&test, "readConcernDocument")) { - bson_lookup_doc (&test, "readConcernDocument", &rc_doc_correct); - rc_doc_result = _mongoc_read_concern_get_bson (rc); - match_bson (&rc_doc_correct, rc_doc_result, false /* is_command */); - } - - if (bson_has_field (&test, "writeConcernDocument")) { - bson_lookup_doc (&test, "writeConcernDocument", &wc_doc_correct); - wc_doc_result = _mongoc_write_concern_get_bson (wc); - match_bson (&wc_doc_correct, wc_doc_result, false); - } - - mongoc_write_concern_destroy (wc); - mongoc_read_concern_destroy (rc); - } -} - - -void -test_read_write_concern_install (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - ASSERT ( - realpath (JSON_DIR "/read_write_concern/connection-string", resolved)); - install_json_test_suite (suite, resolved, &test_rw_concern_uri); - - test_framework_resolve_path (JSON_DIR "/read_write_concern/document", - resolved); - install_json_test_suite (suite, resolved, &test_rw_concern_document); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-retryable-reads.c b/lib/mongoc/libmongoc/tests/test-mongoc-retryable-reads.c deleted file mode 100644 index ecca5910020127a52113b155e1e296732201157f..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-retryable-reads.c +++ /dev/null @@ -1,306 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-collection-private.h" - -#include "json-test.h" -#include "test-libmongoc.h" -#include "mock_server/mock-rs.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "json-test-operations.h" - -static bool -retryable_reads_test_run_operation (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation) -{ - bool *explicit_session = (bool *) ctx->config->ctx; - bson_t reply; - bool res; - - res = json_test_operation (ctx, - test, - operation, - ctx->collection, - *explicit_session ? ctx->sessions[0] : NULL, - &reply); - - bson_destroy (&reply); - - return res; -} - - -/* Callback for JSON tests from Retryable Reads Spec */ -static void -test_retryable_reads_cb (bson_t *scenario) -{ - bool explicit_session; - json_test_config_t config = JSON_TEST_CONFIG_INIT; - - /* use the context pointer to send "explicit_session" to the callback */ - config.ctx = &explicit_session; - config.run_operation_cb = retryable_reads_test_run_operation; - config.scenario = scenario; - config.command_started_events_only = true; - explicit_session = true; - run_json_general_test (&config); - explicit_session = false; - run_json_general_test (&config); -} - - -static void -_set_failpoint (mongoc_client_t *client) -{ - bson_error_t error; - bson_t *cmd = - tmp_bson ("{'configureFailPoint': 'failCommand'," - " 'mode': {'times': 1}," - " 'data': {'errorCode': 10107, 'failCommands': ['count']}}"); - - ASSERT_OR_PRINT ( - mongoc_client_command_simple (client, "admin", cmd, NULL, NULL, &error), - error); -} -/* Test code paths for all command helpers */ -static void -test_cmd_helpers (void *ctx) -{ - mongoc_uri_t *uri; - mongoc_client_t *client; - uint32_t server_id; - mongoc_collection_t *collection; - bson_t *cmd; - bson_t reply; - bson_error_t error; - bson_iter_t iter; - mongoc_cursor_t *cursor; - mongoc_database_t *database; - const bson_t *doc; - - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_bool (uri, "retryReads", true); - - client = mongoc_client_new_from_uri (uri); - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - test_framework_set_ssl_opts (client); - mongoc_uri_destroy (uri); - - /* clean up in case a previous test aborted */ - server_id = mongoc_topology_select_server_id ( - client->topology, MONGOC_SS_WRITE, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - deactivate_fail_points (client, server_id); - - collection = get_test_collection (client, "retryable_reads"); - database = mongoc_client_get_database (client, "test"); - - if (!mongoc_collection_drop (collection, &error)) { - if (strcmp (error.message, "ns not found")) { - /* an error besides ns not found */ - ASSERT_OR_PRINT (false, error); - } - } - - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - collection, tmp_bson ("{'_id': 0}"), NULL, NULL, &error), - error); - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - collection, tmp_bson ("{'_id': 1}"), NULL, NULL, &error), - error); - - cmd = tmp_bson ("{'count': '%s'}", collection->collection); - - /* read helpers must retry. */ - _set_failpoint (client); - ASSERT_OR_PRINT (mongoc_client_read_command_with_opts ( - client, "test", cmd, NULL, NULL, &reply, &error), - error); - bson_iter_init_find (&iter, &reply, "n"); - ASSERT (bson_iter_as_int64 (&iter) == 2); - bson_destroy (&reply); - - _set_failpoint (client); - ASSERT_OR_PRINT (mongoc_database_read_command_with_opts ( - database, cmd, NULL, NULL, &reply, &error), - error); - bson_iter_init_find (&iter, &reply, "n"); - ASSERT (bson_iter_as_int64 (&iter) == 2); - bson_destroy (&reply); - - _set_failpoint (client); - ASSERT_OR_PRINT (mongoc_collection_read_command_with_opts ( - collection, cmd, NULL, NULL, &reply, &error), - error); - bson_iter_init_find (&iter, &reply, "n"); - ASSERT (bson_iter_as_int64 (&iter) == 2); - bson_destroy (&reply); - - /* TODO: once CDRIVER-3314 is resolved, test the read+write helpers. */ - - /* read/write agnostic command_simple helpers must not retry. */ - _set_failpoint (client); - ASSERT ( - !mongoc_client_command_simple (client, "test", cmd, NULL, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - - _set_failpoint (client); - ASSERT (!mongoc_database_command_simple (database, cmd, NULL, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - - _set_failpoint (client); - ASSERT ( - !mongoc_collection_command_simple (collection, cmd, NULL, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - - - /* read/write agnostic command_with_opts helpers must not retry. */ - _set_failpoint (client); - ASSERT (!mongoc_client_command_with_opts ( - client, "test", cmd, NULL, NULL, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - - _set_failpoint (client); - ASSERT (!mongoc_database_command_with_opts ( - database, cmd, NULL, NULL, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - - _set_failpoint (client); - ASSERT (!mongoc_collection_command_with_opts ( - collection, cmd, NULL, NULL, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - - /* read/write agnostic command_simple_with_server_id helper must not retry. - */ - server_id = mongoc_topology_select_server_id ( - client->topology, MONGOC_SS_WRITE, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - _set_failpoint (client); - ASSERT (!mongoc_client_command_simple_with_server_id ( - client, "test", cmd, NULL, server_id, NULL, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - - - /* deprecated command helpers (which goes through cursor logic) function must - * not retry. */ - _set_failpoint (client); - cursor = mongoc_client_command ( - client, "test", MONGOC_QUERY_NONE, 0, 1, 1, cmd, NULL, NULL); - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - mongoc_cursor_destroy (cursor); - - _set_failpoint (client); - cursor = mongoc_database_command ( - database, MONGOC_QUERY_NONE, 0, 1, 1, cmd, NULL, NULL); - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - mongoc_cursor_destroy (cursor); - - _set_failpoint (client); - cursor = mongoc_collection_command ( - collection, MONGOC_QUERY_NONE, 0, 1, 1, cmd, NULL, NULL); - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 10107, "Failing command"); - mongoc_cursor_destroy (cursor); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - deactivate_fail_points (client, server_id); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_retry_reads_off (void *ctx) -{ - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_collection_t *collection; - uint32_t server_id; - bson_t *cmd; - bson_error_t error; - bool res; - - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_bool (uri, "retryreads", false); - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - - /* clean up in case a previous test aborted */ - server_id = mongoc_topology_select_server_id ( - client->topology, MONGOC_SS_WRITE, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - deactivate_fail_points (client, server_id); - - collection = get_test_collection (client, "retryable_reads"); - - cmd = tmp_bson ("{'configureFailPoint': 'failCommand'," - " 'mode': {'times': 1}," - " 'data': {'errorCode': 10107, 'failCommands': ['count']}}"); - ASSERT_OR_PRINT (mongoc_client_command_simple_with_server_id ( - client, "admin", cmd, NULL, server_id, NULL, &error), - error); - - cmd = tmp_bson ("{'count': 'coll'}", collection->collection); - - res = mongoc_collection_read_command_with_opts ( - collection, cmd, NULL, NULL, NULL, &error); - ASSERT (!res); - ASSERT_CONTAINS (error.message, - "Failing command due to 'failCommand' failpoint"); - - deactivate_fail_points (client, server_id); - - mongoc_collection_destroy (collection); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); -} - -/* - *----------------------------------------------------------------------- - * - * Runner for the JSON tests for retryable reads. - * - *----------------------------------------------------------------------- - */ -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - test_framework_resolve_path (JSON_DIR "/retryable_reads", resolved); - install_json_test_suite_with_check (suite, - resolved, - test_retryable_reads_cb, - TestSuite_CheckLive, - test_framework_skip_if_no_failpoint); -} - -void -test_retryable_reads_install (TestSuite *suite) -{ - test_all_spec_tests (suite); - /* Since we need failpoints, require wire version 7 */ - TestSuite_AddFull (suite, - "/retryable_reads/cmd_helpers", - test_cmd_helpers, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_7, - test_framework_skip_if_mongos, - test_framework_skip_if_no_failpoint); - TestSuite_AddFull (suite, - "/retryable_reads/retry_off", - test_retry_reads_off, - NULL, - NULL, - test_framework_skip_if_max_wire_version_less_than_7, - test_framework_skip_if_mongos, - test_framework_skip_if_no_failpoint); -} \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-retryable-writes.c b/lib/mongoc/libmongoc/tests/test-mongoc-retryable-writes.c deleted file mode 100644 index b7fd5ed4d4543febb8e2397efd669aa53d38cf34..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-retryable-writes.c +++ /dev/null @@ -1,619 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-collection-private.h" - -#include "json-test.h" -#include "test-libmongoc.h" -#include "mock_server/mock-rs.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "json-test-operations.h" - - -static bool -retryable_writes_test_run_operation (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation) -{ - bool *explicit_session = (bool *) ctx->config->ctx; - bson_t reply; - bool res; - - res = json_test_operation (ctx, - test, - operation, - ctx->collection, - *explicit_session ? ctx->sessions[0] : NULL, - &reply); - - bson_destroy (&reply); - - return res; -} - - -/* Callback for JSON tests from Retryable Writes Spec */ -static void -test_retryable_writes_cb (bson_t *scenario) -{ - bool explicit_session; - json_test_config_t config = JSON_TEST_CONFIG_INIT; - - /* use the context pointer to send "explicit_session" to the callback */ - config.ctx = &explicit_session; - config.run_operation_cb = retryable_writes_test_run_operation; - config.scenario = scenario; - config.command_started_events_only = true; - explicit_session = true; - run_json_general_test (&config); - explicit_session = false; - run_json_general_test (&config); -} - - -/* "Replica Set Failover Test" from Retryable Writes Spec */ -static void -test_rs_failover (void) -{ - mock_rs_t *rs; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_client_session_t *cs; - bson_t opts = BSON_INITIALIZER; - future_t *future; - request_t *request; - bson_error_t error; - bson_t *b = tmp_bson ("{}"); - - rs = mock_rs_with_autoismaster (WIRE_VERSION_OP_MSG, - true /* has primary */, - 2 /* secondaries */, - 0 /* arbiters */); - - mock_rs_run (rs); - uri = mongoc_uri_copy (mock_rs_get_uri (rs)); - mongoc_uri_set_option_as_bool (uri, "retryWrites", true); - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "db", "collection"); - cs = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (cs, error); - ASSERT_OR_PRINT (mongoc_client_session_append (cs, &opts, &error), error); - - /* initial insert triggers replica set discovery */ - future = future_collection_insert_one (collection, b, &opts, NULL, &error); - request = - mock_rs_receives_msg (rs, 0, tmp_bson ("{'insert': 'collection'}"), b); - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - future_destroy (future); - - /* failover */ - mock_rs_stepdown (rs); - mock_rs_elect (rs, 1 /* server id */); - - /* insert receives "not master" from old primary, reselects and retries */ - future = future_collection_insert_one ( - collection, tmp_bson ("{}"), &opts, NULL, &error); - - request = - mock_rs_receives_msg (rs, 0, tmp_bson ("{'insert': 'collection'}"), b); - BSON_ASSERT (mock_rs_request_is_to_secondary (rs, request)); - mock_server_replies_simple (request, "{'ok': 0, 'errmsg': 'not master'}"); - request_destroy (request); - - request = - mock_rs_receives_msg (rs, 0, tmp_bson ("{'insert': 'collection'}"), b); - BSON_ASSERT (mock_rs_request_is_to_primary (rs, request)); - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - future_destroy (future); - - bson_destroy (&opts); - mongoc_client_session_destroy (cs); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_rs_destroy (rs); -} - - -/* Test code paths for _mongoc_client_command_with_opts */ -static void -test_command_with_opts (void *ctx) -{ - mongoc_uri_t *uri; - mongoc_client_t *client; - uint32_t server_id; - mongoc_collection_t *collection; - bson_t *cmd; - bson_t reply; - bson_t reply_result; - bson_error_t error; - - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_bool (uri, "retryWrites", true); - - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - mongoc_uri_destroy (uri); - - /* clean up in case a previous test aborted */ - server_id = mongoc_topology_select_server_id ( - client->topology, MONGOC_SS_WRITE, NULL, &error); - ASSERT_OR_PRINT (server_id, error); - deactivate_fail_points (client, server_id); - - collection = get_test_collection (client, "retryable_writes"); - - if (!mongoc_collection_drop (collection, &error)) { - if (strcmp (error.message, "ns not found")) { - /* an error besides ns not found */ - ASSERT_OR_PRINT (false, error); - } - } - - ASSERT_OR_PRINT ( - mongoc_collection_insert_one ( - collection, tmp_bson ("{'_id':1, 'x': 1}"), NULL, NULL, &error), - error); - - cmd = tmp_bson ("{'configureFailPoint': 'onPrimaryTransactionalWrite'," - " 'mode': {'times': 1}," - " 'data': {'failBeforeCommitExceptionCode': 1}}"); - - ASSERT_OR_PRINT (mongoc_client_command_simple_with_server_id ( - client, "admin", cmd, NULL, server_id, NULL, &error), - error); - - cmd = tmp_bson ("{'findAndModify': '%s', 'query': {'_id': 1}, 'update': " - "{'$inc': {'x': 1}}, 'new': true}", - collection->collection); - - ASSERT_OR_PRINT (mongoc_collection_read_write_command_with_opts ( - collection, cmd, NULL, NULL, &reply, &error), - error); - - bson_lookup_doc (&reply, "value", &reply_result); - ASSERT (match_bson (&reply_result, tmp_bson ("{'_id': 1, 'x': 2}"), false)); - - deactivate_fail_points (client, server_id); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_destroy (&reply_result); - bson_destroy (&reply); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_insert_one_unacknowledged (void) -{ - mongoc_uri_t *uri; - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (WIRE_VERSION_RETRY_WRITES); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_bool (uri, "retryWrites", true); - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "db", "collection"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_set_journal (wc, false); - mongoc_write_concern_append (wc, &opts); - - future = future_collection_insert_one ( - collection, tmp_bson ("{}"), &opts, NULL, &error); - - request = mock_server_receives_msg ( - server, - 2, /* set moreToCome bit in mongoc_op_msg_flags_t */ - tmp_bson ( - "{'txnNumber': {'$exists': false}, 'lsid': {'$exists': false}}"), - tmp_bson ("{}")); - ASSERT (future_get_bool (future)); - mock_server_auto_endsessions (server); - - mongoc_write_concern_destroy (wc); - mongoc_uri_destroy (uri); - request_destroy (request); - bson_destroy (&opts); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_update_one_unacknowledged (void) -{ - mongoc_uri_t *uri; - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (WIRE_VERSION_RETRY_WRITES); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_bool (uri, "retryWrites", true); - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "db", "collection"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_set_journal (wc, false); - mongoc_write_concern_append (wc, &opts); - - future = future_collection_update_one (collection, - tmp_bson ("{}"), - tmp_bson ("{'$set': {'x': 1}}"), - &opts, - NULL, - &error); - - request = mock_server_receives_msg ( - server, - 2, /* set moreToCome bit in mongoc_op_msg_flags_t */ - tmp_bson ( - "{'txnNumber': {'$exists': false}, 'lsid': {'$exists': false}}"), - tmp_bson ("{'q': {}, 'u': {'$set': {'x': 1}}}")); - ASSERT (future_get_bool (future)); - - mongoc_write_concern_destroy (wc); - mongoc_uri_destroy (uri); - request_destroy (request); - bson_destroy (&opts); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_delete_one_unacknowledged (void) -{ - mongoc_uri_t *uri; - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (WIRE_VERSION_RETRY_WRITES); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_bool (uri, "retryWrites", true); - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "db", "collection"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_set_journal (wc, false); - mongoc_write_concern_append (wc, &opts); - - future = future_collection_delete_one ( - collection, tmp_bson ("{}"), &opts, NULL, &error); - - request = mock_server_receives_msg ( - server, - 2, /* set moreToCome bit in mongoc_op_msg_flags_t */ - tmp_bson ( - "{'txnNumber': {'$exists': false}, 'lsid': {'$exists': false}}"), - tmp_bson ("{'q': {}, 'limit': 1}")); - ASSERT (future_get_bool (future)); - - mongoc_write_concern_destroy (wc); - mongoc_uri_destroy (uri); - request_destroy (request); - bson_destroy (&opts); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_bulk_operation_execute_unacknowledged (void) -{ - mongoc_uri_t *uri; - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_write_concern_t *wc; - mongoc_bulk_operation_t *bulk; - bson_t opts = BSON_INITIALIZER; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (WIRE_VERSION_RETRY_WRITES); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_bool (uri, "retryWrites", true); - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "db", "collection"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_set_journal (wc, false); - mongoc_write_concern_append (wc, &opts); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - mongoc_bulk_operation_insert (bulk, tmp_bson ("{'_id': 1}")); - future = future_bulk_operation_execute (bulk, NULL, &error); - - request = mock_server_receives_msg ( - server, - 2, /* set moreToCome bit in mongoc_op_msg_flags_t */ - tmp_bson ( - "{'txnNumber': {'$exists': false}, 'lsid': {'$exists': false}}"), - tmp_bson ("{'_id': 1}")); - ASSERT (future_get_uint32_t (future) == 1); - - mongoc_write_concern_destroy (wc); - mongoc_uri_destroy (uri); - mongoc_bulk_operation_destroy (bulk); - request_destroy (request); - bson_destroy (&opts); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_remove_unacknowledged (void) -{ - mongoc_uri_t *uri; - mock_server_t *server; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_write_concern_t *wc; - bson_t opts = BSON_INITIALIZER; - future_t *future; - request_t *request; - bson_error_t error; - - server = mock_mongos_new (WIRE_VERSION_RETRY_WRITES); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_bool (uri, "retryWrites", true); - client = mongoc_client_new_from_uri (uri); - collection = mongoc_client_get_collection (client, "db", "collection"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_set_journal (wc, false); - - future = future_collection_remove ( - collection, MONGOC_REMOVE_NONE, tmp_bson ("{'a': 1}"), wc, &error); - - request = mock_server_receives_msg ( - server, - 2, /* set moreToCome bit in mongoc_op_msg_flags_t */ - tmp_bson ( - "{'txnNumber': {'$exists': false}, 'lsid': {'$exists': false}}"), - tmp_bson ("{'q': {'a': 1}, 'limit': 0}")); - ASSERT (future_get_bool (future)); - - mongoc_write_concern_destroy (wc); - mongoc_uri_destroy (uri); - request_destroy (request); - bson_destroy (&opts); - future_destroy (future); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_retry_no_crypto (void *ctx) -{ - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_client_pool_t *pool; - - capture_logs (true); - - /* Test that no warning is logged if retryWrites is disabled. Warning logic - * is implemented in mongoc_topology_new, but test all public APIs that use - * the common code path. */ - client = mongoc_client_new ("mongodb://localhost/?retryWrites=false"); - BSON_ASSERT (client); - ASSERT_NO_CAPTURED_LOGS ("mongoc_client_new and retryWrites=false"); - mongoc_client_destroy (client); - - uri = mongoc_uri_new ("mongodb://localhost/?retryWrites=false"); - BSON_ASSERT (uri); - - client = mongoc_client_new_from_uri (uri); - BSON_ASSERT (client); - ASSERT_NO_CAPTURED_LOGS ("mongoc_client_new_from_uri and retryWrites=false"); - mongoc_client_destroy (client); - - pool = mongoc_client_pool_new (uri); - BSON_ASSERT (pool); - ASSERT_NO_CAPTURED_LOGS ("mongoc_client_pool_new and retryWrites=false"); - mongoc_client_pool_destroy (pool); - - mongoc_uri_destroy (uri); - - /* Test that a warning is logged if retryWrites is enabled. */ - client = mongoc_client_new ("mongodb://localhost/?retryWrites=true"); - BSON_ASSERT (client); - ASSERT_CAPTURED_LOG ( - "mongoc_client_new and retryWrites=true", - MONGOC_LOG_LEVEL_WARNING, - "retryWrites not supported without an SSL crypto library"); - mongoc_client_destroy (client); - - clear_captured_logs (); - - uri = mongoc_uri_new ("mongodb://localhost/?retryWrites=true"); - BSON_ASSERT (uri); - - client = mongoc_client_new_from_uri (uri); - BSON_ASSERT (client); - ASSERT_CAPTURED_LOG ( - "mongoc_client_new_from_uri and retryWrites=true", - MONGOC_LOG_LEVEL_WARNING, - "retryWrites not supported without an SSL crypto library"); - mongoc_client_destroy (client); - - clear_captured_logs (); - - pool = mongoc_client_pool_new (uri); - BSON_ASSERT (pool); - ASSERT_CAPTURED_LOG ( - "mongoc_client_pool_new and retryWrites=true", - MONGOC_LOG_LEVEL_WARNING, - "retryWrites not supported without an SSL crypto library"); - mongoc_client_pool_destroy (pool); - - mongoc_uri_destroy (uri); -} - -static void -test_unsupported_storage_engine_error (void) -{ - mock_rs_t *rs; - mongoc_client_t *client; - mongoc_collection_t *coll; - bson_t reply; - bson_error_t error; - future_t *future; - request_t *request; - mongoc_client_session_t *session; - bson_t opts; - const char *expected_msg = "This MongoDB deployment does not support " - "retryable writes. Please add retryWrites=false " - "to your connection string."; - - rs = mock_rs_with_autoismaster (WIRE_VERSION_RETRY_WRITES, true, 0, 0); - mock_rs_run (rs); - client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - coll = mongoc_client_get_collection (client, "test", "test"); - bson_init (&opts); - ASSERT_OR_PRINT (mongoc_client_session_append (session, &opts, &error), - error); - /* findandmodify is retryable through mongoc_client_write_command_with_opts. - */ - future = future_client_write_command_with_opts ( - client, - "test", - tmp_bson ("{'findandmodify': 'coll' }"), - &opts, - &reply, - &error); - request = mock_rs_receives_request (rs); - mock_server_replies_simple ( - request, - "{'ok': 0, 'code': 20, 'errmsg': 'Transaction numbers are great'}"); - request_destroy (request); - - BSON_ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS (error, MONGOC_ERROR_SERVER, 20, expected_msg); - ASSERT_MATCH (&reply, "{'code': 20, 'errmsg': '%s'}", expected_msg); - - bson_destroy (&opts); - mongoc_client_session_destroy (session); - bson_destroy (&reply); - future_destroy (future); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_rs_destroy (rs); -} -/* - *----------------------------------------------------------------------- - * - * Runner for the JSON tests for retryable writes. - * - *----------------------------------------------------------------------- - */ -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - test_framework_resolve_path (JSON_DIR "/retryable_writes", resolved); - install_json_test_suite_with_check (suite, - resolved, - test_retryable_writes_cb, - test_framework_skip_if_no_crypto, - test_framework_skip_if_not_replset); -} - -void -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", - test_command_with_opts, - NULL, - NULL, - test_framework_skip_if_not_rs_version_6); - TestSuite_AddMockServerTest (suite, - "/retryable_writes/insert_one_unacknowledged", - test_insert_one_unacknowledged, - test_framework_skip_if_no_crypto); - TestSuite_AddMockServerTest (suite, - "/retryable_writes/update_one_unacknowledged", - test_update_one_unacknowledged, - test_framework_skip_if_no_crypto); - TestSuite_AddMockServerTest (suite, - "/retryable_writes/delete_one_unacknowledged", - test_delete_one_unacknowledged, - test_framework_skip_if_no_crypto); - TestSuite_AddMockServerTest (suite, - "/retryable_writes/remove_unacknowledged", - test_remove_unacknowledged, - test_framework_skip_if_no_crypto); - TestSuite_AddMockServerTest ( - 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_AddMockServerTest ( - suite, - "/retryable_writes/unsupported_storage_engine_error", - test_unsupported_storage_engine_error, - test_framework_skip_if_no_crypto); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-rpc.c b/lib/mongoc/libmongoc/tests/test-mongoc-rpc.c deleted file mode 100644 index 5b02bbb3decd2415e9c3d385dd8b7c4c383357f9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-rpc.c +++ /dev/null @@ -1,686 +0,0 @@ -#include <fcntl.h> -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-array-private.h> -#include <mongoc/mongoc-rpc-private.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "TestSuite.h" -#include "mongoc/mongoc-cluster-private.h" - - -static uint8_t * -get_test_file (const char *filename, size_t *length) -{ - ssize_t len; - uint8_t *buf; - char real_filename[256]; - int fd; - - bson_snprintf ( - real_filename, sizeof real_filename, BINARY_DIR "/%s", filename); - -#ifdef _WIN32 - fd = _open (real_filename, O_RDONLY | _O_BINARY); -#else - fd = open (real_filename, O_RDONLY); -#endif - - if (fd == -1) { - fprintf (stderr, "Failed to open: %s\n", real_filename); - abort (); - } - - len = 40960; - buf = (uint8_t *) bson_malloc0 (len); -#ifdef _WIN32 - len = _read (fd, buf, (uint32_t) len); -#else - len = read (fd, buf, (uint32_t) len); -#endif - ASSERT (len > 0); - - *length = len; - return buf; -} - - -/* - * This function expects that @rpc is in HOST ENDIAN format. - */ -static void -assert_rpc_equal (const char *filename, mongoc_rpc_t *rpc) -{ - mongoc_array_t ar; - uint8_t *data; - mongoc_iovec_t *iov; - size_t length; - off_t off = 0; - int r; - int i; - - data = get_test_file (filename, &length); - _mongoc_array_init (&ar, sizeof (mongoc_iovec_t)); - - /* - * Gather our RPC into a series of iovec that can be compared - * to the buffer from the RCP snapshot file. - */ - _mongoc_rpc_gather (rpc, &ar); - -#if 0 - fprintf(stderr, "Before swabbing\n"); - fprintf(stderr, "=========================\n"); - mongoc_rpc_printf(rpc); -#endif - - _mongoc_rpc_swab_to_le (rpc); - -#if 0 - fprintf(stderr, "After swabbing\n"); - fprintf(stderr, "=========================\n"); - mongoc_rpc_printf(rpc); -#endif - - for (i = 0; i < ar.len; i++) { - iov = &_mongoc_array_index (&ar, mongoc_iovec_t, i); - ASSERT (iov->iov_len <= (length - off)); - r = memcmp (&data[off], iov->iov_base, iov->iov_len); - if (r) { - fprintf (stderr, "\nError iovec: %u\n", i); - } - ASSERT (r == 0); - off += iov->iov_len; - } - - _mongoc_array_destroy (&ar); - bson_free (data); -} - - -static void -test_mongoc_rpc_delete_gather (void) -{ - mongoc_rpc_t rpc; - bson_t sel; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - bson_init (&sel); - - rpc.header.msg_len = 0; - rpc.header.request_id = 1234; - rpc.header.response_to = -1; - rpc.header.opcode = MONGOC_OPCODE_DELETE; - rpc.delete_.zero = 0; - rpc.delete_.collection = "test.test"; - rpc.delete_.flags = MONGOC_DELETE_SINGLE_REMOVE; - rpc.delete_.selector = bson_get_data (&sel); - - assert_rpc_equal ("delete1.dat", &rpc); - bson_destroy (&sel); -} - - -static void -test_mongoc_rpc_delete_scatter (void) -{ - uint8_t *data; - mongoc_rpc_t rpc; - bool r; - bson_t sel; - size_t length; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - bson_init (&sel); - - data = get_test_file ("delete1.dat", &length); - r = _mongoc_rpc_scatter (&rpc, data, length); - ASSERT (r); - _mongoc_rpc_swab_from_le (&rpc); - - ASSERT_CMPINT (rpc.header.msg_len, ==, 39); - ASSERT_CMPINT (rpc.header.request_id, ==, 1234); - ASSERT_CMPINT (rpc.header.response_to, ==, -1); - ASSERT_CMPINT (rpc.header.opcode, ==, MONGOC_OPCODE_DELETE); - ASSERT_CMPINT (rpc.delete_.zero, ==, 0); - ASSERT (!strcmp ("test.test", rpc.delete_.collection)); - ASSERT_CMPINT (rpc.delete_.flags, ==, MONGOC_DELETE_SINGLE_REMOVE); - ASSERT (!memcmp (rpc.delete_.selector, bson_get_data (&sel), sel.len)); - - assert_rpc_equal ("delete1.dat", &rpc); - bson_free (data); - bson_destroy (&sel); -} - - -static void -test_mongoc_rpc_get_more_gather (void) -{ - mongoc_rpc_t rpc; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - rpc.header.msg_len = 0; - rpc.header.request_id = 1234; - rpc.header.response_to = -1; - rpc.header.opcode = MONGOC_OPCODE_GET_MORE; - rpc.get_more.zero = 0; - rpc.get_more.collection = "test.test"; - rpc.get_more.n_return = 5; - rpc.get_more.cursor_id = 12345678L; - - assert_rpc_equal ("get_more1.dat", &rpc); -} - - -static void -test_mongoc_rpc_get_more_scatter (void) -{ - uint8_t *data; - mongoc_rpc_t rpc; - bool r; - size_t length; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - data = get_test_file ("get_more1.dat", &length); - r = _mongoc_rpc_scatter (&rpc, data, length); - ASSERT (r); - _mongoc_rpc_swab_from_le (&rpc); - - ASSERT (rpc.header.msg_len == 42); - ASSERT (rpc.header.request_id == 1234); - ASSERT (rpc.header.response_to == -1); - ASSERT (rpc.header.opcode == MONGOC_OPCODE_GET_MORE); - ASSERT (rpc.get_more.zero == 0); - ASSERT (!strcmp ("test.test", rpc.get_more.collection)); - ASSERT (rpc.get_more.n_return == 5); - ASSERT (rpc.get_more.cursor_id == 12345678); - - assert_rpc_equal ("get_more1.dat", &rpc); - bson_free (data); -} - - -static void -test_mongoc_rpc_insert_gather (void) -{ - mongoc_rpc_t rpc; - mongoc_iovec_t iov[20]; - bson_t b; - int i; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - bson_init (&b); - - for (i = 0; i < 20; i++) { - iov[i].iov_base = (void *) bson_get_data (&b); - iov[i].iov_len = b.len; - } - - rpc.header.msg_len = 0; - rpc.header.request_id = 1234; - rpc.header.response_to = -1; - rpc.header.opcode = MONGOC_OPCODE_INSERT; - rpc.insert.flags = MONGOC_INSERT_CONTINUE_ON_ERROR; - rpc.insert.collection = "test.test"; - rpc.insert.documents = iov; - rpc.insert.n_documents = 20; - - assert_rpc_equal ("insert1.dat", &rpc); - bson_destroy (&b); -} - - -static void -test_mongoc_rpc_insert_scatter (void) -{ - bson_reader_t *reader; - uint8_t *data; - const bson_t *b; - mongoc_rpc_t rpc; - bool r; - bool eof = false; - size_t length; - bson_t empty; - int count = 0; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - bson_init (&empty); - - data = get_test_file ("insert1.dat", &length); - r = _mongoc_rpc_scatter (&rpc, data, length); - ASSERT (r); - _mongoc_rpc_swab_from_le (&rpc); - - ASSERT_CMPINT (rpc.header.msg_len, ==, 130); - ASSERT_CMPINT (rpc.header.request_id, ==, 1234); - ASSERT_CMPINT (rpc.header.response_to, ==, (uint32_t) -1); - ASSERT_CMPINT (rpc.header.opcode, ==, MONGOC_OPCODE_INSERT); - ASSERT_CMPINT (rpc.insert.flags, ==, MONGOC_INSERT_CONTINUE_ON_ERROR); - ASSERT (!strcmp ("test.test", rpc.insert.collection)); - reader = - bson_reader_new_from_data ((uint8_t *) rpc.insert.documents[0].iov_base, - rpc.insert.documents[0].iov_len); - while ((b = bson_reader_read (reader, &eof))) { - r = bson_equal (b, &empty); - ASSERT (r); - count++; - } - ASSERT (eof == true); - ASSERT (count == 20); - - assert_rpc_equal ("insert1.dat", &rpc); - bson_free (data); - bson_reader_destroy (reader); - bson_destroy (&empty); -} - - -static void -test_mongoc_rpc_kill_cursors_gather (void) -{ - mongoc_rpc_t rpc; - int64_t cursors[] = {1, 2, 3, 4, 5}; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - rpc.header.msg_len = 0; - rpc.header.request_id = 1234; - rpc.header.response_to = -1; - rpc.header.opcode = MONGOC_OPCODE_KILL_CURSORS; - rpc.kill_cursors.zero = 0; - rpc.kill_cursors.n_cursors = 5; - rpc.kill_cursors.cursors = cursors; - - assert_rpc_equal ("kill_cursors1.dat", &rpc); -} - - -static void -test_mongoc_rpc_kill_cursors_scatter (void) -{ - uint8_t *data; - const int64_t cursors[] = {1, 2, 3, 4, 5}; - mongoc_rpc_t rpc; - bool r; - size_t length; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - data = get_test_file ("kill_cursors1.dat", &length); - r = _mongoc_rpc_scatter (&rpc, data, length); - ASSERT (r); - _mongoc_rpc_swab_from_le (&rpc); - - ASSERT_CMPINT (rpc.header.msg_len, ==, 64); - ASSERT_CMPINT (rpc.header.request_id, ==, 1234); - ASSERT_CMPINT (rpc.header.response_to, ==, -1); - ASSERT_CMPINT (rpc.header.opcode, ==, MONGOC_OPCODE_KILL_CURSORS); - ASSERT_CMPINT (rpc.kill_cursors.zero, ==, 0); - ASSERT_CMPINT (rpc.kill_cursors.n_cursors, ==, 5); - ASSERT (!memcmp (rpc.kill_cursors.cursors, cursors, 5 * 8)); - - assert_rpc_equal ("kill_cursors1.dat", &rpc); - bson_free (data); -} - - -static void -test_mongoc_rpc_query_gather (void) -{ - mongoc_rpc_t rpc; - bson_t b; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - bson_init (&b); - - rpc.header.msg_len = 0; - rpc.header.request_id = 1234; - rpc.header.response_to = -1; - rpc.header.opcode = MONGOC_OPCODE_QUERY; - rpc.query.flags = MONGOC_QUERY_SLAVE_OK; - rpc.query.collection = "test.test"; - rpc.query.skip = 5; - rpc.query.n_return = 1; - rpc.query.query = bson_get_data (&b); - rpc.query.fields = bson_get_data (&b); - - assert_rpc_equal ("query1.dat", &rpc); - bson_destroy (&b); -} - - -static void -test_mongoc_rpc_query_scatter (void) -{ - uint8_t *data; - mongoc_rpc_t rpc; - bool r; - bson_t empty; - size_t length; - - bson_init (&empty); - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - data = get_test_file ("query1.dat", &length); - r = _mongoc_rpc_scatter (&rpc, data, length); - ASSERT (r); - _mongoc_rpc_swab_from_le (&rpc); - - ASSERT (rpc.header.msg_len == 48); - ASSERT (rpc.header.request_id == 1234); - ASSERT (rpc.header.response_to == (uint32_t) -1); - ASSERT (rpc.header.opcode == MONGOC_OPCODE_QUERY); - ASSERT (rpc.query.flags == MONGOC_QUERY_SLAVE_OK); - ASSERT (!strcmp (rpc.query.collection, "test.test")); - ASSERT (rpc.query.skip == 5); - ASSERT (rpc.query.n_return == 1); - ASSERT (!memcmp (rpc.query.query, bson_get_data (&empty), 5)); - ASSERT (!memcmp (rpc.query.fields, bson_get_data (&empty), 5)); - - bson_destroy (&empty); - assert_rpc_equal ("query1.dat", &rpc); - bson_free (data); -} - - -static void -test_mongoc_rpc_reply_gather (void) -{ - bson_writer_t *writer; - mongoc_rpc_t rpc; - uint8_t *buf = NULL; - size_t len = 0; - bson_t *b; - int i; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - writer = bson_writer_new (&buf, &len, 0, bson_realloc_ctx, NULL); - for (i = 0; i < 100; i++) { - bson_writer_begin (writer, &b); - bson_writer_end (writer); - } - - rpc.header.msg_len = 0; - rpc.header.request_id = 1234; - rpc.header.response_to = -1; - rpc.header.opcode = MONGOC_OPCODE_REPLY; - rpc.reply.flags = MONGOC_REPLY_AWAIT_CAPABLE; - rpc.reply.cursor_id = 12345678; - rpc.reply.start_from = 50; - rpc.reply.n_returned = 100; - rpc.reply.documents = buf; - rpc.reply.documents_len = (int32_t) bson_writer_get_length (writer); - - assert_rpc_equal ("reply1.dat", &rpc); - bson_writer_destroy (writer); - bson_free (buf); -} - - -static void -test_mongoc_rpc_reply_scatter (void) -{ - bson_reader_t *reader; - uint8_t *data; - mongoc_rpc_t rpc; - const bson_t *b; - bool r; - bool eof = false; - bson_t empty; - size_t length; - int count = 0; - - bson_init (&empty); - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - data = get_test_file ("reply1.dat", &length); - r = _mongoc_rpc_scatter (&rpc, data, length); - ASSERT (r); - _mongoc_rpc_swab_from_le (&rpc); - - ASSERT_CMPINT (rpc.header.msg_len, ==, 536); - ASSERT_CMPINT (rpc.header.request_id, ==, 1234); - ASSERT_CMPINT (rpc.header.response_to, ==, -1); - ASSERT_CMPINT (rpc.header.opcode, ==, MONGOC_OPCODE_REPLY); - ASSERT_CMPINT (rpc.reply.flags, ==, MONGOC_REPLY_AWAIT_CAPABLE); - ASSERT (rpc.reply.cursor_id == 12345678LL); - ASSERT_CMPINT (rpc.reply.start_from, ==, 50); - ASSERT_CMPINT (rpc.reply.n_returned, ==, 100); - ASSERT_CMPINT (rpc.reply.documents_len, ==, 500); - reader = - bson_reader_new_from_data (rpc.reply.documents, rpc.reply.documents_len); - while ((b = bson_reader_read (reader, &eof))) { - r = bson_equal (b, &empty); - ASSERT (r); - count++; - } - ASSERT (eof == true); - ASSERT (count == 100); - - bson_destroy (&empty); - assert_rpc_equal ("reply1.dat", &rpc); - bson_reader_destroy (reader); - bson_free (data); -} - - -static void -test_mongoc_rpc_reply_scatter2 (void) -{ - bson_reader_t *reader; - uint8_t *data; - mongoc_rpc_t rpc; - const bson_t *b; - bool r; - bool eof = false; - bson_t empty; - size_t length; - int count = 0; - - bson_init (&empty); - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - data = get_test_file ("reply2.dat", &length); - r = _mongoc_rpc_scatter (&rpc, data, length); - ASSERT (r); - _mongoc_rpc_swab_from_le (&rpc); - - ASSERT (rpc.header.msg_len == 16236); - ASSERT (rpc.header.request_id == 0); - ASSERT (rpc.header.response_to == 1234); - ASSERT (rpc.header.opcode == MONGOC_OPCODE_REPLY); - ASSERT (rpc.reply.flags == 0); - ASSERT (rpc.reply.cursor_id == 12345678); - ASSERT (rpc.reply.start_from == 0); - ASSERT (rpc.reply.n_returned == 100); - ASSERT (rpc.reply.documents_len == 16200); - reader = - bson_reader_new_from_data (rpc.reply.documents, rpc.reply.documents_len); - while ((b = bson_reader_read (reader, &eof))) { - count++; - } - ASSERT (eof == true); - ASSERT (count == 100); - - bson_destroy (&empty); - assert_rpc_equal ("reply2.dat", &rpc); - bson_reader_destroy (reader); - bson_free (data); -} - - -static void -test_mongoc_rpc_update_gather (void) -{ - mongoc_rpc_t rpc; - bson_t sel; - bson_t up; - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - bson_init (&sel); - bson_init (&up); - - rpc.header.msg_len = 0; - rpc.header.request_id = 1234; - rpc.header.response_to = -1; - rpc.header.opcode = MONGOC_OPCODE_UPDATE; - rpc.update.zero = 0; - rpc.update.collection = "test.test"; - rpc.update.flags = MONGOC_UPDATE_MULTI_UPDATE; - rpc.update.selector = bson_get_data (&sel); - rpc.update.update = bson_get_data (&up); - - assert_rpc_equal ("update1.dat", &rpc); - - bson_destroy (&sel); - bson_destroy (&up); -} - - -static void -test_mongoc_rpc_update_scatter (void) -{ - uint8_t *data; - mongoc_rpc_t rpc; - bool r; - bson_t b; - bson_t empty; - size_t length; - int32_t len; - - bson_init (&empty); - - memset (&rpc, 0xFFFFFFFF, sizeof rpc); - - data = get_test_file ("update1.dat", &length); - r = _mongoc_rpc_scatter (&rpc, data, length); - ASSERT (r); - _mongoc_rpc_swab_from_le (&rpc); - - ASSERT_CMPINT (rpc.header.msg_len, ==, 44); - ASSERT_CMPINT (rpc.header.request_id, ==, 1234); - ASSERT_CMPINT (rpc.header.response_to, ==, -1); - ASSERT_CMPINT (rpc.header.opcode, ==, MONGOC_OPCODE_UPDATE); - ASSERT_CMPINT (rpc.update.flags, ==, MONGOC_UPDATE_MULTI_UPDATE); - ASSERT (!strcmp (rpc.update.collection, "test.test")); - - memcpy (&len, rpc.update.selector, 4); - len = BSON_UINT32_FROM_LE (len); - ASSERT (len > 4); - r = bson_init_static (&b, rpc.update.selector, len); - ASSERT (r); - r = bson_equal (&b, &empty); - ASSERT (r); - bson_destroy (&b); - - memcpy (&len, rpc.update.update, 4); - len = BSON_UINT32_FROM_LE (len); - ASSERT (len > 4); - r = bson_init_static (&b, rpc.update.update, len); - ASSERT (r); - r = bson_equal (&b, &empty); - ASSERT (r); - bson_destroy (&b); - - bson_destroy (&empty); - assert_rpc_equal ("update1.dat", &rpc); - bson_free (data); -} - - -static void -test_mongoc_rpc_buffer_iov (void) -{ - mongoc_array_t ar; - mongoc_rpc_t rpc; - bson_t b; - size_t allocate; - char *no_header, *full_opcode; - char *matching_opcode; - int size; - mongoc_iovec_t iov; - - bson_init (&b); - _mongoc_array_init (&ar, sizeof (mongoc_iovec_t)); - - rpc.header.msg_len = 0; - rpc.header.request_id = 1234; - rpc.header.response_to = -1; - rpc.header.opcode = MONGOC_OPCODE_QUERY; - rpc.query.flags = MONGOC_QUERY_SLAVE_OK; - rpc.query.collection = "test.test"; - rpc.query.skip = 5; - rpc.query.n_return = 1; - rpc.query.query = bson_get_data (&b); - rpc.query.fields = bson_get_data (&b); - - _mongoc_rpc_gather (&rpc, &ar); - - allocate = rpc.header.msg_len - 16; - - BSON_ASSERT (allocate > 0); - full_opcode = bson_malloc0 (allocate + 16); - size = _mongoc_cluster_buffer_iovec ( - (mongoc_iovec_t *) ar.data, ar.len, 0, full_opcode); - ASSERT_CMPINT (size, ==, 48); - - iov.iov_len = size; - iov.iov_base = full_opcode; - no_header = bson_malloc0 (allocate); - size = _mongoc_cluster_buffer_iovec (&iov, 1, 16, no_header); - - ASSERT_CMPINT (size, ==, 32); - - matching_opcode = bson_malloc0 (rpc.header.msg_len); - memcpy (matching_opcode, full_opcode, 16); - memcpy (matching_opcode + 16, no_header, 32); - - ASSERT_MEMCMP (full_opcode + 16, no_header, 32); - ASSERT_MEMCMP (matching_opcode, full_opcode, 48); - - bson_free (no_header); - bson_free (full_opcode); - bson_free (matching_opcode); - - bson_destroy (&b); - _mongoc_array_destroy (&ar); -} - - -void -test_rpc_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Rpc/delete/gather", test_mongoc_rpc_delete_gather); - TestSuite_Add (suite, "/Rpc/delete/scatter", test_mongoc_rpc_delete_scatter); - TestSuite_Add ( - suite, "/Rpc/get_more/gather", test_mongoc_rpc_get_more_gather); - TestSuite_Add ( - suite, "/Rpc/get_more/scatter", test_mongoc_rpc_get_more_scatter); - TestSuite_Add (suite, "/Rpc/insert/gather", test_mongoc_rpc_insert_gather); - TestSuite_Add (suite, "/Rpc/insert/scatter", test_mongoc_rpc_insert_scatter); - TestSuite_Add ( - suite, "/Rpc/kill_cursors/gather", test_mongoc_rpc_kill_cursors_gather); - TestSuite_Add ( - suite, "/Rpc/kill_cursors/scatter", test_mongoc_rpc_kill_cursors_scatter); - TestSuite_Add (suite, "/Rpc/query/gather", test_mongoc_rpc_query_gather); - TestSuite_Add (suite, "/Rpc/query/scatter", test_mongoc_rpc_query_scatter); - TestSuite_Add (suite, "/Rpc/reply/gather", test_mongoc_rpc_reply_gather); - TestSuite_Add (suite, "/Rpc/reply/scatter", test_mongoc_rpc_reply_scatter); - TestSuite_Add (suite, "/Rpc/reply/scatter2", test_mongoc_rpc_reply_scatter2); - TestSuite_Add (suite, "/Rpc/update/gather", test_mongoc_rpc_update_gather); - TestSuite_Add (suite, "/Rpc/update/scatter", test_mongoc_rpc_update_scatter); - TestSuite_Add (suite, "/Rpc/buffer/iov", test_mongoc_rpc_buffer_iov); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-sample-commands.c b/lib/mongoc/libmongoc/tests/test-mongoc-sample-commands.c deleted file mode 100644 index 26396e665347ac878130ee33c291f83cb8b01645..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-sample-commands.c +++ /dev/null @@ -1,3519 +0,0 @@ -/* - * Copyright 2017 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. - */ - -/* MongoDB documentation examples - * - * One page on the MongoDB docs site shows a set of common tasks, with example - * code for each driver plus the mongo shell. The source files for these code - * examples are delimited with "Start Example N" / "End Example N" and so on. - * - * These are the C examples for that page. - */ - -/* clang-format off */ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-util-private.h> -#include <mongoc/mongoc-database-private.h> -#include <mongoc/mongoc-collection-private.h> - -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "test-conveniences.h" - - -typedef void (*sample_command_fn_t) (mongoc_database_t *db); -typedef void (*sample_txn_command_fn_t) (mongoc_client_t *client); - - -static void -test_sample_command (sample_command_fn_t fn, - int exampleno, - mongoc_database_t *db, - mongoc_collection_t *collection, - bool drop_collection) -{ - char *example_name = bson_strdup_printf ("example %d", exampleno); - capture_logs (true); - - fn (db); - - ASSERT_NO_CAPTURED_LOGS (example_name); - - if (drop_collection) { - mongoc_collection_drop (collection, NULL); - } - - bson_free (example_name); -} - - -static void -test_example_1 (mongoc_database_t *db) -{ - /* Start Example 1 */ - mongoc_collection_t *collection; - bson_t *doc; - bool r; - bson_error_t error; - - collection = mongoc_database_get_collection (db, "inventory"); - doc = BCON_NEW ( - "item", BCON_UTF8 ("canvas"), - "qty", BCON_INT64 (100), - "tags", "[", - BCON_UTF8 ("cotton"), - "]", - "size", "{", - "h", BCON_DOUBLE (28), - "w", BCON_DOUBLE (35.5), - "uom", BCON_UTF8 ("cm"), - "}"); - - r = mongoc_collection_insert_one (collection, doc, NULL, NULL, &error); - bson_destroy (doc); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - /* End Example 1 */ - ASSERT_COUNT (1, collection); - /* Start Example 1 Post */ -done: - mongoc_collection_destroy (collection); - /* End Example 1 Post */ -} - - -static void -test_example_2 (mongoc_database_t *db) -{ - /* Start Example 2 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("item", BCON_UTF8 ("canvas")); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 2 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 2 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 2 Post */ -} - - -static void -test_example_3 (mongoc_database_t *db) -{ - /* Start Example 3 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "item", BCON_UTF8 ("journal"), - "qty", BCON_INT64 (25), - "tags", "[", - BCON_UTF8 ("blank"), BCON_UTF8 ("red"), - "]", - "size", "{", - "h", BCON_DOUBLE (14), - "w", BCON_DOUBLE (21), - "uom", BCON_UTF8 ("cm"), - "}"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("mat"), - "qty", BCON_INT64 (85), - "tags", "[", - BCON_UTF8 ("gray"), - "]", - "size", "{", - "h", BCON_DOUBLE (27.9), - "w", BCON_DOUBLE (35.5), - "uom", BCON_UTF8 ("cm"), - "}"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("mousepad"), - "qty", BCON_INT64 (25), - "tags", "[", - BCON_UTF8 ("gel"), BCON_UTF8 ("blue"), - "]", - "size", "{", - "h", BCON_DOUBLE (19), - "w", BCON_DOUBLE (22.85), - "uom", BCON_UTF8 ("cm"), - "}"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 3 */ - ASSERT_COUNT (4, collection); - /* Start Example 3 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 3 Post */ -} - - -static void -test_example_6 (mongoc_database_t *db) -{ - /* Start Example 6 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "item", BCON_UTF8 ("journal"), - "qty", BCON_INT64 (25), - "size", "{", - "h", BCON_DOUBLE (14), - "w", BCON_DOUBLE (21), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("notebook"), - "qty", BCON_INT64 (50), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("paper"), - "qty", BCON_INT64 (100), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "status", BCON_UTF8 ("D")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("planner"), - "qty", BCON_INT64 (75), - "size", "{", - "h", BCON_DOUBLE (22.85), - "w", BCON_DOUBLE (30), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("D")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("postcard"), - "qty", BCON_INT64 (45), - "size", "{", - "h", BCON_DOUBLE (10), - "w", BCON_DOUBLE (15.25), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 6 */ - ASSERT_COUNT (5, collection); - /* Start Example 6 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 6 Post */ -} - - -static void -test_example_7 (mongoc_database_t *db) -{ - /* Start Example 7 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW (NULL); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 7 */ - ASSERT_CURSOR_COUNT (5, cursor); - /* Start Example 7 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 7 Post */ -} - - -static void -test_example_9 (mongoc_database_t *db) -{ - /* Start Example 9 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("D")); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 9 */ - ASSERT_CURSOR_COUNT (2, cursor); - /* Start Example 9 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 9 Post */ -} - - -static void -test_example_10 (mongoc_database_t *db) -{ - /* Start Example 10 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "status", "{", - "$in", "[", - BCON_UTF8 ("A"), BCON_UTF8 ("D"), - "]", - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 10 */ - ASSERT_CURSOR_COUNT (5, cursor); - /* Start Example 10 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 10 Post */ -} - - -static void -test_example_11 (mongoc_database_t *db) -{ - /* Start Example 11 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "status", BCON_UTF8 ("A"), - "qty", "{", - "$lt", BCON_INT64 (30), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 11 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 11 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 11 Post */ -} - - -static void -test_example_12 (mongoc_database_t *db) -{ - /* Start Example 12 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "$or", "[", - "{", - "status", BCON_UTF8 ("A"), - "}","{", - "qty", "{", - "$lt", BCON_INT64 (30), - "}", - "}", - "]"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 12 */ - ASSERT_CURSOR_COUNT (3, cursor); - /* Start Example 12 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 12 Post */ -} - - -static void -test_example_13 (mongoc_database_t *db) -{ - /* Start Example 13 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "status", BCON_UTF8 ("A"), - "$or", "[", - "{", - "qty", "{", - "$lt", BCON_INT64 (30), - "}", - "}","{", - "item", BCON_REGEX ("^p", ""), - "}", - "]"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 13 */ - ASSERT_CURSOR_COUNT (2, cursor); - /* Start Example 13 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 13 Post */ -} - - -static void -test_example_14 (mongoc_database_t *db) -{ - /* Start Example 14 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "item", BCON_UTF8 ("journal"), - "qty", BCON_INT64 (25), - "size", "{", - "h", BCON_DOUBLE (14), - "w", BCON_DOUBLE (21), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("notebook"), - "qty", BCON_INT64 (50), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("paper"), - "qty", BCON_INT64 (100), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "status", BCON_UTF8 ("D")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("planner"), - "qty", BCON_INT64 (75), - "size", "{", - "h", BCON_DOUBLE (22.85), - "w", BCON_DOUBLE (30), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("D")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("postcard"), - "qty", BCON_INT64 (45), - "size", "{", - "h", BCON_DOUBLE (10), - "w", BCON_DOUBLE (15.25), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 14 */ - - /* Start Example 14 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 14 Post */ -} - - -static void -test_example_15 (mongoc_database_t *db) -{ - /* Start Example 15 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "size", "{", - "h", BCON_DOUBLE (14), - "w", BCON_DOUBLE (21), - "uom", BCON_UTF8 ("cm"), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 15 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 15 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 15 Post */ -} - - -static void -test_example_16 (mongoc_database_t *db) -{ - /* Start Example 16 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "size", "{", - "w", BCON_DOUBLE (21), - "h", BCON_DOUBLE (14), - "uom", BCON_UTF8 ("cm"), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 16 */ - ASSERT_CURSOR_COUNT (0, cursor); - /* Start Example 16 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 16 Post */ -} - - -static void -test_example_17 (mongoc_database_t *db) -{ - /* Start Example 17 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("size.uom", BCON_UTF8 ("in")); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 17 */ - ASSERT_CURSOR_COUNT (2, cursor); - /* Start Example 17 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 17 Post */ -} - - -static void -test_example_18 (mongoc_database_t *db) -{ - /* Start Example 18 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "size.h", "{", - "$lt", BCON_INT64 (15), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 18 */ - ASSERT_CURSOR_COUNT (4, cursor); - /* Start Example 18 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 18 Post */ -} - - -static void -test_example_19 (mongoc_database_t *db) -{ - /* Start Example 19 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "size.h", "{", - "$lt", BCON_INT64 (15), - "}", - "size.uom", BCON_UTF8 ("in"), - "status", BCON_UTF8 ("D")); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 19 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 19 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 19 Post */ -} - - -static void -test_example_20 (mongoc_database_t *db) -{ - /* Start Example 20 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "item", BCON_UTF8 ("journal"), - "qty", BCON_INT64 (25), - "tags", "[", - BCON_UTF8 ("blank"), BCON_UTF8 ("red"), - "]", - "dim_cm", "[", - BCON_INT64 (14), BCON_INT64 (21), - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("notebook"), - "qty", BCON_INT64 (50), - "tags", "[", - BCON_UTF8 ("red"), BCON_UTF8 ("blank"), - "]", - "dim_cm", "[", - BCON_INT64 (14), BCON_INT64 (21), - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("paper"), - "qty", BCON_INT64 (100), - "tags", "[", - BCON_UTF8 ("red"), BCON_UTF8 ("blank"), BCON_UTF8 ("plain"), - "]", - "dim_cm", "[", - BCON_INT64 (14), BCON_INT64 (21), - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("planner"), - "qty", BCON_INT64 (75), - "tags", "[", - BCON_UTF8 ("blank"), BCON_UTF8 ("red"), - "]", - "dim_cm", "[", - BCON_DOUBLE (22.85), BCON_INT64 (30), - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("postcard"), - "qty", BCON_INT64 (45), - "tags", "[", - BCON_UTF8 ("blue"), - "]", - "dim_cm", "[", - BCON_INT64 (10), BCON_DOUBLE (15.25), - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 20 */ - - /* Start Example 20 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 20 Post */ -} - - -static void -test_example_21 (mongoc_database_t *db) -{ - /* Start Example 21 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "tags", "[", - BCON_UTF8 ("red"), BCON_UTF8 ("blank"), - "]"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 21 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 21 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 21 Post */ -} - - -static void -test_example_22 (mongoc_database_t *db) -{ - /* Start Example 22 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "tags", "{", - "$all", "[", - BCON_UTF8 ("red"), BCON_UTF8 ("blank"), - "]", - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 22 */ - ASSERT_CURSOR_COUNT (4, cursor); - /* Start Example 22 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 22 Post */ -} - - -static void -test_example_23 (mongoc_database_t *db) -{ - /* Start Example 23 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("tags", BCON_UTF8 ("red")); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 23 */ - ASSERT_CURSOR_COUNT (4, cursor); - /* Start Example 23 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 23 Post */ -} - - -static void -test_example_24 (mongoc_database_t *db) -{ - /* Start Example 24 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "dim_cm", "{", - "$gt", BCON_INT64 (25), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 24 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 24 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 24 Post */ -} - - -static void -test_example_25 (mongoc_database_t *db) -{ - /* Start Example 25 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "dim_cm", "{", - "$gt", BCON_INT64 (15), - "$lt", BCON_INT64 (20), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 25 */ - ASSERT_CURSOR_COUNT (4, cursor); - /* Start Example 25 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 25 Post */ -} - - -static void -test_example_26 (mongoc_database_t *db) -{ - /* Start Example 26 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "dim_cm", "{", - "$elemMatch", "{", - "$gt", BCON_INT64 (22), - "$lt", BCON_INT64 (30), - "}", - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 26 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 26 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 26 Post */ -} - - -static void -test_example_27 (mongoc_database_t *db) -{ - /* Start Example 27 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "dim_cm.1", "{", - "$gt", BCON_INT64 (25), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 27 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 27 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 27 Post */ -} - - -static void -test_example_28 (mongoc_database_t *db) -{ - /* Start Example 28 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "tags", "{", - "$size", BCON_INT64 (3), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 28 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 28 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 28 Post */ -} - - -static void -test_example_29 (mongoc_database_t *db) -{ - /* Start Example 29 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "item", BCON_UTF8 ("journal"), - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("A"), - "qty", BCON_INT64 (5), - "}","{", - "warehouse", BCON_UTF8 ("C"), - "qty", BCON_INT64 (15), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("notebook"), - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("C"), - "qty", BCON_INT64 (5), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("paper"), - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("A"), - "qty", BCON_INT64 (60), - "}","{", - "warehouse", BCON_UTF8 ("B"), - "qty", BCON_INT64 (15), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("planner"), - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("A"), - "qty", BCON_INT64 (40), - "}","{", - "warehouse", BCON_UTF8 ("B"), - "qty", BCON_INT64 (5), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("postcard"), - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("B"), - "qty", BCON_INT64 (15), - "}","{", - "warehouse", BCON_UTF8 ("C"), - "qty", BCON_INT64 (35), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 29 */ - - /* Start Example 29 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 29 Post */ -} - - -static void -test_example_30 (mongoc_database_t *db) -{ - /* Start Example 30 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "instock", "{", - "warehouse", BCON_UTF8 ("A"), - "qty", BCON_INT64 (5), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 30 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 30 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 30 Post */ -} - - -static void -test_example_31 (mongoc_database_t *db) -{ - /* Start Example 31 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "instock", "{", - "qty", BCON_INT64 (5), - "warehouse", BCON_UTF8 ("A"), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 31 */ - ASSERT_CURSOR_COUNT (0, cursor); - /* Start Example 31 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 31 Post */ -} - - -static void -test_example_32 (mongoc_database_t *db) -{ - /* Start Example 32 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "instock.0.qty", "{", - "$lte", BCON_INT64 (20), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 32 */ - ASSERT_CURSOR_COUNT (3, cursor); - /* Start Example 32 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 32 Post */ -} - - -static void -test_example_33 (mongoc_database_t *db) -{ - /* Start Example 33 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "instock.qty", "{", - "$lte", BCON_INT64 (20), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 33 */ - ASSERT_CURSOR_COUNT (5, cursor); - /* Start Example 33 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 33 Post */ -} - - -static void -test_example_34 (mongoc_database_t *db) -{ - /* Start Example 34 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "instock", "{", - "$elemMatch", "{", - "qty", BCON_INT64 (5), - "warehouse", BCON_UTF8 ("A"), - "}", - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 34 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 34 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 34 Post */ -} - - -static void -test_example_35 (mongoc_database_t *db) -{ - /* Start Example 35 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "instock", "{", - "$elemMatch", "{", - "qty", "{", - "$gt", BCON_INT64 (10), - "$lte", BCON_INT64 (20), - "}", - "}", - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 35 */ - ASSERT_CURSOR_COUNT (3, cursor); - /* Start Example 35 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 35 Post */ -} - - -static void -test_example_36 (mongoc_database_t *db) -{ - /* Start Example 36 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "instock.qty", "{", - "$gt", BCON_INT64 (10), - "$lte", BCON_INT64 (20), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 36 */ - ASSERT_CURSOR_COUNT (4, cursor); - /* Start Example 36 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 36 Post */ -} - - -static void -test_example_37 (mongoc_database_t *db) -{ - /* Start Example 37 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "instock.qty", BCON_INT64 (5), - "instock.warehouse", BCON_UTF8 ("A")); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 37 */ - ASSERT_CURSOR_COUNT (2, cursor); - /* Start Example 37 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 37 Post */ -} - - -static void -test_example_38 (mongoc_database_t *db) -{ - /* Start Example 38 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "_id", BCON_INT64 (1), - "item", BCON_NULL); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ("_id", BCON_INT64 (2)); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 38 */ - - /* Start Example 38 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 38 Post */ -} - - -static void -test_example_39 (mongoc_database_t *db) -{ - /* Start Example 39 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("item", BCON_NULL); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 39 */ - ASSERT_CURSOR_COUNT (2, cursor); - /* Start Example 39 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 39 Post */ -} - - -static void -test_example_40 (mongoc_database_t *db) -{ - /* Start Example 40 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "item", "{", - "$type", BCON_INT64 (10), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 40 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 40 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 40 Post */ -} - - -static void -test_example_41 (mongoc_database_t *db) -{ - /* Start Example 41 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ( - "item", "{", - "$exists", BCON_BOOL (false), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 41 */ - ASSERT_CURSOR_COUNT (1, cursor); - /* Start Example 41 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 41 Post */ -} - - -static void -test_example_42 (mongoc_database_t *db) -{ - /* Start Example 42 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "item", BCON_UTF8 ("journal"), - "status", BCON_UTF8 ("A"), - "size", "{", - "h", BCON_DOUBLE (14), - "w", BCON_DOUBLE (21), - "uom", BCON_UTF8 ("cm"), - "}", - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("A"), - "qty", BCON_INT64 (5), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("notebook"), - "status", BCON_UTF8 ("A"), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("C"), - "qty", BCON_INT64 (5), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("paper"), - "status", BCON_UTF8 ("D"), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("A"), - "qty", BCON_INT64 (60), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("planner"), - "status", BCON_UTF8 ("D"), - "size", "{", - "h", BCON_DOUBLE (22.85), - "w", BCON_DOUBLE (30), - "uom", BCON_UTF8 ("cm"), - "}", - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("A"), - "qty", BCON_INT64 (40), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("postcard"), - "status", BCON_UTF8 ("A"), - "size", "{", - "h", BCON_DOUBLE (10), - "w", BCON_DOUBLE (15.25), - "uom", BCON_UTF8 ("cm"), - "}", - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("B"), - "qty", BCON_INT64 (15), - "}","{", - "warehouse", BCON_UTF8 ("C"), - "qty", BCON_INT64 (35), - "}", - "]"); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 42 */ - - /* Start Example 42 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 42 Post */ -} - - -static void -test_example_43 (mongoc_database_t *db) -{ - /* Start Example 43 */ - mongoc_collection_t *collection; - bson_t *filter; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("A")); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - /* End Example 43 */ - ASSERT_CURSOR_COUNT (3, cursor); - /* Start Example 43 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 43 Post */ -} - - -static void -test_example_44 (mongoc_database_t *db) -{ - /* Start Example 44 */ - mongoc_collection_t *collection; - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("A")); - opts = BCON_NEW ("projection", "{", "item", BCON_INT64 (1), - "status", BCON_INT64 (1), "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - /* End Example 44 */ - { - const bson_t *doc; - - while (mongoc_cursor_next (cursor, &doc)) { - ASSERT_HAS_FIELD (doc, "_id"); - ASSERT_HAS_FIELD (doc, "item"); - ASSERT_HAS_FIELD (doc, "status"); - ASSERT_HAS_NOT_FIELD (doc, "size"); - ASSERT_HAS_NOT_FIELD (doc, "instock"); - } - } - /* Start Example 44 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (opts); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 44 Post */ -} - - -static void -test_example_45 (mongoc_database_t *db) -{ - /* Start Example 45 */ - mongoc_collection_t *collection; - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("A")); - opts = BCON_NEW ("projection", "{", "item", BCON_INT64 (1), - "status", BCON_INT64 (1), - "_id", BCON_INT64 (0), "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - /* End Example 45 */ - { - const bson_t *doc; - - while (mongoc_cursor_next (cursor, &doc)) { - ASSERT_HAS_NOT_FIELD (doc, "_id"); - ASSERT_HAS_FIELD (doc, "item"); - ASSERT_HAS_FIELD (doc, "status"); - ASSERT_HAS_NOT_FIELD (doc, "size"); - ASSERT_HAS_NOT_FIELD (doc, "instock"); - } - } - /* Start Example 45 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (opts); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 45 Post */ -} - - -static void -test_example_46 (mongoc_database_t *db) -{ - /* Start Example 46 */ - mongoc_collection_t *collection; - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("A")); - opts = BCON_NEW ("projection", "{", "status", BCON_INT64 (0), - "instock", BCON_INT64 (0), "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - /* End Example 46 */ - { - const bson_t *doc; - - while (mongoc_cursor_next (cursor, &doc)) { - ASSERT_HAS_FIELD (doc, "_id"); - ASSERT_HAS_FIELD (doc, "item"); - ASSERT_HAS_NOT_FIELD (doc, "status"); - ASSERT_HAS_FIELD (doc, "size"); - ASSERT_HAS_NOT_FIELD (doc, "instock"); - } - } - /* Start Example 46 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (opts); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 46 Post */ -} - - -static void -test_example_47 (mongoc_database_t *db) -{ - /* Start Example 47 */ - mongoc_collection_t *collection; - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("A")); - opts = BCON_NEW ("projection", "{", "item", BCON_INT64 (1), - "status", BCON_INT64 (1), - "size.uom", BCON_INT64 (1), "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - /* End Example 47 */ - { - const bson_t *doc; - - while (mongoc_cursor_next (cursor, &doc)) { - bson_t size; - - ASSERT_HAS_FIELD (doc, "_id"); - ASSERT_HAS_FIELD (doc, "item"); - ASSERT_HAS_FIELD (doc, "status"); - ASSERT_HAS_FIELD (doc, "size"); - ASSERT_HAS_NOT_FIELD (doc, "instock"); - bson_lookup_doc (doc, "size", &size); - ASSERT_HAS_FIELD (&size, "uom"); - ASSERT_HAS_NOT_FIELD (&size, "h"); - ASSERT_HAS_NOT_FIELD (&size, "w"); - } - } - /* Start Example 47 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (opts); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 47 Post */ -} - - -static void -test_example_48 (mongoc_database_t *db) -{ - /* Start Example 48 */ - mongoc_collection_t *collection; - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("A")); - opts = BCON_NEW ("projection", "{", "size.uom", BCON_INT64 (0), "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - /* End Example 48 */ - { - const bson_t *doc; - - while (mongoc_cursor_next (cursor, &doc)) { - bson_t size; - - ASSERT_HAS_FIELD (doc, "_id"); - ASSERT_HAS_FIELD (doc, "item"); - ASSERT_HAS_FIELD (doc, "status"); - ASSERT_HAS_FIELD (doc, "size"); - ASSERT_HAS_FIELD (doc, "instock"); - bson_lookup_doc (doc, "size", &size); - ASSERT_HAS_NOT_FIELD (&size, "uom"); - ASSERT_HAS_FIELD (&size, "h"); - ASSERT_HAS_FIELD (&size, "w"); - } - } - /* Start Example 48 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (opts); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 48 Post */ -} - - -static void -test_example_49 (mongoc_database_t *db) -{ - /* Start Example 49 */ - mongoc_collection_t *collection; - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("A")); - opts = BCON_NEW ("projection", "{", "item", BCON_INT64 (1), - "status", BCON_INT64 (1), - "instock.qty", BCON_INT64 (1), "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - /* End Example 49 */ - { - const bson_t *doc; - - while (mongoc_cursor_next (cursor, &doc)) { - ASSERT_HAS_FIELD (doc, "_id"); - ASSERT_HAS_FIELD (doc, "item"); - ASSERT_HAS_FIELD (doc, "status"); - ASSERT_HAS_NOT_FIELD (doc, "size"); - ASSERT_HAS_FIELD (doc, "instock"); - { - bson_iter_t iter; - - BSON_ASSERT (bson_iter_init_find (&iter, doc, "instock")); - while (bson_iter_next (&iter)) { - bson_t subdoc; - - bson_iter_bson (&iter, &subdoc); - ASSERT_HAS_NOT_FIELD (&subdoc, "warehouse"); - ASSERT_HAS_FIELD (&subdoc, "qty"); - } - } - } - } - /* Start Example 49 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (opts); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 49 Post */ -} - - -static void -test_example_50 (mongoc_database_t *db) -{ - /* Start Example 50 */ - mongoc_collection_t *collection; - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - - collection = mongoc_database_get_collection (db, "inventory"); - filter = BCON_NEW ("status", BCON_UTF8 ("A")); - opts = BCON_NEW ("projection", "{", "item", BCON_INT64 (1), - "status", BCON_INT64 (1), - "instock", "{", - "$slice", BCON_INT64 (-1), - "}", "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - /* End Example 50 */ - { - const bson_t *doc; - - while (mongoc_cursor_next (cursor, &doc)) { - bson_t subdoc; - - ASSERT_HAS_FIELD (doc, "_id"); - ASSERT_HAS_FIELD (doc, "item"); - ASSERT_HAS_FIELD (doc, "status"); - ASSERT_HAS_NOT_FIELD (doc, "size"); - ASSERT_HAS_FIELD (doc, "instock"); - bson_lookup_doc (doc, "instock", &subdoc); - ASSERT_CMPUINT32 (1, ==, bson_count_keys (&subdoc)); - } - } - /* Start Example 50 Post */ - mongoc_cursor_destroy (cursor); - bson_destroy (opts); - bson_destroy (filter); - mongoc_collection_destroy (collection); - /* End Example 50 Post */ -} - - -static void -test_example_51 (mongoc_database_t *db) -{ - /* Start Example 51 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "item", BCON_UTF8 ("canvas"), - "qty", BCON_INT64 (100), - "size", "{", - "h", BCON_DOUBLE (28), - "w", BCON_DOUBLE (35.5), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("journal"), - "qty", BCON_INT64 (25), - "size", "{", - "h", BCON_DOUBLE (14), - "w", BCON_DOUBLE (21), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("mat"), - "qty", BCON_INT64 (85), - "size", "{", - "h", BCON_DOUBLE (27.9), - "w", BCON_DOUBLE (35.5), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("mousepad"), - "qty", BCON_INT64 (25), - "size", "{", - "h", BCON_DOUBLE (19), - "w", BCON_DOUBLE (22.85), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("P")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("notebook"), - "qty", BCON_INT64 (50), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "status", BCON_UTF8 ("P")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("paper"), - "qty", BCON_INT64 (100), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "status", BCON_UTF8 ("D")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("planner"), - "qty", BCON_INT64 (75), - "size", "{", - "h", BCON_DOUBLE (22.85), - "w", BCON_DOUBLE (30), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("D")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("postcard"), - "qty", BCON_INT64 (45), - "size", "{", - "h", BCON_DOUBLE (10), - "w", BCON_DOUBLE (15.25), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("sketchbook"), - "qty", BCON_INT64 (80), - "size", "{", - "h", BCON_DOUBLE (14), - "w", BCON_DOUBLE (21), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("sketch pad"), - "qty", BCON_INT64 (95), - "size", "{", - "h", BCON_DOUBLE (22.85), - "w", BCON_DOUBLE (30.5), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 51 */ - - /* Start Example 51 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 51 Post */ -} - - -static void -test_example_52 (mongoc_database_t *db) -{ - /* Start Example 52 */ - mongoc_collection_t *collection; - bson_t *selector; - bson_t *update; - bool r; - bson_error_t error; - - collection = mongoc_database_get_collection (db, "inventory"); - selector = BCON_NEW ("item", BCON_UTF8 ("paper")); - update = BCON_NEW ( - "$set", "{", - "size.uom", BCON_UTF8 ("cm"), - "status", BCON_UTF8 ("P"), - "}", - "$currentDate", "{", - "lastModified", BCON_BOOL (true), - "}"); - - /* MONGOC_UPDATE_NONE means "no special options" */ - r = mongoc_collection_update (collection, MONGOC_UPDATE_NONE, selector, - update, NULL, &error); - bson_destroy (selector); - bson_destroy (update); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - /* End Example 52 */ - { - bson_t *filter; - mongoc_cursor_t *cursor; - const bson_t *doc; - - filter = BCON_NEW ("item", BCON_UTF8 ("paper")); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - while (mongoc_cursor_next (cursor, &doc)) { - ASSERT_CMPSTR (bson_lookup_utf8 (doc, "size.uom"), "cm"); - ASSERT_CMPSTR (bson_lookup_utf8 (doc, "status"), "P"); - ASSERT_HAS_FIELD (doc, "lastModified"); - } - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - } - /* Start Example 52 Post */ -done: - mongoc_collection_destroy (collection); - /* End Example 52 Post */ -} - - -static void -test_example_53 (mongoc_database_t *db) -{ - /* Start Example 53 */ - mongoc_collection_t *collection; - bson_t *selector; - bson_t *update; - bool r; - bson_error_t error; - - collection = mongoc_database_get_collection (db, "inventory"); - selector = BCON_NEW ( - "qty", "{", - "$lt", BCON_INT64 (50), - "}"); - update = BCON_NEW ( - "$set", "{", - "size.uom", BCON_UTF8 ("in"), - "status", BCON_UTF8 ("P"), - "}", - "$currentDate", "{", - "lastModified", BCON_BOOL (true), - "}"); - - r = mongoc_collection_update (collection, MONGOC_UPDATE_MULTI_UPDATE, selector, update, NULL, &error); - bson_destroy (selector); - bson_destroy (update); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - /* End Example 53 */ - { - bson_t *filter; - mongoc_cursor_t *cursor; - const bson_t *doc; - - filter = BCON_NEW ( - "qty", "{", - "$lt", BCON_INT64 (50), - "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); - while (mongoc_cursor_next (cursor, &doc)) { - ASSERT_CMPSTR (bson_lookup_utf8 (doc, "size.uom"), "in"); - ASSERT_CMPSTR (bson_lookup_utf8 (doc, "status"), "P"); - ASSERT_HAS_FIELD (doc, "lastModified"); - } - mongoc_cursor_destroy (cursor); - bson_destroy (filter); - } - /* Start Example 53 Post */ -done: - mongoc_collection_destroy (collection); - /* End Example 53 Post */ -} - - -static void -test_example_54 (mongoc_database_t *db) -{ - /* Start Example 54 */ - mongoc_collection_t *collection; - bson_t *selector; - bson_t *replacement; - bool r; - bson_error_t error; - - collection = mongoc_database_get_collection (db, "inventory"); - selector = BCON_NEW ("item", BCON_UTF8 ("paper")); - replacement = BCON_NEW ( - "item", BCON_UTF8 ("paper"), - "instock", "[", - "{", - "warehouse", BCON_UTF8 ("A"), - "qty", BCON_INT64 (60), - "}","{", - "warehouse", BCON_UTF8 ("B"), - "qty", BCON_INT64 (40), - "}", - "]"); - - /* MONGOC_UPDATE_NONE means "no special options" */ - r = mongoc_collection_update (collection, MONGOC_UPDATE_NONE, selector, replacement, NULL, &error); - bson_destroy (selector); - bson_destroy (replacement); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - /* End Example 54 */ - { - bson_t *filter; - bson_t *opts; - mongoc_cursor_t *cursor; - const bson_t *doc; - - filter = BCON_NEW ("item", BCON_UTF8 ("paper")); - opts = BCON_NEW ("projection", "{", "_id", BCON_INT64 (0), "}"); - cursor = mongoc_collection_find_with_opts (collection, filter, opts, NULL); - while (mongoc_cursor_next (cursor, &doc)) { - bson_t subdoc; - - ASSERT_CMPUINT32 (2, ==, bson_count_keys (doc)); - ASSERT_HAS_FIELD (doc, "item"); - ASSERT_HAS_FIELD (doc, "instock"); - bson_lookup_doc (doc, "instock", &subdoc); - ASSERT_CMPUINT32 (2, ==, bson_count_keys (&subdoc)); - } - mongoc_cursor_destroy (cursor); - bson_destroy (opts); - bson_destroy (filter); - } - /* Start Example 54 Post */ -done: - mongoc_collection_destroy (collection); - /* End Example 54 Post */ -} - - -static void -test_example_55 (mongoc_database_t *db) -{ - /* Start Example 55 */ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - bson_t *doc; - bool r; - bson_error_t error; - bson_t reply; - - collection = mongoc_database_get_collection (db, "inventory"); - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - doc = BCON_NEW ( - "item", BCON_UTF8 ("journal"), - "qty", BCON_INT64 (25), - "size", "{", - "h", BCON_DOUBLE (14), - "w", BCON_DOUBLE (21), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("notebook"), - "qty", BCON_INT64 (50), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "status", BCON_UTF8 ("P")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("paper"), - "qty", BCON_INT64 (100), - "size", "{", - "h", BCON_DOUBLE (8.5), - "w", BCON_DOUBLE (11), - "uom", BCON_UTF8 ("in"), - "}", - "status", BCON_UTF8 ("D")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("planner"), - "qty", BCON_INT64 (75), - "size", "{", - "h", BCON_DOUBLE (22.85), - "w", BCON_DOUBLE (30), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("D")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - doc = BCON_NEW ( - "item", BCON_UTF8 ("postcard"), - "qty", BCON_INT64 (45), - "size", "{", - "h", BCON_DOUBLE (10), - "w", BCON_DOUBLE (15.25), - "uom", BCON_UTF8 ("cm"), - "}", - "status", BCON_UTF8 ("A")); - - r = mongoc_bulk_operation_insert_with_opts (bulk, doc, NULL, &error); - bson_destroy (doc); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - - /* "reply" is initialized on success or error */ - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - /* End Example 55 */ - ASSERT_COUNT (5, collection); - /* Start Example 55 Post */ -done: - bson_destroy (&reply); - mongoc_bulk_operation_destroy (bulk); - mongoc_collection_destroy (collection); - /* End Example 55 Post */ -} - - -static void -test_example_57 (mongoc_database_t *db) -{ - /* Start Example 57 */ - mongoc_collection_t *collection; - bson_t *selector; - bool r; - bson_error_t error; - - collection = mongoc_database_get_collection (db, "inventory"); - selector = BCON_NEW ("status", BCON_UTF8 ("A")); - - r = mongoc_collection_delete_many (collection, selector, NULL, NULL, &error); - bson_destroy (selector); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - /* End Example 57 */ - ASSERT_COUNT (3, collection); - /* Start Example 57 Post */ -done: - mongoc_collection_destroy (collection); - /* End Example 57 Post */ -} - - -static void -test_example_58 (mongoc_database_t *db) -{ - /* Start Example 58 */ - mongoc_collection_t *collection; - bson_t *selector; - bool r; - bson_error_t error; - - collection = mongoc_database_get_collection (db, "inventory"); - selector = BCON_NEW ("status", BCON_UTF8 ("D")); - - r = mongoc_collection_delete_one (collection, selector, NULL, NULL, &error); - bson_destroy (selector); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - /* End Example 58 */ - ASSERT_COUNT (2, collection); - /* Start Example 58 Post */ -done: - mongoc_collection_destroy (collection); - /* End Example 58 Post */ -} - - -static void -test_example_56 (mongoc_database_t *db) -{ - /* Start Example 56 */ - mongoc_collection_t *collection; - bson_t *selector; - bool r; - bson_error_t error; - - collection = mongoc_database_get_collection (db, "inventory"); - selector = BCON_NEW (NULL); - - r = mongoc_collection_delete_many (collection, selector, NULL, NULL, &error); - bson_destroy (selector); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - goto done; - } - /* End Example 56 */ - ASSERT_COUNT (0, collection); - /* Start Example 56 Post */ -done: - mongoc_collection_destroy (collection); - /* End Example 56 Post */ -} - - -typedef struct { - bson_mutex_t lock; - mongoc_collection_t *collection; - bool done; -} change_stream_ctx_t; - - -static void * -insert_docs (void *p) -{ - change_stream_ctx_t *ctx = (change_stream_ctx_t *) p; - bson_t doc = BSON_INITIALIZER; - bson_error_t error; - bool r; - - while (true) { - bson_mutex_lock (&ctx->lock); - r = mongoc_collection_insert ( - ctx->collection, MONGOC_INSERT_NONE, &doc, NULL, &error); - ASSERT_OR_PRINT (r, error); - if (ctx->done) { - bson_destroy (&doc); - bson_mutex_unlock (&ctx->lock); - return 0; - } - - bson_mutex_unlock (&ctx->lock); - _mongoc_usleep (100 * 1000); /* 100 ms */ - } - bson_destroy (&doc); -} - - -static void -test_sample_change_stream_command (sample_command_fn_t fn, - mongoc_database_t *db) -{ - mongoc_client_t *client; - change_stream_ctx_t ctx; - bson_thread_t thread; - int r; - - /* change streams require a replica set running MongoDB 3.6+ */ - if (test_framework_skip_if_not_rs_version_6 () && - test_framework_skip_if_slow ()) { - - /* separate client for the background thread */ - client = test_framework_client_new (); - - bson_mutex_init (&ctx.lock); - ctx.collection = mongoc_client_get_collection ( - client, db->name, "inventory"); - ctx.done = false; - - r = bson_thread_create (&thread, insert_docs, (void *) &ctx); - ASSERT_OR_PRINT_ERRNO (r == 0, r); - - capture_logs (true); - fn (db); - ASSERT_NO_CAPTURED_LOGS ("change stream examples"); - - bson_mutex_lock (&ctx.lock); - ctx.done = true; - bson_mutex_unlock (&ctx.lock); - bson_thread_join (thread); - - mongoc_collection_destroy (ctx.collection); - mongoc_client_destroy (client); - } -} - - -static void -test_example_change_stream (mongoc_database_t *db) -{ - /* Start Changestream Example 1 */ - mongoc_collection_t *collection; - bson_t *pipeline = bson_new (); - bson_t opts = BSON_INITIALIZER; - mongoc_change_stream_t *stream; - const bson_t *change; - const bson_t *resume_token; - bson_error_t error; - - collection = mongoc_database_get_collection (db, "inventory"); - stream = mongoc_collection_watch (collection, pipeline, NULL /* opts */); - mongoc_change_stream_next (stream, &change); - if (mongoc_change_stream_error_document (stream, &error, NULL)) { - MONGOC_ERROR ("%s\n", error.message); - } - - mongoc_change_stream_destroy (stream); - /* End Changestream Example 1 */ - - /* Start Changestream Example 2 */ - BSON_APPEND_UTF8 (&opts, "fullDocument", "updateLookup"); - stream = mongoc_collection_watch (collection, pipeline, &opts); - mongoc_change_stream_next (stream, &change); - if (mongoc_change_stream_error_document (stream, &error, NULL)) { - MONGOC_ERROR ("%s\n", error.message); - } - - mongoc_change_stream_destroy (stream); - /* End Changestream Example 2 */ - - bson_reinit (&opts); - - /* Start Changestream Example 3 */ - stream = mongoc_collection_watch (collection, pipeline, NULL); - if (mongoc_change_stream_next (stream, &change)) { - resume_token = mongoc_change_stream_get_resume_token (stream); - BSON_APPEND_DOCUMENT (&opts, "resumeAfter", resume_token); - - mongoc_change_stream_destroy (stream); - stream = mongoc_collection_watch (collection, pipeline, &opts); - mongoc_change_stream_next (stream, &change); - mongoc_change_stream_destroy (stream); - } else { - if (mongoc_change_stream_error_document (stream, &error, NULL)) { - MONGOC_ERROR ("%s\n", error.message); - } - - mongoc_change_stream_destroy (stream); - } - /* End Changestream Example 3 */ - - bson_destroy (pipeline); - - /* Start Changestream Example 4 */ - pipeline = BCON_NEW ("pipeline", - "[", - "{", - "$match", - "{", - "fullDocument.username", - BCON_UTF8 ("alice"), - "}", - "}", - "{", - "$addFields", - "{", - "newField", - BCON_UTF8 ("this is an added field!"), - "}", - "}", - "]"); - - stream = mongoc_collection_watch (collection, pipeline, &opts); - mongoc_change_stream_next (stream, &change); - if (mongoc_change_stream_error_document (stream, &error, NULL)) { - MONGOC_ERROR ("%s\n", error.message); - } - - mongoc_change_stream_destroy (stream); - /* End Changestream Example 4 */ - - bson_destroy (&opts); - bson_destroy (pipeline); - mongoc_collection_destroy (collection); -} - - -static void -test_sample_causal_consistency (mongoc_client_t *client) -{ - mongoc_session_opt_t *session_opts = NULL; - mongoc_client_session_t *session1 = NULL; - mongoc_client_session_t *session2 = NULL; - mongoc_read_prefs_t *read_prefs = NULL; - const bson_t *cluster_time = NULL; - mongoc_write_concern_t *wc = NULL; - mongoc_read_concern_t *rc = NULL; - mongoc_collection_t *coll = NULL; - mongoc_cursor_t *cursor = NULL; - const bson_t *result = NULL; - bson_t *update_opts = NULL; - bson_t *insert_opts = NULL; - bson_t *find_query = NULL; - bson_t *find_opts = NULL; - bson_t *insert = NULL; - bson_t *update = NULL; - bson_t *query = NULL; - bson_t *doc = NULL; - char *json = NULL; - uint32_t timestamp; - uint32_t increment; - bson_error_t error; - bool res; - - if (!test_framework_skip_if_no_txns ()) { - return; - } - - /* Seed the 'db.items' collection with a document. */ - coll = mongoc_client_get_collection (client, "db", "items"); - mongoc_collection_drop (coll, &error); - - doc = BCON_NEW ("sku", "111", "name", "Peanuts", - "start", BCON_DATE_TIME (bson_get_monotonic_time ())); - - res = mongoc_collection_insert_one (coll, doc, NULL, NULL, &error); - if (!res) { - fprintf (stderr, "insert failed: %s\n", error.message); - goto cleanup; - } - - /* Start Causal Consistency Example 1 */ - - /* Use a causally-consistent session to run some operations. */ - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_wmajority (wc, 1000); - mongoc_collection_set_write_concern (coll, wc); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_collection_set_read_concern (coll, rc); - - session_opts = mongoc_session_opts_new (); - mongoc_session_opts_set_causal_consistency (session_opts, true); - - session1 = mongoc_client_start_session (client, session_opts, &error); - if (!session1) { - fprintf (stderr, "couldn't start session: %s\n", error.message); - goto cleanup; - } - - /* Run an update_one with our causally-consistent session. */ - update_opts = bson_new (); - res = mongoc_client_session_append (session1, update_opts, &error); - if (!res) { - fprintf (stderr, "couldn't add session to opts: %s\n", error.message); - goto cleanup; - } - - query = BCON_NEW ("sku", "111"); - update = BCON_NEW ("$set", "{", "end", - BCON_DATE_TIME (bson_get_monotonic_time ()), "}"); - res = mongoc_collection_update_one (coll, - query, - update, - update_opts, - NULL, /* reply */ - &error); - - if (!res) { - fprintf (stderr, "update failed: %s\n", error.message); - goto cleanup; - } - - /* Run an insert with our causally-consistent session */ - insert_opts = bson_new (); - res = mongoc_client_session_append (session1, insert_opts, &error); - if (!res) { - fprintf (stderr, "couldn't add session to opts: %s\n", error.message); - goto cleanup; - } - - insert = BCON_NEW ("sku", "nuts-111", "name", "Pecans", - "start", BCON_DATE_TIME (bson_get_monotonic_time ())); - res = mongoc_collection_insert_one (coll, insert, insert_opts, NULL, &error); - if (!res) { - fprintf (stderr, "insert failed: %s\n", error.message); - goto cleanup; - } - - /* End Causal Consistency Example 1 */ - - /* Start Causal Consistency Example 2 */ - - /* Make a new session, session2, and make it causally-consistent - * with session1, so that session2 will read session1's writes. */ - session2 = mongoc_client_start_session (client, session_opts, &error); - if (!session2) { - fprintf (stderr, "couldn't start session: %s\n", error.message); - goto cleanup; - } - - /* Set the cluster time for session2 to session1's cluster time */ - cluster_time = mongoc_client_session_get_cluster_time (session1); - mongoc_client_session_advance_cluster_time (session2, cluster_time); - - /* Set the operation time for session2 to session2's operation time */ - mongoc_client_session_get_operation_time (session1, ×tamp, &increment); - mongoc_client_session_advance_operation_time (session2, - timestamp, - increment); - - /* Run a find on session2, which should now find all writes done - * inside of session1 */ - find_opts = bson_new (); - res = mongoc_client_session_append (session2, find_opts, &error); - if (!res) { - fprintf (stderr, "couldn't add session to opts: %s\n", error.message); - goto cleanup; - } - - find_query = BCON_NEW ("end", BCON_NULL); - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - cursor = mongoc_collection_find_with_opts (coll, - query, - find_opts, - read_prefs); - - while (mongoc_cursor_next (cursor, &result)) { - json = bson_as_json (result, NULL); - fprintf (stdout, "Document: %s\n", json); - bson_free (json); - } - - if (mongoc_cursor_error (cursor, &error)) { - fprintf (stderr, "cursor failure: %s\n", error.message); - goto cleanup; - } - - /* End Causal Consistency Example 2 */ - - cleanup: - - bson_destroy (doc); - bson_destroy (query); - bson_destroy (insert); - bson_destroy (update); - bson_destroy (find_query); - bson_destroy (update_opts); - bson_destroy (find_opts); - bson_destroy (insert_opts); - - mongoc_read_concern_destroy (rc); - mongoc_read_prefs_destroy (read_prefs); - mongoc_write_concern_destroy (wc); - mongoc_collection_destroy (coll); - mongoc_cursor_destroy (cursor); - mongoc_session_opts_destroy (session_opts); - mongoc_client_session_destroy (session1); - mongoc_client_session_destroy (session2); -} - - -static void -test_sample_aggregation (mongoc_database_t *db) -{ - /* Start Aggregation Example 1 */ - mongoc_collection_t *collection; - bson_t *pipeline; - mongoc_cursor_t *cursor; - bson_error_t error; - const bson_t *doc; - - collection = mongoc_database_get_collection (db, "sales"); - - pipeline = BCON_NEW ("pipeline", "[", - "{", - "$match", "{", - "items.fruit", BCON_UTF8 ("banana"), - "}", - "}", - "{", - "$sort", "{", - "date", BCON_INT32 (1), - "}", - "}", - "]"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - bson_destroy (pipeline); - - while (mongoc_cursor_next (cursor, &doc)) { - /* Do something with each doc here */ - } - - if (mongoc_cursor_error (cursor, &error)) { - MONGOC_ERROR ("%s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - /* End Aggregation Example 1 */ - - /* Start Aggregation Example 2 */ - pipeline = BCON_NEW ("pipeline", "[", - "{", - "$unwind", BCON_UTF8 ("$items"), - "}", - "{", - "$match", "{", - "items.fruit", BCON_UTF8 ("banana"), - "}", - "}", - "{", - "$group", "{", - "_id", "{", - "day", "{", - "$dayOfWeek", BCON_UTF8 ("$date"), - "}", - "}", - "count", "{", - "$sum", BCON_UTF8 ("$items.quantity"), - "}", - "}", - "}", - "{", - "$project", "{", - "dayOfWeek", BCON_UTF8 ("$_id.day"), - "numberSold", BCON_UTF8 ("$count"), - "_id", BCON_INT32 (0), - "}", - "}", - "{", - "$sort", "{", - "numberSold", BCON_INT32 (1), - "}", - "}", - "]"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - bson_destroy (pipeline); - - while (mongoc_cursor_next (cursor, &doc)) { - /* Do something with each doc here */ - } - - if (mongoc_cursor_error (cursor, &error)) { - MONGOC_ERROR ("%s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - /* End Aggregation Example 2 */ - - /* Start Aggregation Example 3 */ - pipeline = BCON_NEW ("pipeline", "[", - "{", - "$unwind", BCON_UTF8 ("$items"), - "}", - "{", - "$group", "{", - "_id", "{", - "day", "{", - "$dayOfWeek", BCON_UTF8 ("$date"), - "}", - "}", - "items_sold", "{", - "$sum", BCON_UTF8 ("$items.quantity"), - "}", - "revenue", "{", - "$sum", "{", - "$multiply", "[", - BCON_UTF8 ("$items.quantity"), - BCON_UTF8 ("$items.price"), - "]", - "}", - "}", - "}", - "}", - "{", - "$project", "{", - "day", BCON_UTF8 ("$_id.day"), - "revenue", BCON_INT32 (1), - "items_sold", BCON_INT32 (1), - "discount", "{", - "$cond", "{", - "if", "{", - "$lte", "[", - "$revenue", - BCON_INT32 (250), - "]", - "}", - "then", BCON_INT32 (25), - "else", BCON_INT32 (0), - "}", - "}", - "}", - "}", - "]"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - bson_destroy (pipeline); - - while (mongoc_cursor_next (cursor, &doc)) { - /* Do something with each doc here */ - } - - if (mongoc_cursor_error (cursor, &error)) { - MONGOC_ERROR ("%s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - /* End Aggregation Example 3 */ - - mongoc_collection_destroy (collection); - - - /* Need MongoDB 3.6 to use unrelated subqueries */ - if(test_framework_skip_if_max_wire_version_less_than_6 ()){ - - /* Start Aggregation Example 4 */ - collection = mongoc_database_get_collection (db, "air_alliances"); - pipeline = BCON_NEW ("pipeline", "[", - "{", - "$lookup", "{", - "from", BCON_UTF8 ("air_airlines"), - "let", "{", - "constituents", BCON_UTF8 ("$airlines"), - "}", - "pipeline", "[", - "{", - "$match", "{", - "$expr", "{", - "$in", "[", - "$name", - BCON_UTF8 ("$$constituents"), - "]", - "}", - "}", - "}", - "]", - "as", BCON_UTF8 ("airlines"), - "}", - "}", - "{", - "$project", "{", - "_id", BCON_INT32 (0), - "name", BCON_INT32 (1), - "airlines", "{", - "$filter", "{", - "input", BCON_UTF8 ("$airlines"), - "as", BCON_UTF8 ("airline"), - "cond", "{", - "$eq", "[", - BCON_UTF8 ("$$airline.country"), - BCON_UTF8 ("Canada"), - "]", - "}", - "}", - "}", - "}", - "}", - "]"); - - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL); - bson_destroy (pipeline); - - while (mongoc_cursor_next (cursor, &doc)) { - /* Do something with each doc here */ - } - - if (mongoc_cursor_error (cursor, &error)) { - MONGOC_ERROR ("%s\n", error.message); - } - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - /* End Aggregation Example 4 */ - - } - - ASSERT_NO_CAPTURED_LOGS ("sample aggregation examples"); -} - -static void -test_sample_run_command (mongoc_database_t *db) -{ - /* Start runCommand Example 1 */ - bson_t *run_command; - bson_t reply; - bson_error_t error; - bool r; - - run_command = BCON_NEW ("buildInfo", BCON_INT32 (1)); - - r = mongoc_database_write_command_with_opts ( - db, run_command, NULL /* opts */, &reply, &error); - bson_destroy (run_command); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - - /* Do something with reply here */ - - bson_destroy (&reply); - /* End runCommand Example 1 */ - - /* Start runCommand Example 2 */ - run_command = BCON_NEW ("collStats", BCON_UTF8 ("restaurants")); - - r = mongoc_database_write_command_with_opts ( - db, run_command, NULL /* opts */, &reply, &error); - bson_destroy (run_command); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - - /* Do something with reply here */ - - bson_destroy (&reply); - /* End runCommand Example 2 */ - - ASSERT_NO_CAPTURED_LOGS ("sample runCommand examples"); -} - -static void -test_sample_indexes (mongoc_database_t *db) -{ - /* Start Index Example 1 */ - const char *collection_name = "records"; - char *index_name; - bson_t *create_indexes; - bson_t reply; - bson_t keys; - bson_error_t error; - bool r; - - bson_init (&keys); - BSON_APPEND_INT32 (&keys, "score", 1); - index_name = mongoc_collection_keys_to_index_string (&keys); - - create_indexes = BCON_NEW ("createIndexes", BCON_UTF8 (collection_name), - "indexes", "[", - "{", - "key", BCON_DOCUMENT (&keys), - "name", BCON_UTF8 (index_name), - "}", - "]"); - - r = mongoc_database_write_command_with_opts ( - db, create_indexes, NULL /* opts */, &reply, &error); - bson_destroy (create_indexes); - bson_free(index_name); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - - /* Do something with reply here */ - - bson_destroy (&reply); - bson_destroy (&keys); - /* End Index Example 1 */ - - /* Start Index Example 2 */ - collection_name = "restaurants"; - - bson_init (&keys); - BSON_APPEND_INT32 (&keys, "cuisine", 1); - BSON_APPEND_INT32 (&keys, "name", 1); - index_name = mongoc_collection_keys_to_index_string (&keys); - create_indexes = BCON_NEW ("createIndexes", BCON_UTF8 (collection_name), - "indexes", "[", - "{", - "key", BCON_DOCUMENT (&keys), - "partialFilterExpression", "{", - "rating", "{", - "$gt", BCON_INT32 (5), - "}", - "}", - "name", BCON_UTF8 (index_name), - "}", - "]"); - - r = mongoc_database_write_command_with_opts ( - db, create_indexes, NULL /* opts */, &reply, &error); - bson_destroy (create_indexes); - bson_free(index_name); - - if (!r) { - MONGOC_ERROR ("%s\n", error.message); - } - - /* Do something with reply here */ - - bson_destroy (&reply); - bson_destroy (&keys); - /* End Index Example 2 */ - - ASSERT_NO_CAPTURED_LOGS ("sample index examples"); -} - - -/* convenience function for testing the outcome of example code */ -static void -find_and_match (mongoc_collection_t *collection, - const char *filter, - const char *pattern) -{ - mongoc_cursor_t *cursor; - const bson_t *doc; - bson_error_t error; - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson (filter), NULL, NULL); - - if (!mongoc_cursor_next (cursor, &doc)) { - if (mongoc_cursor_error (cursor, &error)) { - ASSERT_OR_PRINT (false, error); - } - - test_error ( - "No document in %s matching %s", collection->collection, filter); - } - - ASSERT_MATCH (doc, pattern); - mongoc_cursor_destroy (cursor); -} - - -/* setup, preliminary to transactions example code */ -static void -insert_employee (mongoc_client_t *client, int employee) -{ - mongoc_collection_t *employees; - mongoc_collection_t *events; - bson_error_t error; - bool r; - - employees = mongoc_client_get_collection (client, "hr", "employees"); - mongoc_collection_drop (employees, NULL); - - r = mongoc_collection_insert_one ( - employees, - tmp_bson ("{'employee': %d, 'status': 'Active'}", employee), - NULL, - NULL, - &error); - ASSERT_OR_PRINT (r, error); - - events = mongoc_client_get_collection (client, "reporting", "events"); - - mongoc_collection_drop (events, NULL); - - r = mongoc_collection_insert_one ( - events, - tmp_bson ("{'employee': %d, 'status': {'new': 'Active', 'old': null}}", - employee), - NULL, - NULL, - &error); - ASSERT_OR_PRINT (r, error); - - mongoc_collection_destroy (employees); - mongoc_collection_destroy (events); -} - - -/* clang-format on */ -/* Start Transactions Retry Example 3 */ -/* takes a session, an out-param for server reply, and out-param for error. */ -typedef bool (*txn_func_t) (mongoc_client_session_t *, - bson_t *, - bson_error_t *); - - -/* runs transactions with retry logic */ -bool -run_transaction_with_retry (txn_func_t txn_func, - mongoc_client_session_t *cs, - bson_error_t *error) -{ - bson_t reply; - bool r; - - while (true) { - /* perform transaction */ - r = txn_func (cs, &reply, error); - if (r) { - /* success */ - bson_destroy (&reply); - return true; - } - - MONGOC_WARNING ("Transaction aborted: %s", error->message); - if (mongoc_error_has_label (&reply, "TransientTransactionError")) { - /* on transient error, retry the whole transaction */ - MONGOC_WARNING ("TransientTransactionError, retrying transaction..."); - bson_destroy (&reply); - } else { - /* non-transient error */ - break; - } - } - - bson_destroy (&reply); - return false; -} - - -/* commit transactions with retry logic */ -bool -commit_with_retry (mongoc_client_session_t *cs, bson_error_t *error) -{ - bson_t reply; - bool r; - - while (true) { - /* commit uses write concern set at transaction start, see - * mongoc_transaction_opts_set_write_concern */ - r = mongoc_client_session_commit_transaction (cs, &reply, error); - if (r) { - MONGOC_INFO ("Transaction committed"); - break; - } - - if (mongoc_error_has_label (&reply, "UnknownTransactionCommitResult")) { - MONGOC_WARNING ("UnknownTransactionCommitResult, retrying commit ..."); - bson_destroy (&reply); - } else { - /* commit failed, cannot retry */ - break; - } - } - - bson_destroy (&reply); - - return r; -} - - -/* updates two collections in a transaction and calls commit_with_retry */ -bool -update_employee_info (mongoc_client_session_t *cs, - bson_t *reply, - bson_error_t *error) -{ - mongoc_client_t *client; - mongoc_collection_t *employees; - mongoc_collection_t *events; - mongoc_read_concern_t *rc; - mongoc_write_concern_t *wc; - mongoc_transaction_opt_t *txn_opts; - bson_t opts = BSON_INITIALIZER; - bson_t *filter = NULL; - bson_t *update = NULL; - bson_t *event = NULL; - bool r; - - bson_init (reply); - - client = mongoc_client_session_get_client (cs); - employees = mongoc_client_get_collection (client, "hr", "employees"); - events = mongoc_client_get_collection (client, "reporting", "events"); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_SNAPSHOT); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_MAJORITY); - txn_opts = mongoc_transaction_opts_new (); - mongoc_transaction_opts_set_read_concern (txn_opts, rc); - mongoc_transaction_opts_set_write_concern (txn_opts, wc); - - r = mongoc_client_session_start_transaction (cs, txn_opts, error); - if (!r) { - goto done; - } - - r = mongoc_client_session_append (cs, &opts, error); - if (!r) { - goto done; - } - - filter = BCON_NEW ("employee", BCON_INT32 (3)); - update = BCON_NEW ("$set", "{", "status", "Inactive", "}"); - /* mongoc_collection_update_one will reinitialize reply */ - bson_destroy (reply); - r = mongoc_collection_update_one ( - employees, filter, update, &opts, reply, error); - - if (!r) { - goto abort; - } - - event = BCON_NEW ("employee", BCON_INT32 (3)); - BCON_APPEND (event, "status", "{", "new", "Inactive", "old", "Active", "}"); - - bson_destroy (reply); - r = mongoc_collection_insert_one (events, event, &opts, reply, error); - if (!r) { - goto abort; - } - - r = commit_with_retry (cs, error); - -abort: - if (!r) { - MONGOC_ERROR ("Aborting due to error in transaction: %s", error->message); - mongoc_client_session_abort_transaction (cs, NULL); - } - -done: - mongoc_collection_destroy (employees); - mongoc_collection_destroy (events); - mongoc_read_concern_destroy (rc); - mongoc_write_concern_destroy (wc); - mongoc_transaction_opts_destroy (txn_opts); - bson_destroy (&opts); - bson_destroy (filter); - bson_destroy (update); - bson_destroy (event); - - return r; -} - - -void -example_func (mongoc_client_t *client) -{ - mongoc_client_session_t *cs; - bson_error_t error; - bool r; - - cs = mongoc_client_start_session (client, NULL, &error); - if (!cs) { - MONGOC_ERROR ("Could not start session: %s", error.message); - return; - } - - r = run_transaction_with_retry (update_employee_info, cs, &error); - if (!r) { - MONGOC_ERROR ("Could not update employee, permanent error: %s", - error.message); - } - - mongoc_client_session_destroy (cs); -} -/* End Transactions Retry Example 3 */ -/* clang-format off */ - -static void -test_sample_txn_commands (mongoc_client_t *client) -{ - mongoc_collection_t *employees; - mongoc_collection_t *events; - - if (!test_framework_skip_if_no_txns ()) { - return; - } - - /* preliminary: create collections outside txn */ - insert_employee (client, 3); - employees = mongoc_client_get_collection (client, "hr", "employees"); - events = mongoc_client_get_collection (client, "reporting", "events"); - - capture_logs (true); - - /* test transactions retry example 3 */ - example_func (client); - ASSERT_NO_CAPTURED_LOGS ("transactions retry example 3"); - find_and_match (employees, "{'employee': 3}", "{'status': 'Inactive'}"); - - mongoc_collection_destroy (employees); - mongoc_collection_destroy (events); -} - - -static void -test_sample_commands (void) -{ - mongoc_client_t *client; - mongoc_database_t *db; - mongoc_collection_t *collection; - - client = test_framework_client_new (); - db = mongoc_client_get_database (client, "test_sample_command"); - collection = mongoc_database_get_collection (db, "inventory"); - mongoc_collection_drop (collection, NULL); - - test_sample_command (test_example_1, 1, db, collection, false); - test_sample_command (test_example_2, 2, db, collection, false); - test_sample_command (test_example_3, 3, db, collection, true); - test_sample_command (test_example_6, 6, db, collection, false); - test_sample_command (test_example_7, 7, db, collection, false); - test_sample_command (test_example_9, 9, db, collection, false); - test_sample_command (test_example_10, 10, db, collection, false); - test_sample_command (test_example_11, 11, db, collection, false); - test_sample_command (test_example_12, 12, db, collection, false); - test_sample_command (test_example_13, 13, db, collection, true); - test_sample_command (test_example_14, 14, db, collection, false); - test_sample_command (test_example_15, 15, db, collection, false); - test_sample_command (test_example_16, 16, db, collection, false); - test_sample_command (test_example_17, 17, db, collection, false); - test_sample_command (test_example_18, 18, db, collection, false); - test_sample_command (test_example_19, 19, db, collection, true); - test_sample_command (test_example_20, 20, db, collection, false); - test_sample_command (test_example_21, 21, db, collection, false); - test_sample_command (test_example_22, 22, db, collection, false); - test_sample_command (test_example_23, 23, db, collection, false); - test_sample_command (test_example_24, 24, db, collection, false); - test_sample_command (test_example_25, 25, db, collection, false); - test_sample_command (test_example_26, 26, db, collection, false); - test_sample_command (test_example_27, 27, db, collection, false); - test_sample_command (test_example_28, 28, db, collection, true); - test_sample_command (test_example_29, 29, db, collection, false); - test_sample_command (test_example_30, 30, db, collection, false); - test_sample_command (test_example_31, 31, db, collection, false); - test_sample_command (test_example_32, 32, db, collection, false); - test_sample_command (test_example_33, 33, db, collection, false); - test_sample_command (test_example_34, 34, db, collection, false); - test_sample_command (test_example_35, 35, db, collection, false); - test_sample_command (test_example_36, 36, db, collection, false); - test_sample_command (test_example_37, 37, db, collection, true); - test_sample_command (test_example_38, 38, db, collection, false); - test_sample_command (test_example_39, 39, db, collection, false); - test_sample_command (test_example_40, 40, db, collection, false); - test_sample_command (test_example_41, 41, db, collection, true); - test_sample_command (test_example_42, 42, db, collection, false); - test_sample_command (test_example_43, 43, db, collection, false); - test_sample_command (test_example_44, 44, db, collection, false); - test_sample_command (test_example_45, 45, db, collection, false); - test_sample_command (test_example_46, 46, db, collection, false); - test_sample_command (test_example_47, 47, db, collection, false); - test_sample_command (test_example_48, 48, db, collection, false); - test_sample_command (test_example_49, 49, db, collection, false); - test_sample_command (test_example_50, 50, db, collection, true); - test_sample_command (test_example_51, 51, db, collection, false); - test_sample_command (test_example_52, 52, db, collection, false); - test_sample_command (test_example_53, 53, db, collection, false); - test_sample_command (test_example_54, 54, db, collection, true); - test_sample_command (test_example_55, 55, db, collection, false); - test_sample_command (test_example_57, 57, db, collection, false); - test_sample_command (test_example_58, 58, db, collection, false); - test_sample_command (test_example_56, 56, db, collection, true); - test_sample_change_stream_command (test_example_change_stream, db); - test_sample_causal_consistency (client); - test_sample_aggregation (db); - test_sample_indexes (db); - test_sample_run_command (db); - test_sample_txn_commands (client); - - mongoc_collection_drop (collection, NULL); - - mongoc_collection_destroy (collection); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - - -void -test_samples_install (TestSuite *suite) -{ - TestSuite_AddLive (suite, "/Samples", test_sample_commands); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-scram.c b/lib/mongoc/libmongoc/tests/test-mongoc-scram.c deleted file mode 100644 index 79d46599b8483647961b95ef5706d633426efd3c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-scram.c +++ /dev/null @@ -1,586 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mock_server/mock-server.h> -#include <mock_server/future.h> -#include <mock_server/future-functions.h> - -#include "mongoc/mongoc-crypto-private.h" -#include "mongoc/mongoc-scram-private.h" - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - -#ifdef MONGOC_ENABLE_SSL -static void -test_mongoc_scram_step_username_not_set (void) -{ - mongoc_scram_t scram; - bool success; - uint8_t buf[4096] = {0}; - uint32_t buflen = 0; - bson_error_t error; - - _mongoc_scram_init (&scram, MONGOC_CRYPTO_ALGORITHM_SHA_1); - _mongoc_scram_set_pass (&scram, "password"); - - success = _mongoc_scram_step ( - &scram, buf, buflen, buf, sizeof buf, &buflen, &error); - - ASSERT (!success); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: username is not set"); - - _mongoc_scram_destroy (&scram); -} - -typedef struct { - const char *original; - const char *normalized; - bool should_be_required; - bool should_succeed; -} sasl_prep_testcase_t; - - -/* test that an error is reported if the server responds with an iteration - * count that is less than 4096 */ -static void -test_iteration_count (int count, bool should_succeed) -{ - mongoc_scram_t scram; - uint8_t buf[4096] = {0}; - uint32_t buflen = 0; - bson_error_t error; - const char *client_nonce = "YWJjZA=="; - char *server_response; - bool success; - - server_response = bson_strdup_printf ( - "r=YWJjZA==YWJjZA==,s=r6+P1iLmSJvhrRyuFi6Wsg==,i=%d", count); - /* set up the scram state to immediately test step 2. */ - _mongoc_scram_init (&scram, MONGOC_CRYPTO_ALGORITHM_SHA_1); - _mongoc_scram_set_pass (&scram, "password"); - bson_strncpy (scram.encoded_nonce, client_nonce, sizeof (scram.encoded_nonce)); - scram.encoded_nonce_len = (int32_t) strlen (client_nonce); - scram.auth_message = bson_malloc0 (4096); - scram.auth_messagemax = 4096; - /* prepare the server's "response" from step 1 as the input for step 2. */ - memcpy (buf, server_response, strlen (server_response) + 1); - buflen = (int32_t) strlen (server_response); - scram.step = 1; - success = _mongoc_scram_step ( - &scram, buf, buflen, buf, sizeof buf, &buflen, &error); - if (should_succeed) { - ASSERT_OR_PRINT (success, error); - } else { - BSON_ASSERT (!success); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SCRAM, - MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, - "SCRAM Failure: iterations must be at least 4096"); - } - bson_free (server_response); - _mongoc_scram_destroy (&scram); -} - -static void -test_mongoc_scram_iteration_count (void) -{ - test_iteration_count (1000, false); - test_iteration_count (4095, false); - test_iteration_count (4096, true); - test_iteration_count (10000, true); -} - -static void -test_mongoc_scram_sasl_prep (void) -{ -#ifdef MONGOC_ENABLE_ICU - int i, ntests; - char *normalized; - bson_error_t err; - /* examples from RFC 4013 section 3. */ - sasl_prep_testcase_t tests[] = {{"\x65\xCC\x81", "\xC3\xA9", true, true}, - {"I\xC2\xADX", "IX", true, true}, - {"user", "user", false, true}, - {"USER", "USER", false, true}, - {"\xC2\xAA", "a", true, true}, - {"\xE2\x85\xA8", "IX", true, true}, - {"\x07", "(invalid)", true, false}, - {"\xD8\xA7\x31", "(invalid)", true, false}}; - ntests = sizeof (tests) / sizeof (sasl_prep_testcase_t); - for (i = 0; i < ntests; i++) { - ASSERT_CMPINT (tests[i].should_be_required, - ==, - _mongoc_sasl_prep_required (tests[i].original)); - memset (&err, 0, sizeof (err)); - normalized = _mongoc_sasl_prep ( - tests[i].original, strlen (tests[i].original), &err); - if (tests[i].should_succeed) { - ASSERT_CMPSTR (tests[i].normalized, normalized); - ASSERT_CMPINT (err.code, ==, 0); - bson_free (normalized); - } else { - ASSERT_CMPINT (err.code, ==, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR); - ASSERT_CMPINT (err.domain, ==, MONGOC_ERROR_SCRAM); - BSON_ASSERT (normalized == NULL); - } - } -#endif -} -#endif - -static void -_create_scram_users (void) -{ - mongoc_client_t *client; - bool res; - bson_error_t error; - client = test_framework_client_new (); - res = mongoc_client_command_simple ( - client, - "admin", - tmp_bson ("{'createUser': 'sha1', 'pwd': 'sha1', 'roles': ['root'], " - "'mechanisms': ['SCRAM-SHA-1']}"), - NULL /* read_prefs */, - NULL /* reply */, - &error); - ASSERT_OR_PRINT (res, error); - res = mongoc_client_command_simple ( - client, - "admin", - tmp_bson ("{'createUser': 'sha256', 'pwd': 'sha256', 'roles': ['root'], " - "'mechanisms': ['SCRAM-SHA-256']}"), - NULL /* read_prefs */, - NULL /* reply */, - &error); - ASSERT_OR_PRINT (res, error); - res = mongoc_client_command_simple ( - client, - "admin", - tmp_bson ("{'createUser': 'both', 'pwd': 'both', 'roles': ['root'], " - "'mechanisms': ['SCRAM-SHA-1', 'SCRAM-SHA-256']}"), - NULL /* read_prefs */, - NULL /* reply */, - &error); - ASSERT_OR_PRINT (res, error); - mongoc_client_destroy (client); -} - -static void -_drop_scram_users (void) -{ - mongoc_client_t *client; - mongoc_database_t *db; - bool res; - bson_error_t error; - client = test_framework_client_new (); - db = mongoc_client_get_database (client, "admin"); - res = mongoc_database_remove_user (db, "sha1", &error); - ASSERT_OR_PRINT (res, error); - res = mongoc_database_remove_user (db, "sha256", &error); - ASSERT_OR_PRINT (res, error); - res = mongoc_database_remove_user (db, "both", &error); - ASSERT_OR_PRINT (res, error); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -static void -_check_mechanism (bool pooled, - const char *client_mech, - const char *server_mechs, - const char *expected_used_mech) -{ - mock_server_t *server; - mongoc_client_pool_t *client_pool = NULL; - mongoc_client_t *client = NULL; - mongoc_uri_t *uri; - future_t *future; - request_t *request; - const bson_t *sasl_doc; - const char *used_mech; - - server = mock_server_new (); - mock_server_auto_ismaster (server, - "{'ok': 1, 'minWireVersion': 3, " - "'maxWireVersion': %d, 'ismaster': true, " - "'saslSupportedMechs': [%s]}", - WIRE_VERSION_MAX, - server_mechs ? server_mechs : ""); - - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_username (uri, "user"); - mongoc_uri_set_password (uri, "password"); - if (client_mech) { - mongoc_uri_set_auth_mechanism (uri, client_mech); - } - - if (pooled) { - client_pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (client_pool); - /* suppress the auth failure logs from pooled clients. */ - capture_logs (true); - } else { - client = mongoc_client_new_from_uri (uri); - } - future = future_client_command_simple (client, - "admin", - tmp_bson ("{'dbstats': 1}"), - NULL /* read_prefs. */, - NULL /* reply. */, - NULL /* error. */); - request = - mock_server_receives_msg (server, MONGOC_QUERY_NONE, tmp_bson ("{}")); - sasl_doc = request_get_doc (request, 0); - used_mech = bson_lookup_utf8 (sasl_doc, "mechanism"); - ASSERT_CMPSTR (used_mech, expected_used_mech); - /* we're not actually going to auth, just hang up. */ - mock_server_hangs_up (request); - future_wait (future); - future_destroy (future); - request_destroy (request); - mongoc_uri_destroy (uri); - if (pooled) { - mongoc_client_pool_push (client_pool, client); - mongoc_client_pool_destroy (client_pool); - capture_logs (false); - } else { - mongoc_client_destroy (client); - } - mock_server_destroy (server); -} - -typedef enum { - MONGOC_TEST_NO_ERROR, - MONGOC_TEST_USER_NOT_FOUND_ERROR, - MONGOC_TEST_AUTH_ERROR, - MONGOC_TEST_NO_ICU_ERROR -} test_error_t; - -void -_check_error (const bson_error_t *error, test_error_t expected_error) -{ - int32_t domain = 0; - int32_t code = 0; - const char *message = ""; - - switch (expected_error) { - case MONGOC_TEST_AUTH_ERROR: - domain = MONGOC_ERROR_CLIENT; - code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - message = "Authentication failed"; - break; - case MONGOC_TEST_USER_NOT_FOUND_ERROR: - domain = MONGOC_ERROR_CLIENT; - code = MONGOC_ERROR_CLIENT_AUTHENTICATE; - message = "Could not find user"; - break; - case MONGOC_TEST_NO_ICU_ERROR: - domain = MONGOC_ERROR_SCRAM; - code = MONGOC_ERROR_SCRAM_PROTOCOL_ERROR; - message = "SCRAM Failure: ICU required to SASLPrep password"; - break; - case MONGOC_TEST_NO_ERROR: - default: - return; - } - - ASSERT_ERROR_CONTAINS ((*error), domain, code, message); -} - -/* if auth is expected to succeed, expected_error is zero'd out. */ -static void -_try_auth (bool pooled, - const char *user, - const char *pwd, - const char *mechanism, - test_error_t expected_error) -{ - mongoc_uri_t *uri; - mongoc_client_pool_t *client_pool = NULL; - mongoc_client_t *client = NULL; - bson_error_t error; - bson_t reply; - bool res; - - uri = test_framework_get_uri (); - mongoc_uri_set_username (uri, user); - mongoc_uri_set_password (uri, pwd); - if (mechanism) { - mongoc_uri_set_auth_mechanism (uri, mechanism); - } - if (pooled) { - client_pool = mongoc_client_pool_new (uri); - mongoc_client_pool_set_error_api (client_pool, 2); - client = mongoc_client_pool_pop (client_pool); - /* suppress the auth failure logs from pooled clients. */ - capture_logs (true); - } else { - client = mongoc_client_new_from_uri (uri); - mongoc_client_set_error_api (client, 2); - } - res = mongoc_client_command_simple (client, - "admin", - tmp_bson ("{'dbstats': 1}"), - NULL /* read_prefs. */, - &reply, - &error); - - if (expected_error == MONGOC_TEST_NO_ERROR) { - ASSERT (res); - ASSERT_MATCH (&reply, "{'db': 'admin', 'ok': 1}"); - } else { - ASSERT (!res); - _check_error (&error, expected_error); - } - bson_destroy (&reply); - mongoc_uri_destroy (uri); - if (pooled) { - mongoc_client_pool_push (client_pool, client); - mongoc_client_pool_destroy (client_pool); - capture_logs (false); - } else { - mongoc_client_destroy (client); - } -} - - -static void -_test_mongoc_scram_auth (bool pooled) -{ - /* Auth spec: "For each test user, verify that you can connect and run a - command requiring authentication for the following cases: - - Explicitly specifying each mechanism the user supports. - - Specifying no mechanism and relying on mechanism negotiation." */ - _try_auth (pooled, "sha1", "sha1", NULL, MONGOC_TEST_NO_ERROR); - _try_auth (pooled, "sha1", "sha1", "SCRAM-SHA-1", MONGOC_TEST_NO_ERROR); - _try_auth (pooled, "sha256", "sha256", NULL, MONGOC_TEST_NO_ERROR); - _try_auth ( - pooled, "sha256", "sha256", "SCRAM-SHA-256", MONGOC_TEST_NO_ERROR); - _try_auth (pooled, "both", "both", NULL, MONGOC_TEST_NO_ERROR); - _try_auth (pooled, "both", "both", "SCRAM-SHA-1", MONGOC_TEST_NO_ERROR); - _try_auth (pooled, "both", "both", "SCRAM-SHA-256", MONGOC_TEST_NO_ERROR); - - _check_mechanism (pooled, NULL, NULL, "SCRAM-SHA-1"); - _check_mechanism (pooled, NULL, "'SCRAM-SHA-1'", "SCRAM-SHA-1"); - _check_mechanism (pooled, NULL, "'SCRAM-SHA-256'", "SCRAM-SHA-256"); - _check_mechanism ( - pooled, NULL, "'SCRAM-SHA-1','SCRAM-SHA-256'", "SCRAM-SHA-256"); - - _check_mechanism (pooled, "SCRAM-SHA-1", NULL, "SCRAM-SHA-1"); - _check_mechanism (pooled, "SCRAM-SHA-1", "'SCRAM-SHA-1'", "SCRAM-SHA-1"); - _check_mechanism (pooled, "SCRAM-SHA-1", "'SCRAM-SHA-256'", "SCRAM-SHA-1"); - _check_mechanism ( - pooled, "SCRAM-SHA-1", "'SCRAM-SHA-1','SCRAM-SHA-256'", "SCRAM-SHA-1"); - - _check_mechanism (pooled, "SCRAM-SHA-256", NULL, "SCRAM-SHA-256"); - _check_mechanism (pooled, "SCRAM-SHA-256", "'SCRAM-SHA-1'", "SCRAM-SHA-256"); - _check_mechanism ( - pooled, "SCRAM-SHA-256", "'SCRAM-SHA-256'", "SCRAM-SHA-256"); - _check_mechanism (pooled, - "SCRAM-SHA-256", - "'SCRAM-SHA-1','SCRAM-SHA-256'", - "SCRAM-SHA-256"); - - /* Test some failure auths. */ - _try_auth (pooled, "sha1", "bad", NULL, MONGOC_TEST_AUTH_ERROR); - _try_auth (pooled, "sha256", "bad", NULL, MONGOC_TEST_AUTH_ERROR); - _try_auth (pooled, "both", "bad", NULL, MONGOC_TEST_AUTH_ERROR); - _try_auth (pooled, "sha1", "bad", "SCRAM-SHA-256", MONGOC_TEST_AUTH_ERROR); - _try_auth (pooled, "sha256", "bad", "SCRAM-SHA-1", MONGOC_TEST_AUTH_ERROR); - - /* Auth spec: "For a non-existent username, verify that not specifying a - * mechanism when connecting fails with the same error type that would occur - * with a correct username but incorrect password or mechanism." */ - _try_auth ( - pooled, "unknown_user", "bad", NULL, MONGOC_TEST_USER_NOT_FOUND_ERROR); -} - -/* test the auth tests described in the auth spec. */ -static void -test_mongoc_scram_auth (void *ctx) -{ - /* Auth spec: "Create three test users, one with only SHA-1, one with only - * SHA-256 and one with both" */ - _create_scram_users (); - _test_mongoc_scram_auth (false); - _test_mongoc_scram_auth (true); - _drop_scram_users (); -} - -static int -_skip_if_no_sha256 () -{ - mongoc_uri_t *uri; - mongoc_client_t *client; - bool res; - - uri = test_framework_get_uri (); - mongoc_uri_set_auth_mechanism (uri, "SCRAM-SHA-256"); - client = mongoc_client_new_from_uri (uri); - res = mongoc_client_command_simple (client, - "admin", - tmp_bson ("{'dbstats': 1}"), - NULL /* read_prefs */, - NULL /* reply */, - NULL /* error */); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); - return res ? 1 : 0; -} - -#define ROMAN_NUMERAL_NINE "\xE2\x85\xA8" -#define ROMAN_NUMERAL_FOUR "\xE2\x85\xA3" - -static int -skip_if_no_icu (void) -{ -#ifdef MONGOC_ENABLE_ICU - return true; -#else - return false; -#endif -} - -static int -skip_if_icu (void) -{ - return !skip_if_no_icu (); -} - -static void -_create_saslprep_users () -{ - mongoc_client_t *client; - bool res; - bson_error_t error; - client = test_framework_client_new (); - res = mongoc_client_command_simple ( - client, - "admin", - tmp_bson ("{'createUser': 'IX', 'pwd': 'IX', 'roles': ['root'], " - "'mechanisms': ['SCRAM-SHA-256']}"), - NULL /* read_prefs */, - NULL /* reply */, - &error); - ASSERT_OR_PRINT (res, error); - res = mongoc_client_command_simple ( - client, - "admin", - tmp_bson ("{'createUser': '" ROMAN_NUMERAL_NINE - "', 'pwd': '" ROMAN_NUMERAL_FOUR - "', 'roles': ['root'], 'mechanisms': ['SCRAM-SHA-256']}"), - NULL /* read_prefs */, - NULL /* reply */, - &error); - ASSERT_OR_PRINT (res, error); - mongoc_client_destroy (client); -} - -static void -_drop_saslprep_users () -{ - mongoc_client_t *client; - mongoc_database_t *db; - bool res; - bson_error_t error; - client = test_framework_client_new (); - db = mongoc_client_get_database (client, "admin"); - res = mongoc_database_remove_user (db, "IX", &error); - ASSERT_OR_PRINT (res, error); - res = mongoc_database_remove_user (db, ROMAN_NUMERAL_NINE, &error); - ASSERT_OR_PRINT (res, error); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - -static void -_test_mongoc_scram_saslprep_auth (bool pooled) -{ - _try_auth (pooled, "IX", "IX", NULL, MONGOC_TEST_NO_ERROR); - _try_auth (pooled, "IX", ROMAN_NUMERAL_NINE, NULL, MONGOC_TEST_NO_ERROR); - _try_auth (pooled, ROMAN_NUMERAL_NINE, "IV", NULL, MONGOC_TEST_NO_ERROR); - _try_auth (pooled, - ROMAN_NUMERAL_NINE, - ROMAN_NUMERAL_FOUR, - NULL, - MONGOC_TEST_NO_ERROR); -} - - -static void -test_mongoc_saslprep_auth (void *ctx) -{ - _create_saslprep_users (); - _test_mongoc_scram_saslprep_auth (false); - _test_mongoc_scram_saslprep_auth (true); - _drop_saslprep_users (); -} - - -static void -_test_mongoc_scram_saslprep_auth_no_icu (bool pooled) -{ - _try_auth (pooled, "IX", "IX", NULL, MONGOC_TEST_NO_ERROR); - _try_auth (pooled, "IX", ROMAN_NUMERAL_NINE, NULL, MONGOC_TEST_NO_ICU_ERROR); - _try_auth (pooled, ROMAN_NUMERAL_NINE, "IV", NULL, MONGOC_TEST_NO_ERROR); - _try_auth (pooled, - ROMAN_NUMERAL_NINE, - ROMAN_NUMERAL_FOUR, - NULL, - MONGOC_TEST_NO_ICU_ERROR); -} - -static void -test_mongoc_saslprep_auth_no_icu (void *ctx) -{ - _create_saslprep_users (); - _test_mongoc_scram_saslprep_auth_no_icu (false); - _test_mongoc_scram_saslprep_auth_no_icu (true); - _drop_saslprep_users (); -} - -void -test_scram_install (TestSuite *suite) -{ -#ifdef MONGOC_ENABLE_SSL - TestSuite_Add (suite, - "/scram/username_not_set", - test_mongoc_scram_step_username_not_set); - TestSuite_Add (suite, "/scram/sasl_prep", test_mongoc_scram_sasl_prep); - TestSuite_Add ( - suite, "/scram/iteration_count", test_mongoc_scram_iteration_count); -#endif - TestSuite_AddFull (suite, - "/scram/auth_tests", - test_mongoc_scram_auth, - NULL /* dtor */, - NULL /* ctx */, - test_framework_skip_if_no_auth, - test_framework_skip_if_max_wire_version_less_than_6, - _skip_if_no_sha256, - TestSuite_CheckLive); - TestSuite_AddFull (suite, - "/scram/saslprep_auth", - test_mongoc_saslprep_auth, - NULL /* dtor */, - NULL /* ctx */, - test_framework_skip_if_no_auth, - test_framework_skip_if_max_wire_version_less_than_6, - _skip_if_no_sha256, - skip_if_no_icu, - TestSuite_CheckLive); - TestSuite_AddFull (suite, - "/scram/saslprep_auth_no_icu", - test_mongoc_saslprep_auth_no_icu, - NULL /* dtor */, - NULL /* ctx */, - test_framework_skip_if_no_auth, - test_framework_skip_if_max_wire_version_less_than_6, - _skip_if_no_sha256, - skip_if_icu, - TestSuite_CheckLive); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-sdam-monitoring.c b/lib/mongoc/libmongoc/tests/test-mongoc-sdam-monitoring.c deleted file mode 100644 index c210707a4887ec462d2fdd930640d2a4faca99d1..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-sdam-monitoring.c +++ /dev/null @@ -1,911 +0,0 @@ -#include <mongoc/mongoc.h> -#include "json-test.h" - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-topology-description-apm-private.h" - -#include "test-libmongoc.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "json-test-monitoring.h" - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - - -typedef struct { - bson_t events; - uint32_t n_events; - mongoc_array_t heartbeat_succeeded_durations; - mongoc_array_t heartbeat_failed_durations; - bson_oid_t topology_id; -} context_t; - -static void -check_json_sdam_events (const bson_t *events, const bson_t *expectations) -{ - uint32_t expected_keys; - uint32_t actual_keys; - match_ctx_t match_ctx = {{0}}; - - expected_keys = bson_count_keys (expectations); - actual_keys = bson_count_keys (events); - - if (expected_keys != actual_keys) { - test_error ("SDAM test failed expectations:\n\n" - "%s\n\n" - "events:\n%s\n\n" - "expected %" PRIu32 " events, got %" PRIu32, - bson_as_canonical_extended_json (expectations, NULL), - bson_as_canonical_extended_json (events, NULL), - expected_keys, - actual_keys); - } - - if (!match_bson_with_ctx (events, expectations, &match_ctx)) { - test_error ("SDAM test failed expectations:\n\n" - "%s\n\n" - "events:\n%s\n\n%s", - bson_as_canonical_extended_json (expectations, NULL), - bson_as_canonical_extended_json (events, NULL), - match_ctx.errmsg); - } -} - - -static void -context_init (context_t *context) -{ - bson_init (&context->events); - context->n_events = 0; - _mongoc_array_init (&context->heartbeat_succeeded_durations, - sizeof (int64_t)); - _mongoc_array_init (&context->heartbeat_failed_durations, sizeof (int64_t)); - bson_oid_init_from_string (&context->topology_id, - "000000000000000000000000"); -} - -static void -context_append (context_t *context, bson_t *event) -{ - char str[16]; - const char *key; - - bson_uint32_to_string (context->n_events, &key, str, sizeof str); - BSON_APPEND_DOCUMENT (&context->events, key, event); - - context->n_events++; - - bson_destroy (event); -} - -static void -context_destroy (context_t *context) -{ - bson_destroy (&context->events); - _mongoc_array_destroy (&context->heartbeat_succeeded_durations); - _mongoc_array_destroy (&context->heartbeat_failed_durations); -} - -static void -append_array (bson_t *bson, const char *key, const bson_t *array) -{ - if (array->len) { - BSON_APPEND_ARRAY (bson, key, array); - } else { - bson_t tmp = BSON_INITIALIZER; - BSON_APPEND_ARRAY (bson, key, &tmp); - bson_destroy (&tmp); - } -} - -static void -sd_to_bson (const mongoc_server_description_t *sd, bson_t *bson) -{ - const mongoc_host_list_t *host_list; - - host_list = mongoc_server_description_host (sd); - - bson_init (bson); - BSON_APPEND_UTF8 (bson, "address", host_list->host_and_port); - - append_array (bson, "arbiters", &sd->arbiters); - append_array (bson, "hosts", &sd->hosts); - append_array (bson, "passives", &sd->passives); - - if (sd->current_primary) { - BSON_APPEND_UTF8 (bson, "primary", sd->current_primary); - } - - if (sd->set_name) { - BSON_APPEND_UTF8 (bson, "setName", sd->set_name); - } - - BSON_APPEND_UTF8 (bson, "type", mongoc_server_description_type (sd)); -} - -static void -td_to_bson (const mongoc_topology_description_t *td, bson_t *bson) -{ - size_t i; - bson_t servers = BSON_INITIALIZER; - bson_t server; - char str[16]; - const char *key; - - for (i = 0; i < td->servers->items_len; i++) { - bson_uint32_to_string ((uint32_t) i, &key, str, sizeof str); - sd_to_bson (mongoc_set_get_item (td->servers, (int) i), &server); - BSON_APPEND_DOCUMENT (&servers, key, &server); - bson_destroy (&server); - } - - bson_init (bson); - BSON_APPEND_UTF8 ( - bson, "topologyType", mongoc_topology_description_type (td)); - - if (td->set_name) { - BSON_APPEND_UTF8 (bson, "setName", td->set_name); - } - - BSON_APPEND_ARRAY (bson, "servers", &servers); - - bson_destroy (&servers); -} - -static void -server_changed (const mongoc_apm_server_changed_t *event) -{ - context_t *ctx; - bson_oid_t topology_id; - const char *host_and_port; - bson_t prev_sd; - bson_t new_sd; - - ctx = (context_t *) mongoc_apm_server_changed_get_context (event); - - /* check topology id is consistent */ - mongoc_apm_server_changed_get_topology_id (event, &topology_id); - ASSERT (bson_oid_equal (&topology_id, &ctx->topology_id)); - - host_and_port = mongoc_apm_server_changed_get_host (event)->host_and_port; - sd_to_bson (mongoc_apm_server_changed_get_previous_description (event), - &prev_sd); - sd_to_bson (mongoc_apm_server_changed_get_new_description (event), &new_sd); - - context_append (ctx, - BCON_NEW ("server_description_changed_event", - "{", - "topologyId", - BCON_UTF8 ("42"), - "address", - BCON_UTF8 (host_and_port), - "previousDescription", - BCON_DOCUMENT (&prev_sd), - "newDescription", - BCON_DOCUMENT (&new_sd), - "}")); - - bson_destroy (&prev_sd); - bson_destroy (&new_sd); -} - -static void -server_opening (const mongoc_apm_server_opening_t *event) -{ - context_t *ctx; - bson_oid_t topology_id; - const char *host_and_port; - - ctx = (context_t *) mongoc_apm_server_opening_get_context (event); - - mongoc_apm_server_opening_get_topology_id (event, &topology_id); - ASSERT (bson_oid_equal (&topology_id, &ctx->topology_id)); - - host_and_port = mongoc_apm_server_opening_get_host (event)->host_and_port; - context_append (ctx, - BCON_NEW ("server_opening_event", - "{", - "address", - BCON_UTF8 (host_and_port), - "topologyId", - BCON_UTF8 ("42"), - "}")); -} - -static void -server_closed (const mongoc_apm_server_closed_t *event) -{ - context_t *ctx; - bson_oid_t topology_id; - const char *host_and_port; - - ctx = (context_t *) mongoc_apm_server_closed_get_context (event); - - mongoc_apm_server_closed_get_topology_id (event, &topology_id); - ASSERT (bson_oid_equal (&topology_id, &ctx->topology_id)); - - host_and_port = mongoc_apm_server_closed_get_host (event)->host_and_port; - context_append (ctx, - BCON_NEW ("server_closed_event", - "{", - "address", - BCON_UTF8 (host_and_port), - "topologyId", - BCON_UTF8 ("42"), - "}")); -} - -static void -topology_changed (const mongoc_apm_topology_changed_t *event) -{ - context_t *ctx; - bson_oid_t topology_id; - bson_t prev_td; - bson_t new_td; - - ctx = (context_t *) mongoc_apm_topology_changed_get_context (event); - - mongoc_apm_topology_changed_get_topology_id (event, &topology_id); - ASSERT (bson_oid_equal (&topology_id, &ctx->topology_id)); - - td_to_bson (mongoc_apm_topology_changed_get_previous_description (event), - &prev_td); - td_to_bson (mongoc_apm_topology_changed_get_new_description (event), - &new_td); - - context_append (ctx, - BCON_NEW ("topology_description_changed_event", - "{", - "newDescription", - BCON_DOCUMENT (&new_td), - "previousDescription", - BCON_DOCUMENT (&prev_td), - "topologyId", - BCON_UTF8 ("42"), - "}")); - - bson_destroy (&prev_td); - bson_destroy (&new_td); -} - -static void -topology_opening (const mongoc_apm_topology_opening_t *event) -{ - context_t *ctx; - bson_oid_t zeroes; - - /* new event's topology id is NOT all zeroes */ - bson_oid_init_from_string (&zeroes, "000000000000000000000000"); - ASSERT (!bson_oid_equal (&event->topology_id, &zeroes)); - - ctx = (context_t *) mongoc_apm_topology_opening_get_context (event); - mongoc_apm_topology_opening_get_topology_id (event, &ctx->topology_id); - context_append ( - ctx, - BCON_NEW ( - "topology_opening_event", "{", "topologyId", BCON_UTF8 ("42"), "}")); -} - -static void -topology_closed (const mongoc_apm_topology_closed_t *event) -{ - context_t *ctx; - bson_oid_t topology_id; - - ctx = (context_t *) mongoc_apm_topology_closed_get_context (event); - mongoc_apm_topology_closed_get_topology_id (event, &topology_id); - ASSERT (bson_oid_equal (&topology_id, &ctx->topology_id)); - context_append ( - ctx, - BCON_NEW ( - "topology_closed_event", "{", "topologyId", BCON_UTF8 ("42"), "}")); -} - -/* no standard tests in the specs repo for heartbeat events, so invent some */ -static void -server_heartbeat_started (const mongoc_apm_server_heartbeat_started_t *event) -{ - context_t *ctx; - const mongoc_host_list_t *host; - - ctx = (context_t *) mongoc_apm_server_heartbeat_started_get_context (event); - host = mongoc_apm_server_heartbeat_started_get_host (event); - context_append (ctx, - BCON_NEW ("heartbeat_started_event", - "{", - "host", - BCON_UTF8 (host->host_and_port), - "}")); -} - -static void -server_heartbeat_succeeded ( - const mongoc_apm_server_heartbeat_succeeded_t *event) -{ - context_t *ctx; - const mongoc_host_list_t *host; - int64_t duration; - - ctx = - (context_t *) mongoc_apm_server_heartbeat_succeeded_get_context (event); - host = mongoc_apm_server_heartbeat_succeeded_get_host (event); - context_append (ctx, - BCON_NEW ("heartbeat_succeeded_event", - "{", - "host", - BCON_UTF8 (host->host_and_port), - "}")); - - duration = mongoc_apm_server_heartbeat_succeeded_get_duration (event); - _mongoc_array_append_val (&ctx->heartbeat_succeeded_durations, duration); -} - -static void -server_heartbeat_failed (const mongoc_apm_server_heartbeat_failed_t *event) -{ - context_t *ctx; - const mongoc_host_list_t *host; - int64_t duration; - - ctx = (context_t *) mongoc_apm_server_heartbeat_failed_get_context (event); - host = mongoc_apm_server_heartbeat_failed_get_host (event); - context_append (ctx, - BCON_NEW ("heartbeat_failed_event", - "{", - "host", - BCON_UTF8 (host->host_and_port), - "}")); - - duration = mongoc_apm_server_heartbeat_failed_get_duration (event); - _mongoc_array_append_val (&ctx->heartbeat_failed_durations, duration); -} - -static mongoc_apm_callbacks_t * -topology_event_callbacks (void) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_server_changed_cb (callbacks, server_changed); - mongoc_apm_set_server_opening_cb (callbacks, server_opening); - mongoc_apm_set_server_closed_cb (callbacks, server_closed); - mongoc_apm_set_topology_changed_cb (callbacks, topology_changed); - mongoc_apm_set_topology_opening_cb (callbacks, topology_opening); - mongoc_apm_set_topology_closed_cb (callbacks, topology_closed); - - return callbacks; -} - -static void -client_set_topology_event_callbacks (mongoc_client_t *client, - context_t *context) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = topology_event_callbacks (); - mongoc_client_set_apm_callbacks (client, callbacks, (void *) context); - mongoc_apm_callbacks_destroy (callbacks); -} - -static void -pool_set_topology_event_callbacks (mongoc_client_pool_t *pool, - context_t *context) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = topology_event_callbacks (); - mongoc_client_pool_set_apm_callbacks (pool, callbacks, (void *) context); - mongoc_apm_callbacks_destroy (callbacks); -} - -static mongoc_apm_callbacks_t * -heartbeat_event_callbacks (void) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_server_heartbeat_started_cb (callbacks, - server_heartbeat_started); - mongoc_apm_set_server_heartbeat_succeeded_cb (callbacks, - server_heartbeat_succeeded); - mongoc_apm_set_server_heartbeat_failed_cb (callbacks, - server_heartbeat_failed); - - return callbacks; -} - -static void -client_set_heartbeat_event_callbacks (mongoc_client_t *client, - context_t *context) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = heartbeat_event_callbacks (); - mongoc_client_set_apm_callbacks (client, callbacks, (void *) context); - mongoc_apm_callbacks_destroy (callbacks); -} - -static void -pool_set_heartbeat_event_callbacks (mongoc_client_pool_t *pool, - context_t *context) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = heartbeat_event_callbacks (); - mongoc_client_pool_set_apm_callbacks (pool, callbacks, (void *) context); - mongoc_apm_callbacks_destroy (callbacks); -} - -/* - *----------------------------------------------------------------------- - * - * Run the JSON tests from the SDAM Monitoring spec. - * - *----------------------------------------------------------------------- - */ -static void -test_sdam_monitoring_cb (bson_t *test) -{ - mongoc_client_t *client; - mongoc_topology_t *topology; - bson_t phase; - bson_t phases; - bson_t outcome; - bson_iter_t phase_iter; - bson_iter_t phase_field_iter; - bson_iter_t outcome_iter; - bson_iter_t iter; - bson_t events_expected; - context_t context; - - /* parse out the uri and use it to create a client */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "uri")); - client = mongoc_client_new (bson_iter_utf8 (&iter, NULL)); - topology = client->topology; - context_init (&context); - client_set_topology_event_callbacks (client, &context); - - /* for each phase, parse and validate */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "phases")); - bson_iter_bson (&iter, &phases); - bson_iter_init (&phase_iter, &phases); - - while (bson_iter_next (&phase_iter)) { - bson_iter_bson (&phase_iter, &phase); - - /* this test doesn't exercise this code path naturally, see below in - * _test_topology_events for a non-hacky test of this event */ - _mongoc_topology_description_monitor_opening (&topology->description); - process_sdam_test_ismaster_responses (&phase, - &client->topology->description); - - /* parse out "outcome" and validate */ - BSON_ASSERT (bson_iter_init_find (&phase_field_iter, &phase, "outcome")); - bson_iter_bson (&phase_field_iter, &outcome); - bson_iter_init (&outcome_iter, &outcome); - - while (bson_iter_next (&outcome_iter)) { - if (strcmp ("events", bson_iter_key (&outcome_iter)) == 0) { - bson_iter_bson (&outcome_iter, &events_expected); - check_json_sdam_events (&context.events, &events_expected); - } else { - fprintf (stderr, - "ERROR: unparsed test field %s\n", - bson_iter_key (&outcome_iter)); - BSON_ASSERT (false); - } - } - } - - mongoc_client_destroy (client); - context_destroy (&context); -} - -/* - *----------------------------------------------------------------------- - * - * Runner for the JSON tests for SDAM Monitoring.. - * - *----------------------------------------------------------------------- - */ -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - ASSERT (realpath (JSON_DIR "/server_discovery_and_monitoring/monitoring", - resolved)); - - install_json_test_suite (suite, resolved, &test_sdam_monitoring_cb); -} - -static void -_test_topology_events (bool pooled) -{ - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - context_t context; - bool r; - bson_error_t error; - bson_iter_t events_iter; - bson_iter_t event_iter; - uint32_t i; - - context_init (&context); - - if (pooled) { - pool = test_framework_client_pool_new (); - pool_set_topology_event_callbacks (pool, &context); - client = mongoc_client_pool_pop (pool); - } else { - client = test_framework_client_new (); - client_set_topology_event_callbacks (client, &context); - } - - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - /* first event is topology opening */ - bson_iter_init (&events_iter, &context.events); - bson_iter_next (&events_iter); - ASSERT (bson_iter_recurse (&events_iter, &event_iter)); - ASSERT (bson_iter_find (&event_iter, "topology_opening_event")); - - /* last event is topology closed */ - for (i = 1; i < context.n_events; i++) { - ASSERT (bson_iter_next (&events_iter)); - } - - ASSERT (bson_iter_recurse (&events_iter, &event_iter)); - ASSERT (bson_iter_find (&event_iter, "topology_closed_event")); - - /* no more events */ - ASSERT (!bson_iter_next (&events_iter)); - - context_destroy (&context); -} - -static void -test_topology_events_single (void) -{ - _test_topology_events (false); -} - -static void -test_topology_events_pooled (void) -{ - _test_topology_events (true); -} - -static void -test_topology_events_disabled (void) -{ - mongoc_client_t *client; - context_t context; - bool r; - bson_error_t error; - bson_iter_t events_iter; - bson_iter_t event_iter; - uint32_t i; - - context_init (&context); - - client = test_framework_client_new (); - client_set_topology_event_callbacks (client, &context); - - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - /* disable callbacks before destroying so we don't see a topology closed - * event */ - mongoc_client_set_apm_callbacks (client, NULL, NULL); - mongoc_client_destroy (client); - - /* first event is topology opening */ - bson_iter_init (&events_iter, &context.events); - bson_iter_next (&events_iter); - ASSERT (bson_iter_recurse (&events_iter, &event_iter)); - ASSERT (bson_iter_find (&event_iter, "topology_opening_event")); - - /* move forward to the last event */ - for (i = 1; i < context.n_events; i++) { - ASSERT (bson_iter_next (&events_iter)); - } - - /* verify we didn't receive a topology closed event */ - ASSERT (bson_iter_recurse (&events_iter, &event_iter)); - ASSERT (!bson_iter_find (&event_iter, "topology_closed_event")); - - /* no more events */ - ASSERT (!bson_iter_next (&events_iter)); - - context_destroy (&context); -} - -static bool -responder (request_t *request, void *data) -{ - if (!strcmp (request->command_name, "foo")) { - mock_server_replies_simple (request, "{'ok': 1}"); - request_destroy (request); - return true; - } - - return false; -} - -static void -_test_heartbeat_events (bool pooled, bool succeeded) -{ - context_t context; - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - int64_t start; - int64_t duration; - future_t *future; - request_t *request; - char *expected_json; - bson_error_t error; - mongoc_array_t *durations; - size_t i; - - context_init (&context); - - /* auto-respond to "foo" command */ - server = mock_server_new (); - mock_server_run (server); - mock_server_autoresponds (server, responder, NULL, NULL); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 400); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - pool_set_heartbeat_event_callbacks (pool, &context); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - client_set_heartbeat_event_callbacks (client, &context); - } - - start = bson_get_monotonic_time (); - - /* trigger "ismaster" handshake */ - future = future_client_command_simple ( - client, "admin", tmp_bson ("{'foo': 1}"), NULL, NULL, &error); - - /* topology scanner calls ismaster once */ - request = mock_server_receives_ismaster (server); - - if (succeeded) { - mock_server_replies ( - request, - MONGOC_REPLY_NONE, - 0, - 0, - 1, - "{'ok': 1, 'minWireVersion': 2, 'maxWireVersion': 5}"); - request_destroy (request); - } else { - mock_server_hangs_up (request); - request_destroy (request); - } - - /* pooled client opens new socket, handshakes it by calling ismaster again */ - if (pooled && succeeded) { - request = mock_server_receives_ismaster (server); - mock_server_replies ( - request, - MONGOC_REPLY_NONE, - 0, - 0, - 1, - "{'ok': 1, 'minWireVersion': 2, 'maxWireVersion': 5}"); - request_destroy (request); - } - - if (succeeded) { - /* "foo" command succeeds */ - ASSERT_OR_PRINT (future_get_bool (future), error); - } else { - ASSERT (!future_get_bool (future)); - } - - duration = bson_get_monotonic_time () - start; - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - /* even if pooled, only topology scanner sends events, so we get one pair */ - if (succeeded) { - durations = &context.heartbeat_succeeded_durations; - expected_json = bson_strdup_printf ( - "{'0': {'heartbeat_started_event': {'host': '%s'}}," - " '1': {'heartbeat_succeeded_event': {'host': '%s'}}}", - mock_server_get_host_and_port (server), - mock_server_get_host_and_port (server)); - } else { - durations = &context.heartbeat_failed_durations; - expected_json = bson_strdup_printf ( - "{'0': {'heartbeat_started_event': {'host': '%s'}}," - " '1': {'heartbeat_failed_event': {'host': '%s'}}}", - mock_server_get_host_and_port (server), - mock_server_get_host_and_port (server)); - } - - ASSERT_CMPSIZE_T (durations->len, >, (size_t) 0); - for (i = 0; i < durations->len; i++) { - int64_t d = _mongoc_array_index (durations, int64_t, i); - ASSERT_CMPINT64 (d, >=, (int64_t) 0); - ASSERT_CMPINT64 (d, <=, duration); - } - - check_json_sdam_events (&context.events, tmp_bson (expected_json)); - - future_destroy (future); - bson_free (expected_json); - mongoc_uri_destroy (uri); - mock_server_destroy (server); - context_destroy (&context); -} - -static void -test_heartbeat_events_single_succeeded (void) -{ - _test_heartbeat_events (false, true); -} - -static void -test_heartbeat_events_pooled_succeeded (void) -{ - _test_heartbeat_events (true, true); -} - -static void -test_heartbeat_events_single_failed (void) -{ - _test_heartbeat_events (false, false); -} - -static void -test_heartbeat_events_pooled_failed (void) -{ - _test_heartbeat_events (true, false); -} - -static void -_test_heartbeat_fails_dns (bool pooled) -{ - context_t context; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - int64_t start; - int64_t duration; - bool r; - bson_error_t error; - mongoc_array_t *durations; - size_t i; - - context_init (&context); - uri = mongoc_uri_new ( - "mongodb://doesntexist.foobar/?serverSelectionTimeoutMS=1000"); - if (pooled) { - pool = mongoc_client_pool_new (uri); - pool_set_heartbeat_event_callbacks (pool, &context); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - client_set_heartbeat_event_callbacks (client, &context); - } - - start = bson_get_monotonic_time (); - - /* trigger "ismaster" handshake */ - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'foo': 1}"), NULL, NULL, &error); - - ASSERT (!r); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "Failed to resolve"); - - duration = bson_get_monotonic_time () - start; - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - durations = &context.heartbeat_failed_durations; - - ASSERT_CMPSIZE_T (durations->len, >, (size_t) 0); - for (i = 0; i < durations->len; i++) { - int64_t d = _mongoc_array_index (durations, int64_t, i); - ASSERT_CMPINT64 (d, >=, (int64_t) 0); - ASSERT_CMPINT64 (d, <=, duration); - } - - mongoc_uri_destroy (uri); - context_destroy (&context); -} - -static void -test_heartbeat_fails_dns_single (void *ctx) -{ - _test_heartbeat_fails_dns (false); -} - -static void -test_heartbeat_fails_dns_pooled (void *ctx) -{ - _test_heartbeat_fails_dns (true); -} - -void -test_sdam_monitoring_install (TestSuite *suite) -{ - test_all_spec_tests (suite); - TestSuite_AddLive ( - suite, - "/server_discovery_and_monitoring/monitoring/topology/single", - test_topology_events_single); - TestSuite_AddLive ( - suite, - "/server_discovery_and_monitoring/monitoring/topology/pooled", - test_topology_events_pooled); - TestSuite_AddLive ( - suite, - "/server_discovery_and_monitoring/monitoring/topology/disabled", - test_topology_events_disabled); - TestSuite_AddMockServerTest ( - suite, - "/server_discovery_and_monitoring/monitoring/heartbeat/single/succeeded", - test_heartbeat_events_single_succeeded); - TestSuite_AddMockServerTest ( - suite, - "/server_discovery_and_monitoring/monitoring/heartbeat/single/failed", - test_heartbeat_events_single_failed); - TestSuite_AddMockServerTest ( - suite, - "/server_discovery_and_monitoring/monitoring/heartbeat/pooled/succeeded", - test_heartbeat_events_pooled_succeeded); - TestSuite_AddMockServerTest ( - suite, - "/server_discovery_and_monitoring/monitoring/heartbeat/pooled/failed", - test_heartbeat_events_pooled_failed); - TestSuite_AddFull ( - suite, - "/server_discovery_and_monitoring/monitoring/heartbeat/single/dns", - test_heartbeat_fails_dns_single, - NULL, - NULL, - test_framework_skip_if_offline); - TestSuite_AddFull ( - suite, - "/server_discovery_and_monitoring/monitoring/heartbeat/pooled/dns", - test_heartbeat_fails_dns_pooled, - NULL, - NULL, - test_framework_skip_if_offline); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-sdam.c b/lib/mongoc/libmongoc/tests/test-mongoc-sdam.c deleted file mode 100644 index 01e8e748851c27bcbe9ff0547c0399af133cc2d9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-sdam.c +++ /dev/null @@ -1,210 +0,0 @@ -#include <mongoc/mongoc.h> - -#include <mongoc/mongoc-set-private.h> - -#include "json-test.h" - -#include "mongoc/mongoc-client-private.h" -#include "test-libmongoc.h" - -#ifdef BSON_HAVE_STRINGS_H -#include <strings.h> -#endif - - -static void -_topology_has_description (mongoc_topology_description_t *topology, - bson_t *server, - const char *address) -{ - mongoc_server_description_t *sd; - bson_iter_t server_iter; - const char *server_type; - const char *set_name; - - sd = server_description_by_hostname (topology, address); - BSON_ASSERT (sd); - - bson_iter_init (&server_iter, server); - while (bson_iter_next (&server_iter)) { - if (strcmp ("setName", bson_iter_key (&server_iter)) == 0) { - set_name = bson_iter_utf8 (&server_iter, NULL); - if (set_name) { - BSON_ASSERT (sd->set_name); - ASSERT_CMPSTR (sd->set_name, set_name); - } - } else if (strcmp ("type", bson_iter_key (&server_iter)) == 0) { - server_type = bson_iter_utf8 (&server_iter, NULL); - if (sd->type != server_type_from_test (server_type)) { - fprintf (stderr, - "expected server type %s not %s\n", - server_type, - mongoc_server_description_type (sd)); - abort (); - } - } else if (strcmp ("setVersion", bson_iter_key (&server_iter)) == 0) { - int64_t expected_set_version; - if (BSON_ITER_HOLDS_NULL (&server_iter)) { - expected_set_version = MONGOC_NO_SET_VERSION; - } else { - expected_set_version = bson_iter_as_int64 (&server_iter); - } - BSON_ASSERT (sd->set_version == expected_set_version); - } else if (strcmp ("electionId", bson_iter_key (&server_iter)) == 0) { - bson_oid_t expected_oid; - if (BSON_ITER_HOLDS_NULL (&server_iter)) { - bson_oid_init_from_string (&expected_oid, - "000000000000000000000000"); - } else { - ASSERT (BSON_ITER_HOLDS_OID (&server_iter)); - bson_oid_copy (bson_iter_oid (&server_iter), &expected_oid); - } - - ASSERT_CMPOID (&sd->election_id, &expected_oid); - } else { - fprintf ( - stderr, "ERROR: unparsed field %s\n", bson_iter_key (&server_iter)); - BSON_ASSERT (0); - } - } -} - -/* - *----------------------------------------------------------------------- - * - * Run the JSON tests from the Server Discovery and Monitoring spec. - * - *----------------------------------------------------------------------- - */ -static void -test_sdam_cb (bson_t *test) -{ - mongoc_client_t *client; - mongoc_topology_description_t *td; - bson_t phase; - bson_t phases; - bson_t servers; - bson_t server; - bson_t outcome; - bson_iter_t phase_iter; - bson_iter_t phase_field_iter; - bson_iter_t servers_iter; - bson_iter_t outcome_iter; - bson_iter_t iter; - const char *set_name; - const char *hostname; - - /* parse out the uri and use it to create a client */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "uri")); - client = mongoc_client_new (bson_iter_utf8 (&iter, NULL)); - td = &client->topology->description; - - /* for each phase, parse and validate */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "phases")); - bson_iter_bson (&iter, &phases); - bson_iter_init (&phase_iter, &phases); - - while (bson_iter_next (&phase_iter)) { - bson_iter_bson (&phase_iter, &phase); - - process_sdam_test_ismaster_responses (&phase, td); - - /* parse out "outcome" and validate */ - BSON_ASSERT (bson_iter_init_find (&phase_field_iter, &phase, "outcome")); - bson_iter_bson (&phase_field_iter, &outcome); - bson_iter_init (&outcome_iter, &outcome); - - while (bson_iter_next (&outcome_iter)) { - if (strcmp ("servers", bson_iter_key (&outcome_iter)) == 0) { - bson_iter_bson (&outcome_iter, &servers); - ASSERT_CMPINT ( - bson_count_keys (&servers), ==, (int) td->servers->items_len); - - bson_iter_init (&servers_iter, &servers); - - /* for each server, ensure topology has a matching entry */ - while (bson_iter_next (&servers_iter)) { - hostname = bson_iter_key (&servers_iter); - bson_iter_bson (&servers_iter, &server); - - _topology_has_description (td, &server, hostname); - } - - } else if (strcmp ("setName", bson_iter_key (&outcome_iter)) == 0) { - set_name = bson_iter_utf8 (&outcome_iter, NULL); - if (set_name) { - BSON_ASSERT (td->set_name); - ASSERT_CMPSTR (td->set_name, set_name); - } - } else if (strcmp ("topologyType", bson_iter_key (&outcome_iter)) == - 0) { - ASSERT_CMPSTR (mongoc_topology_description_type (td), - bson_iter_utf8 (&outcome_iter, NULL)); - } else if (strcmp ("logicalSessionTimeoutMinutes", - bson_iter_key (&outcome_iter)) == 0) { - if (BSON_ITER_HOLDS_NULL (&outcome_iter)) { - ASSERT_CMPINT64 (td->session_timeout_minutes, - ==, - (int64_t) MONGOC_NO_SESSIONS); - } else { - ASSERT_CMPINT64 (td->session_timeout_minutes, - ==, - bson_iter_as_int64 (&outcome_iter)); - } - } else if (strcmp ("compatible", bson_iter_key (&outcome_iter)) == 0) { - if (bson_iter_as_bool (&outcome_iter)) { - ASSERT_CMPINT (0, ==, td->compatibility_error.domain); - } else { - ASSERT_ERROR_CONTAINS (td->compatibility_error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - ""); - } - } else { - fprintf (stderr, - "ERROR: unparsed test field %s\n", - bson_iter_key (&outcome_iter)); - BSON_ASSERT (false); - } - } - } - mongoc_client_destroy (client); -} - -/* - *----------------------------------------------------------------------- - * - * Runner for the JSON tests for server discovery and monitoring.. - * - *----------------------------------------------------------------------- - */ -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - /* Single */ - ASSERT ( - realpath (JSON_DIR "/server_discovery_and_monitoring/single", resolved)); - install_json_test_suite (suite, resolved, &test_sdam_cb); - - /* Replica set */ - test_framework_resolve_path (JSON_DIR "/server_discovery_and_monitoring/rs", resolved); - install_json_test_suite (suite, resolved, &test_sdam_cb); - - /* Sharded */ - ASSERT ( - realpath (JSON_DIR "/server_discovery_and_monitoring/sharded", resolved)); - install_json_test_suite (suite, resolved, &test_sdam_cb); - - /* Tests not in official Server Discovery And Monitoring Spec */ - ASSERT (realpath (JSON_DIR "/server_discovery_and_monitoring/supplemental", - resolved)); - install_json_test_suite (suite, resolved, &test_sdam_cb); -} - -void -test_sdam_install (TestSuite *suite) -{ - test_all_spec_tests (suite); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-server-selection-errors.c b/lib/mongoc/libmongoc/tests/test-mongoc-server-selection-errors.c deleted file mode 100644 index cc787e1b0887baa7527c8e39f6ed05120e203cea..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-server-selection-errors.c +++ /dev/null @@ -1,341 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-client-pool-private.h" - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - - -static mongoc_stream_t * -cannot_resolve (const mongoc_uri_t *uri, - const mongoc_host_list_t *host, - void *user_data, - bson_error_t *error) -{ - bson_set_error (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NAME_RESOLUTION, - "Fake error for '%s'", - host->host); - - return NULL; -} - - -static void -server_selection_error_dns (const char *uri_str, - const char *errmsg, - bool expect_success, - bool pooled) -{ - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_collection_t *collection; - bson_error_t error; - bson_t *command; - bson_t reply; - bool success; - - uri = mongoc_uri_new (uri_str); - ASSERT (uri); - - if (pooled && expect_success) { - pool = mongoc_client_pool_new (uri); - test_framework_set_pool_ssl_opts (pool); - client = mongoc_client_pool_pop (pool); - } else if (pooled) { - /* we expect selection to fail; let the test finish faster */ - mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 100); - pool = mongoc_client_pool_new (uri); - test_framework_set_pool_ssl_opts (pool); - _mongoc_client_pool_set_stream_initiator (pool, cannot_resolve, NULL); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - if (!expect_success) { - mongoc_client_set_stream_initiator (client, cannot_resolve, NULL); - } - } - - collection = mongoc_client_get_collection (client, "test", "test"); - - command = tmp_bson ("{'ping': 1}"); - success = mongoc_collection_command_simple ( - collection, command, NULL, &reply, &error); - ASSERT_OR_PRINT (success == expect_success, error); - - if (!success && errmsg) { - ASSERT_CMPSTR (error.message, errmsg); - } - - bson_destroy (&reply); - mongoc_collection_destroy (collection); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); -} - -static void -test_server_selection_error_dns_direct_single (void) -{ - server_selection_error_dns ( - "mongodb://example-localhost:27017/", - "No suitable servers found (`serverSelectionTryOnce` set): " - "[Fake error for 'example-localhost']", - false, - false); -} - -static void -test_server_selection_error_dns_direct_pooled (void *ctx) -{ - server_selection_error_dns ( - "mongodb://example-localhost:27017/", - "No suitable servers found: `serverSelectionTimeoutMS` expired: " - "[Fake error for 'example-localhost']", - false, - true); -} - -static void -test_server_selection_error_dns_multi_fail_single (void) -{ - server_selection_error_dns ( - "mongodb://example-localhost:27017,other-example-localhost:27017/", - "No suitable servers found (`serverSelectionTryOnce` set):" - " [Fake error for 'example-localhost']" - " [Fake error for 'other-example-localhost']", - false, - false); -} - -static void -test_server_selection_error_dns_multi_fail_pooled (void *ctx) -{ - server_selection_error_dns ( - "mongodb://example-localhost:27017,other-example-localhost:27017/", - "No suitable servers found: `serverSelectionTimeoutMS` expired:" - " [Fake error for 'example-localhost']" - " [Fake error for 'other-example-localhost']", - false, - true); -} - -static void -_test_server_selection_error_dns_multi_success (bool pooled) -{ - char *host; - char *uri_str; - - host = test_framework_get_host (); - uri_str = bson_strdup_printf ("mongodb://example-localhost:27017," - "%s:%d," - "other-example-localhost:27017/", - host, - test_framework_get_port ()); - - server_selection_error_dns (uri_str, "", true, pooled); - - bson_free (uri_str); - bson_free (host); -} - -static void -test_server_selection_error_dns_multi_success_single (void *context) -{ - _test_server_selection_error_dns_multi_success (false); -} - -static void -test_server_selection_error_dns_multi_success_pooled (void *context) -{ - _test_server_selection_error_dns_multi_success (true); -} - -static void -_test_server_selection_uds_auth_failure (bool pooled) -{ - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - char *path; - char *uri_str; - - path = test_framework_get_unix_domain_socket_path_escaped (); - uri_str = bson_strdup_printf ("mongodb://user:wrongpass@%s", path); - - uri = mongoc_uri_new (uri_str); - ASSERT (uri); - - if (pooled) { - pool = mongoc_client_pool_new (uri); -#ifdef MONGOC_ENABLE_SSL - test_framework_set_pool_ssl_opts (pool); -#endif - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); -#ifdef MONGOC_ENABLE_SSL - test_framework_set_ssl_opts (client); -#endif - } - - capture_logs (true); - - ASSERT_OR_PRINT ( - !mongoc_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, &error), - error); - - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_CLIENT); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_CLIENT_AUTHENTICATE); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - bson_free (path); - bson_free (uri_str); - mongoc_uri_destroy (uri); -} - -static void -test_server_selection_uds_auth_failure_single (void *context) -{ - _test_server_selection_uds_auth_failure (false); -} - -static void -test_server_selection_uds_auth_failure_pooled (void *context) -{ - _test_server_selection_uds_auth_failure (true); -} - -static void -_test_server_selection_uds_not_found (bool pooled) -{ - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bson_error_t error; - - uri = mongoc_uri_new ("mongodb://%2Ftmp%2Fmongodb-so-close.sock"); - ASSERT (uri); - mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 100); - - if (pooled) { - pool = mongoc_client_pool_new (uri); -#ifdef MONGOC_ENABLE_SSL - test_framework_set_pool_ssl_opts (pool); -#endif - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); -#ifdef MONGOC_ENABLE_SSL - test_framework_set_ssl_opts (client); -#endif - } - -#ifdef MONGOC_ENABLE_SSL - test_framework_set_ssl_opts (client); -#endif - - ASSERT (!mongoc_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, &error)); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER_SELECTION); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_SERVER_SELECTION_FAILURE); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); -} - -static void -test_server_selection_uds_not_found_single (void *context) -{ - _test_server_selection_uds_not_found (false); -} - -static void -test_server_selection_uds_not_found_pooled (void *context) -{ - _test_server_selection_uds_not_found (true); -} - - -void -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", - test_server_selection_error_dns_direct_pooled, - NULL, - NULL, - test_framework_skip_if_slow); - 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", - 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", - 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", - 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", - 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", - 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", - test_server_selection_uds_not_found_single, - NULL, - NULL, - test_framework_skip_if_windows); - TestSuite_AddFull (suite, - "/server_selection/errors/uds/not_found/pooled", - test_server_selection_uds_not_found_pooled, - NULL, - NULL, - test_framework_skip_if_windows); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-server-selection.c b/lib/mongoc/libmongoc/tests/test-mongoc-server-selection.c deleted file mode 100644 index 2fe5ee8a541cb3c5c86df86e603a8be3fa203c9d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-server-selection.c +++ /dev/null @@ -1,71 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "json-test.h" -#include "test-libmongoc.h" - - -/* - *----------------------------------------------------------------------- - * - * test_rtt_calculation_cb -- - * - * Runs the JSON tests for RTT calculation included with the - * Server Selection spec. - * - *----------------------------------------------------------------------- - */ - -static void -test_rtt_calculation_cb (bson_t *test) -{ - mongoc_server_description_t *description; - bson_iter_t iter; - - BSON_ASSERT (test); - - description = - (mongoc_server_description_t *) bson_malloc0 (sizeof *description); - mongoc_server_description_init (description, "localhost:27017", 1); - - /* parse RTT into server description */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "avg_rtt_ms")); - description->round_trip_time_msec = bson_iter_int64 (&iter); - - /* update server description with new rtt */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "new_rtt_ms")); - mongoc_server_description_update_rtt (description, bson_iter_int64 (&iter)); - - /* ensure new RTT was calculated correctly */ - BSON_ASSERT (bson_iter_init_find (&iter, test, "new_avg_rtt")); - BSON_ASSERT (description->round_trip_time_msec == bson_iter_int64 (&iter)); - - mongoc_server_description_destroy (description); -} - - -/* - *----------------------------------------------------------------------- - * - * Runner for the JSON tests for server selection. - * - *----------------------------------------------------------------------- - */ -static void -test_all_spec_tests (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - /* RTT calculation */ - test_framework_resolve_path (JSON_DIR "/server_selection/rtt", resolved); - install_json_test_suite (suite, resolved, &test_rtt_calculation_cb); - - /* SS logic */ - test_framework_resolve_path (JSON_DIR "/server_selection/server_selection", resolved); - install_json_test_suite (suite, resolved, &test_server_selection_logic_cb); -} - -void -test_server_selection_install (TestSuite *suite) -{ - test_all_spec_tests (suite); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-set.c b/lib/mongoc/libmongoc/tests/test-mongoc-set.c deleted file mode 100644 index 102bef7068fff5e4013ba851b9efd30cb4d3e1d6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-set.c +++ /dev/null @@ -1,92 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-set-private.h" - -#include "TestSuite.h" - -static void -test_set_dtor (void *item_, void *ctx_) -{ - int *destroyed = (int *) ctx_; - - (*destroyed)++; -} - -static bool -test_set_visit_cb (void *item_, void *ctx_) -{ - int *visited = (int *) ctx_; - - (*visited)++; - - return true; -} - -static bool -test_set_stop_after_cb (void *item_, void *ctx_) -{ - int *stop_after = (int *) ctx_; - - (*stop_after)--; - - return *stop_after > 0; -} - -static void -test_set_new (void) -{ - void *items[10]; - int i; - int destroyed = 0; - int visited = 0; - int stop_after = 3; - - mongoc_set_t *set = mongoc_set_new (2, &test_set_dtor, &destroyed); - - for (i = 0; i < 5; i++) { - mongoc_set_add (set, i, items + i); - } - - for (i = 0; i < 5; i++) { - BSON_ASSERT (mongoc_set_get (set, i) == items + i); - } - - mongoc_set_rm (set, 0); - - BSON_ASSERT (destroyed == 1); - - for (i = 5; i < 10; i++) { - mongoc_set_add (set, i, items + i); - } - - for (i = 5; i < 10; i++) { - BSON_ASSERT (mongoc_set_get (set, i) == items + i); - } - - mongoc_set_rm (set, 9); - BSON_ASSERT (destroyed == 2); - mongoc_set_rm (set, 5); - BSON_ASSERT (destroyed == 3); - - BSON_ASSERT (mongoc_set_get (set, 1) == items + 1); - BSON_ASSERT (mongoc_set_get (set, 7) == items + 7); - BSON_ASSERT (!mongoc_set_get (set, 5)); - - mongoc_set_add (set, 5, items + 5); - BSON_ASSERT (mongoc_set_get (set, 5) == items + 5); - - mongoc_set_for_each (set, test_set_visit_cb, &visited); - BSON_ASSERT (visited == 8); - - mongoc_set_for_each (set, test_set_stop_after_cb, &stop_after); - BSON_ASSERT (stop_after == 0); - - mongoc_set_destroy (set); -} - - -void -test_set_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Set/new", test_set_new); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-socket.c b/lib/mongoc/libmongoc/tests/test-mongoc-socket.c deleted file mode 100644 index a9081caac6d2d2558a389208222755972d9db61d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-socket.c +++ /dev/null @@ -1,476 +0,0 @@ -#include <fcntl.h> -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-util-private.h> - -#include "mongoc/mongoc-socket-private.h" -#include "mongoc/mongoc-thread-private.h" -#include "mongoc/mongoc-errno-private.h" -#include "TestSuite.h" - -#include "test-libmongoc.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "socket-test" - -#define TIMEOUT 10000 -#define WAIT 1000 - - -static size_t gFourMB = 1024 * 1024 * 4; - -typedef struct { - unsigned short server_port; - mongoc_cond_t cond; - bson_mutex_t cond_mutex; - bool closed_socket; - int amount; - int32_t server_sleep_ms; -} socket_test_data_t; - - -static void * -socket_test_server (void *data_) -{ - socket_test_data_t *data = (socket_test_data_t *) data_; - struct sockaddr_in server_addr = {0}; - mongoc_socket_t *listen_sock; - mongoc_socket_t *conn_sock; - mongoc_stream_t *stream; - mongoc_iovec_t iov; - mongoc_socklen_t sock_len; - ssize_t r; - char buf[5]; - - iov.iov_base = buf; - iov.iov_len = sizeof (buf); - - listen_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (listen_sock); - - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - server_addr.sin_port = htons (0); - - r = mongoc_socket_bind ( - listen_sock, (struct sockaddr *) &server_addr, sizeof server_addr); - BSON_ASSERT (r == 0); - - sock_len = sizeof (server_addr); - r = mongoc_socket_getsockname ( - listen_sock, (struct sockaddr *) &server_addr, &sock_len); - BSON_ASSERT (r == 0); - - r = mongoc_socket_listen (listen_sock, 10); - BSON_ASSERT (r == 0); - - bson_mutex_lock (&data->cond_mutex); - data->server_port = ntohs (server_addr.sin_port); - mongoc_cond_signal (&data->cond); - bson_mutex_unlock (&data->cond_mutex); - - conn_sock = mongoc_socket_accept (listen_sock, -1); - BSON_ASSERT (conn_sock); - - stream = mongoc_stream_socket_new (conn_sock); - BSON_ASSERT (stream); - - r = mongoc_stream_readv (stream, &iov, 1, 5, TIMEOUT); - BSON_ASSERT (r == 5); - BSON_ASSERT (strcmp (buf, "ping") == 0); - - strcpy (buf, "pong"); - - _mongoc_usleep (data->server_sleep_ms * 1000); - r = mongoc_stream_writev (stream, &iov, 1, TIMEOUT); - - /* if we sleep the client times out, else assert the client reads the data */ - if (data->server_sleep_ms == 0) { - BSON_ASSERT (r == 5); - } - - mongoc_stream_destroy (stream); - - bson_mutex_lock (&data->cond_mutex); - data->closed_socket = true; - mongoc_cond_signal (&data->cond); - bson_mutex_unlock (&data->cond_mutex); - - mongoc_socket_destroy (listen_sock); - - return NULL; -} - - -static void * -socket_test_client (void *data_) -{ - socket_test_data_t *data = (socket_test_data_t *) data_; - int64_t start; - mongoc_socket_t *conn_sock; - char buf[5]; - ssize_t r; - bool closed; - struct sockaddr_in server_addr = {0}; - mongoc_stream_t *stream; - mongoc_iovec_t iov; - - iov.iov_base = buf; - iov.iov_len = sizeof (buf); - - conn_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (conn_sock); - - bson_mutex_lock (&data->cond_mutex); - while (!data->server_port) { - mongoc_cond_wait (&data->cond, &data->cond_mutex); - } - bson_mutex_unlock (&data->cond_mutex); - - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons (data->server_port); - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - - r = mongoc_socket_connect ( - conn_sock, (struct sockaddr *) &server_addr, sizeof (server_addr), -1); - BSON_ASSERT (r == 0); - - stream = mongoc_stream_socket_new (conn_sock); - - strcpy (buf, "ping"); - - closed = mongoc_stream_check_closed (stream); - BSON_ASSERT (closed == false); - - r = mongoc_stream_writev (stream, &iov, 1, TIMEOUT); - BSON_ASSERT (r == 5); - - closed = mongoc_stream_check_closed (stream); - BSON_ASSERT (closed == false); - - if (data->server_sleep_ms == 0) { - r = mongoc_stream_readv (stream, &iov, 1, 5, TIMEOUT); - BSON_ASSERT (r == 5); - BSON_ASSERT (strcmp (buf, "pong") == 0); - - bson_mutex_lock (&data->cond_mutex); - while (!data->closed_socket) { - mongoc_cond_wait (&data->cond, &data->cond_mutex); - } - bson_mutex_unlock (&data->cond_mutex); - - /* wait up to a second for the client to detect server's shutdown */ - start = bson_get_monotonic_time (); - while (!mongoc_stream_check_closed (stream)) { - ASSERT_CMPINT64 (bson_get_monotonic_time (), <, start + 1000 * 1000); - _mongoc_usleep (1000); - } - BSON_ASSERT (!mongoc_stream_timed_out (stream)); - } else { - r = mongoc_stream_readv (stream, &iov, 1, 5, data->server_sleep_ms / 2); - ASSERT_CMPSSIZE_T (r, ==, (ssize_t) -1); - BSON_ASSERT (mongoc_stream_timed_out (stream)); - } - - mongoc_stream_destroy (stream); - - return NULL; -} - - -static void * -sendv_test_server (void *data_) -{ - socket_test_data_t *data = (socket_test_data_t *) data_; - struct sockaddr_in server_addr = {0}; - mongoc_socket_t *listen_sock; - mongoc_socket_t *conn_sock; - mongoc_stream_t *stream; - mongoc_iovec_t iov; - mongoc_socklen_t sock_len; - int amount = 0; - ssize_t r; - char *buf = (char *) bson_malloc (gFourMB); - - iov.iov_base = buf; - iov.iov_len = gFourMB; - - listen_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (listen_sock); - - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - server_addr.sin_port = htons (0); - - r = mongoc_socket_bind ( - listen_sock, (struct sockaddr *) &server_addr, sizeof server_addr); - BSON_ASSERT (r == 0); - - sock_len = sizeof (server_addr); - r = mongoc_socket_getsockname ( - listen_sock, (struct sockaddr *) &server_addr, &sock_len); - BSON_ASSERT (r == 0); - - r = mongoc_socket_listen (listen_sock, 10); - BSON_ASSERT (r == 0); - - bson_mutex_lock (&data->cond_mutex); - data->server_port = ntohs (server_addr.sin_port); - mongoc_cond_signal (&data->cond); - bson_mutex_unlock (&data->cond_mutex); - - conn_sock = mongoc_socket_accept (listen_sock, -1); - BSON_ASSERT (conn_sock); - - stream = mongoc_stream_socket_new (conn_sock); - BSON_ASSERT (stream); - - /* Wait until the client has pushed so much data he can't write more */ - bson_mutex_lock (&data->cond_mutex); - while (!data->amount) { - mongoc_cond_wait (&data->cond, &data->cond_mutex); - } - amount = data->amount; - data->amount = 0; - bson_mutex_unlock (&data->cond_mutex); - - /* Start reading everything off the socket to unblock the client */ - do { - r = mongoc_stream_readv (stream, &iov, 1, amount, WAIT); - if (r > 0) { - amount -= r; - } - } while (amount > 0); - - /* Allow the client to finish all its writes */ - bson_mutex_lock (&data->cond_mutex); - while (!data->amount) { - mongoc_cond_wait (&data->cond, &data->cond_mutex); - } - /* amount is likely negative value now, we've read more then caused the - * original blocker */ - amount += data->amount; - data->amount = 0; - bson_mutex_unlock (&data->cond_mutex); - - do { - r = mongoc_stream_readv (stream, &iov, 1, amount, WAIT); - if (r > 0) { - amount -= r; - } - } while (amount > 0); - ASSERT_CMPINT (0, ==, amount); - - bson_free (buf); - mongoc_stream_destroy (stream); - mongoc_socket_destroy (listen_sock); - - return NULL; -} - - -static void * -sendv_test_client (void *data_) -{ - socket_test_data_t *data = (socket_test_data_t *) data_; - mongoc_socket_t *conn_sock; - ssize_t r; - int i; - int amount = 0; - struct sockaddr_in server_addr = {0}; - mongoc_stream_t *stream; - mongoc_iovec_t iov; - bool done = false; - char *buf = (char *) bson_malloc (gFourMB); - - BSON_ASSERT (gFourMB > 0); - memset (buf, 'a', (gFourMB) -1); - buf[gFourMB - 1] = '\0'; - - iov.iov_base = buf; - iov.iov_len = gFourMB; - - conn_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (conn_sock); - - bson_mutex_lock (&data->cond_mutex); - while (!data->server_port) { - mongoc_cond_wait (&data->cond, &data->cond_mutex); - } - bson_mutex_unlock (&data->cond_mutex); - - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons (data->server_port); - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - - r = mongoc_socket_connect ( - conn_sock, (struct sockaddr *) &server_addr, sizeof (server_addr), -1); - BSON_ASSERT (r == 0); - - stream = mongoc_stream_socket_new (conn_sock); - - for (i = 0; i < 5; i++) { - r = mongoc_stream_writev (stream, &iov, 1, WAIT); - if (r > 0) { - amount += r; - } - if (r != gFourMB) { - if (!done) { - bson_mutex_lock (&data->cond_mutex); - data->amount = amount; - amount = 0; - mongoc_cond_signal (&data->cond); - bson_mutex_unlock (&data->cond_mutex); - done = true; - } - } - } - BSON_ASSERT (true == done); - bson_mutex_lock (&data->cond_mutex); - data->amount = amount; - mongoc_cond_signal (&data->cond); - bson_mutex_unlock (&data->cond_mutex); - - mongoc_stream_destroy (stream); - bson_free (buf); - - return NULL; -} - - -static void -_test_mongoc_socket_check_closed (int32_t server_sleep_ms) -{ - socket_test_data_t data = {0}; - bson_thread_t threads[2]; - int i, r; - - bson_mutex_init (&data.cond_mutex); - mongoc_cond_init (&data.cond); - data.server_sleep_ms = server_sleep_ms; - - r = bson_thread_create (threads, &socket_test_server, &data); - BSON_ASSERT (r == 0); - - r = bson_thread_create (threads + 1, &socket_test_client, &data); - BSON_ASSERT (r == 0); - - for (i = 0; i < 2; i++) { - r = bson_thread_join (threads[i]); - BSON_ASSERT (r == 0); - } - - bson_mutex_destroy (&data.cond_mutex); - mongoc_cond_destroy (&data.cond); -} - - -static void -test_mongoc_socket_check_closed (void) -{ - _test_mongoc_socket_check_closed (0); -} - - -static void -test_mongoc_socket_timed_out (void *ctx) -{ - _test_mongoc_socket_check_closed (1000); -} - - -static void -test_mongoc_socket_sendv (void *ctx) -{ - socket_test_data_t data = {0}; - bson_thread_t threads[2]; - int i, r; - - bson_mutex_init (&data.cond_mutex); - mongoc_cond_init (&data.cond); - - r = bson_thread_create (threads, &sendv_test_server, &data); - BSON_ASSERT (r == 0); - - r = bson_thread_create (threads + 1, &sendv_test_client, &data); - BSON_ASSERT (r == 0); - - for (i = 0; i < 2; i++) { - r = bson_thread_join (threads[i]); - BSON_ASSERT (r == 0); - } - - bson_mutex_destroy (&data.cond_mutex); - mongoc_cond_destroy (&data.cond); -} - -static void -test_mongoc_socket_poll_refusal (void *ctx) -{ - mongoc_stream_poll_t *poller; - mongoc_socket_t *sock; - mongoc_stream_t *ssock; - int64_t start; - - struct sockaddr_in ipv4_addr = {0}; - ipv4_addr.sin_family = AF_INET; - BSON_ASSERT (inet_pton (AF_INET, "127.0.0.1", &ipv4_addr.sin_addr)); - ipv4_addr.sin_port = htons (12345); - - /* create a new non-blocking socket. */ - sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - - (void) mongoc_socket_connect ( - sock, (struct sockaddr *) &ipv4_addr, sizeof (ipv4_addr), 0); - - start = bson_get_monotonic_time (); - - ssock = mongoc_stream_socket_new (sock); - - poller = bson_malloc0 (sizeof (*poller)); - poller->revents = 0; - poller->events = POLLOUT | POLLERR | POLLHUP; - poller->stream = ssock; - - while (bson_get_monotonic_time () - start < 5000 * 1000) { - BSON_ASSERT (mongoc_stream_poll (poller, 1, 10 * 1000) > 0); - if (poller->revents & POLLHUP) { - break; - } - } - - mongoc_stream_destroy (ssock); - bson_free (poller); - -#ifdef _WIN32 - ASSERT_WITHIN_TIME_INTERVAL ( - (int) (bson_get_monotonic_time () - start), 1000 * 500, 1500 * 1000); -#else - ASSERT_WITHIN_TIME_INTERVAL ( - (int) (bson_get_monotonic_time () - start), 0, 500); -#endif -} - -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); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-stream-tls-error.c b/lib/mongoc/libmongoc/tests/test-mongoc-stream-tls-error.c deleted file mode 100644 index 028d01c4c5dcb6dcacbb329c4ab412e900862cd4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-stream-tls-error.c +++ /dev/null @@ -1,405 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-thread-private.h> -#include <mongoc/mongoc-util-private.h> -#include <mongoc/mongoc-stream-tls.h> - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -#include <openssl/err.h> -#endif - -#include "ssl-test.h" -#include "test-conveniences.h" -#include "TestSuite.h" -#include "test-libmongoc.h" - -#define TIMEOUT 10000 /* milliseconds */ - -#if !defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) && \ - !defined(MONGOC_ENABLE_SSL_LIBRESSL) && \ - !defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) -/** run as a child thread by test_mongoc_tls_hangup - * - * It: - * 1. spins up - * 2. binds and listens to a random port - * 3. notifies the client of its port through a condvar - * 4. accepts a request - * 5. reads a byte - * 7. hangs up - */ -static void * -ssl_error_server (void *ptr) -{ - ssl_test_data_t *data = (ssl_test_data_t *) ptr; - - mongoc_stream_t *sock_stream; - mongoc_stream_t *ssl_stream; - mongoc_socket_t *listen_sock; - mongoc_socket_t *conn_sock; - mongoc_socklen_t sock_len; - char buf; - ssize_t r; - mongoc_iovec_t iov; - struct sockaddr_in server_addr = {0}; - bson_error_t error; - - iov.iov_base = &buf; - iov.iov_len = 1; - - listen_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (listen_sock); - - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - server_addr.sin_port = htons (0); - - r = mongoc_socket_bind ( - listen_sock, (struct sockaddr *) &server_addr, sizeof server_addr); - BSON_ASSERT (r == 0); - - sock_len = sizeof (server_addr); - r = mongoc_socket_getsockname ( - listen_sock, (struct sockaddr *) &server_addr, &sock_len); - BSON_ASSERT (r == 0); - - r = mongoc_socket_listen (listen_sock, 10); - BSON_ASSERT (r == 0); - - bson_mutex_lock (&data->cond_mutex); - data->server_port = ntohs (server_addr.sin_port); - mongoc_cond_signal (&data->cond); - bson_mutex_unlock (&data->cond_mutex); - - conn_sock = mongoc_socket_accept (listen_sock, -1); - BSON_ASSERT (conn_sock); - - sock_stream = mongoc_stream_socket_new (conn_sock); - BSON_ASSERT (sock_stream); - - ssl_stream = mongoc_stream_tls_new_with_hostname ( - sock_stream, data->host, data->server, 0); - BSON_ASSERT (ssl_stream); - - switch (data->behavior) { - case SSL_TEST_BEHAVIOR_STALL_BEFORE_HANDSHAKE: - _mongoc_usleep (data->handshake_stall_ms * 1000); - break; - case SSL_TEST_BEHAVIOR_HANGUP_AFTER_HANDSHAKE: - r = mongoc_stream_tls_handshake_block ( - ssl_stream, data->host, TIMEOUT, &error); - BSON_ASSERT (r); - - r = mongoc_stream_readv (ssl_stream, &iov, 1, 1, TIMEOUT); - BSON_ASSERT (r == 1); - break; - case SSL_TEST_BEHAVIOR_NORMAL: - default: - fprintf (stderr, "unimplemented ssl_test_behavior_t\n"); - abort (); - } - - data->server_result->result = SSL_TEST_SUCCESS; - - mongoc_stream_close (ssl_stream); - mongoc_stream_destroy (ssl_stream); - mongoc_socket_destroy (listen_sock); - - return NULL; -} - - -#if !defined(__sun) && !defined(__APPLE__) -/** run as a child thread by test_mongoc_tls_hangup - * - * It: - * 1. spins up - * 2. waits on a condvar until the server is up - * 3. connects to the server's port - * 4. writes a byte - * 5. confirms that the server hangs up promptly - * 6. shuts down - */ -static void * -ssl_hangup_client (void *ptr) -{ - ssl_test_data_t *data = (ssl_test_data_t *) ptr; - mongoc_stream_t *sock_stream; - mongoc_stream_t *ssl_stream; - mongoc_socket_t *conn_sock; - char buf = 'b'; - ssize_t r; - mongoc_iovec_t riov; - mongoc_iovec_t wiov; - struct sockaddr_in server_addr = {0}; - int64_t start_time; - bson_error_t error; - - conn_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); - BSON_ASSERT (conn_sock); - - bson_mutex_lock (&data->cond_mutex); - while (!data->server_port) { - mongoc_cond_wait (&data->cond, &data->cond_mutex); - } - bson_mutex_unlock (&data->cond_mutex); - - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons (data->server_port); - server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - - r = mongoc_socket_connect ( - conn_sock, (struct sockaddr *) &server_addr, sizeof (server_addr), -1); - BSON_ASSERT (r == 0); - - sock_stream = mongoc_stream_socket_new (conn_sock); - BSON_ASSERT (sock_stream); - - ssl_stream = mongoc_stream_tls_new_with_hostname ( - sock_stream, data->host, data->client, 1); - BSON_ASSERT (ssl_stream); - - r = mongoc_stream_tls_handshake_block ( - ssl_stream, data->host, TIMEOUT, &error); - BSON_ASSERT (r); - - wiov.iov_base = (void *) &buf; - wiov.iov_len = 1; - r = mongoc_stream_writev (ssl_stream, &wiov, 1, TIMEOUT); - BSON_ASSERT (r == 1); - - riov.iov_base = (void *) &buf; - riov.iov_len = 1; - - /* we should notice promptly that the server hangs up */ - start_time = bson_get_monotonic_time (); - r = mongoc_stream_readv (ssl_stream, &riov, 1, 1, TIMEOUT); - /* time is in microseconds */ - BSON_ASSERT (bson_get_monotonic_time () - start_time < 1000 * 1000); - BSON_ASSERT (r == -1); - mongoc_stream_destroy (ssl_stream); - data->client_result->result = SSL_TEST_SUCCESS; - return NULL; -} - -static void -test_mongoc_tls_hangup (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - ssl_test_data_t data = {0}; - bson_thread_t threads[2]; - int i, r; - - sopt.pem_file = CERT_SERVER; - sopt.weak_cert_validation = 1; - copt.weak_cert_validation = 1; - - data.server = &sopt; - data.client = &copt; - data.behavior = SSL_TEST_BEHAVIOR_HANGUP_AFTER_HANDSHAKE; - data.server_result = &sr; - data.client_result = &cr; - data.host = "localhost"; - - bson_mutex_init (&data.cond_mutex); - mongoc_cond_init (&data.cond); - - r = bson_thread_create (threads, &ssl_error_server, &data); - BSON_ASSERT (r == 0); - - r = bson_thread_create (threads + 1, &ssl_hangup_client, &data); - BSON_ASSERT (r == 0); - - for (i = 0; i < 2; i++) { - r = bson_thread_join (threads[i]); - BSON_ASSERT (r == 0); - } - - bson_mutex_destroy (&data.cond_mutex); - mongoc_cond_destroy (&data.cond); - - ASSERT (cr.result == SSL_TEST_SUCCESS); - ASSERT (sr.result == SSL_TEST_SUCCESS); -} -#endif - - -/** run as a child thread by test_mongoc_tls_handshake_stall - * - * It: - * 1. spins up - * 2. waits on a condvar until the server is up - * 3. connects to the server's port - * 4. attempts handshake - * 5. confirms that it times out - * 6. shuts down - */ -static void * -handshake_stall_client (void *ptr) -{ - ssl_test_data_t *data = (ssl_test_data_t *) ptr; - char *uri_str; - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - int64_t connect_timeout_ms = data->handshake_stall_ms - 100; - int64_t duration_ms; - - int64_t start_time; - - bson_mutex_lock (&data->cond_mutex); - while (!data->server_port) { - mongoc_cond_wait (&data->cond, &data->cond_mutex); - } - bson_mutex_unlock (&data->cond_mutex); - - /* Note: do not use localhost here. If localhost has both A and AAAA records, - * an attempt to connect to IPv6 occurs first. Most platforms refuse the IPv6 - * attempt immediately, so IPv4 succeeds immediately. Windows is an - * exception, and waits 1 second before refusing: - * https://support.microsoft.com/en-us/help/175523/info-winsock-tcp-connection-performance-to-unused-ports - */ - uri_str = bson_strdup_printf ("mongodb://127.0.0.1:%u/" - "?ssl=true&serverselectiontimeoutms=200&" - "connecttimeoutms=%" PRId64, - data->server_port, - connect_timeout_ms); - - client = mongoc_client_new (uri_str); - mongoc_client_set_ssl_opts (client, data->client); - - /* we should time out after about 200ms */ - start_time = bson_get_monotonic_time (); - mongoc_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &reply, &error); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "socket timeout"); - - /* time is in microseconds */ - duration_ms = (bson_get_monotonic_time () - start_time) / 1000; - - if (llabs (duration_ms - connect_timeout_ms) > 100) { - fprintf (stderr, - "expected timeout after about 200ms, not %" PRId64 "\n", - duration_ms); - abort (); - } - - data->client_result->result = SSL_TEST_SUCCESS; - - bson_destroy (&reply); - mongoc_client_destroy (client); - bson_free (uri_str); - - return NULL; -} - - -/* CDRIVER-2222 this should be reenabled for Apple Secure Transport too */ -#if !defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) -static void -test_mongoc_tls_handshake_stall (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - ssl_test_data_t data = {0}; - bson_thread_t threads[2]; - int i, r; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - sopt.weak_cert_validation = 1; - copt.ca_file = CERT_CA; - copt.weak_cert_validation = 1; - - data.server = &sopt; - data.client = &copt; - data.behavior = SSL_TEST_BEHAVIOR_STALL_BEFORE_HANDSHAKE; - data.handshake_stall_ms = 300; - data.server_result = &sr; - data.client_result = &cr; - data.host = "localhost"; - - bson_mutex_init (&data.cond_mutex); - mongoc_cond_init (&data.cond); - - r = bson_thread_create (threads, &ssl_error_server, &data); - BSON_ASSERT (r == 0); - - r = bson_thread_create (threads + 1, &handshake_stall_client, &data); - BSON_ASSERT (r == 0); - - for (i = 0; i < 2; i++) { - r = bson_thread_join (threads[i]); - BSON_ASSERT (r == 0); - } - - bson_mutex_destroy (&data.cond_mutex); - mongoc_cond_destroy (&data.cond); - - ASSERT (cr.result == SSL_TEST_SUCCESS); - ASSERT (sr.result == SSL_TEST_SUCCESS); -} - -#endif /* !MONGOC_ENABLE_SSL_SECURE_TRANSPORT */ -#endif /* !MONGOC_ENABLE_SSL_SECURE_CHANNEL && !MONGOC_ENABLE_SSL_LIBRESSL */ - -/* TLS stream should be NULL and base stream should still be valid, and error - * messages should be consistent across TLS libs. Until CDRIVER-2844, just - * assert message includes the filename, and handle NULL or non-NULL return. */ -#define TLS_LOAD_ERR(_field) \ - do { \ - (_field) = "badfile"; \ - capture_logs (true); \ - base = mongoc_stream_socket_new ( \ - mongoc_socket_new (AF_INET, SOCK_STREAM, 0)); \ - tls_stream = mongoc_stream_tls_new_with_hostname (base, NULL, &opt, 0); \ - \ - ASSERT_CAPTURED_LOG ( \ - "bad TLS config file", MONGOC_LOG_LEVEL_ERROR, "badfile"); \ - \ - if (tls_stream) { \ - mongoc_stream_destroy (tls_stream); \ - } else { \ - mongoc_stream_destroy (base); \ - } \ - \ - opt.pem_file = opt.ca_file = opt.ca_dir = opt.crl_file = NULL; \ - } while (0) - -static void -test_mongoc_tls_load_files (void) -{ - mongoc_ssl_opt_t opt = {0}; - mongoc_stream_t *base; - mongoc_stream_t *tls_stream = NULL; - - TLS_LOAD_ERR (opt.pem_file); - TLS_LOAD_ERR (opt.ca_file); -} - - -void -test_stream_tls_error_install (TestSuite *suite) -{ -#if !defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) && \ - !defined(MONGOC_ENABLE_SSL_LIBRESSL) -#if !defined(__APPLE__) - TestSuite_Add (suite, "/TLS/hangup", test_mongoc_tls_hangup); -#endif - -/* see CDRIVER-2222 this occasionally stalls for a few 100ms on Mac */ -#if !defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) - TestSuite_Add ( - suite, "/TLS/handshake_stall", test_mongoc_tls_handshake_stall); -#endif -#endif /* !MONGOC_ENABLE_SSL_SECURE_CHANNEL && !MONGOC_ENABLE_SSL_LIBRESSL */ - TestSuite_Add (suite, "/TLS/load_files", test_mongoc_tls_load_files); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-stream-tls.c b/lib/mongoc/libmongoc/tests/test-mongoc-stream-tls.c deleted file mode 100644 index afcc9304060a53afc2e6e146aa3c8ae8da2894d2..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-stream-tls.c +++ /dev/null @@ -1,422 +0,0 @@ -#include <mongoc/mongoc.h> - - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -#include <openssl/err.h> -#endif - -#include "ssl-test.h" -#include "TestSuite.h" -#include "test-libmongoc.h" - -#if !defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) && \ - !defined(MONGOC_ENABLE_SSL_LIBRESSL) - -static void -test_mongoc_tls_no_certs (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - capture_logs (true); - /* No server cert is not valid TLS at all */ - ssl_test (&copt, &sopt, "doesnt_matter", &cr, &sr); - - ASSERT_CMPINT (cr.result, !=, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, !=, SSL_TEST_SUCCESS); -} - - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -static void -test_mongoc_tls_password (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_PASSWORD_PROTECTED; - copt.pem_pwd = CERT_PASSWORD; - - /* Password protected key */ - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - -static void -test_mongoc_tls_bad_password (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_PASSWORD_PROTECTED; - copt.pem_pwd = "incorrect password"; - - - capture_logs (true); - /* Incorrect password cannot unlock the key */ - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SSL_HANDSHAKE); - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SSL_INIT); - - /* Change it to the right password */ - copt.pem_pwd = CERT_PASSWORD; - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} -#endif - - -static void -test_mongoc_tls_no_verify (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - /* Weak cert validation allows never fails */ - copt.weak_cert_validation = 1; - - ssl_test (&copt, &sopt, "bad_domain.com", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -static void -test_mongoc_tls_allow_invalid_hostname (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - copt.allow_invalid_hostname = 1; - - /* Connect to a domain not listed in the cert */ - ssl_test (&copt, &sopt, "bad_domain.com", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -static void -test_mongoc_tls_bad_verify (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - - capture_logs (true); - ssl_test (&copt, &sopt, "bad_domain.com", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SSL_HANDSHAKE); - ASSERT_CMPINT (sr.result, !=, SSL_TEST_SUCCESS); - - - /* weak_cert_validation allows bad domains */ - copt.weak_cert_validation = 1; - ssl_test (&copt, &sopt, "bad_domain.com", &cr, &sr); - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -static void -test_mongoc_tls_basic (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -static void -test_mongoc_tls_weak_cert_validation (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - copt.crl_file = CERT_CRL; - copt.pem_file = CERT_CLIENT; - - capture_logs (true); - /* Certificate has has been revoked, this should fail */ - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SSL_HANDSHAKE); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SSL_HANDSHAKE); - - - /* weak_cert_validation allows revoked certs */ - copt.weak_cert_validation = 1; - ssl_test (&copt, &sopt, "bad_domain.com", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -static void -test_mongoc_tls_crl (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); - - copt.crl_file = CERT_CRL; - capture_logs (true); - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SSL_HANDSHAKE); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SSL_HANDSHAKE); - - /* Weak cert validation allows revoked */ - copt.weak_cert_validation = true; - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} -#endif - - -static void -test_mongoc_tls_expired (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_EXPIRED; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - - capture_logs (true); - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SSL_HANDSHAKE); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SSL_HANDSHAKE); - - /* Weak cert validation allows expired certs */ - copt.weak_cert_validation = true; - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -static void -test_mongoc_tls_common_name (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_COMMONNAME; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - - /* Match against commonName */ - ssl_test (&copt, &sopt, "commonName.mongodb.org", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -static void -test_mongoc_tls_altname (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_ALTNAME; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - - /* Match against secondary Subject Alternative Name (SAN) */ - ssl_test (&copt, &sopt, "alternative.mongodb.com", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -static void -test_mongoc_tls_wild (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_WILD; - - copt.ca_file = CERT_CA; - copt.pem_file = CERT_CLIENT; - - ssl_test (&copt, &sopt, "anything.mongodb.org", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} - - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -static void -test_mongoc_tls_ip (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - copt.ca_file = CERT_CA; - - ssl_test (&copt, &sopt, "127.0.0.1", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} -#endif - - -#if !defined(__APPLE__) && !defined(_WIN32) && \ - defined(MONGOC_ENABLE_SSL_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10000000L -static void -test_mongoc_tls_trust_dir (void) -{ - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; - ssl_test_result_t sr; - ssl_test_result_t cr; - - sopt.pem_file = CERT_SERVER; - sopt.ca_file = CERT_CA; - - copt.ca_dir = CERT_TEST_DIR; - - ssl_test (&copt, &sopt, "localhost", &cr, &sr); - - ASSERT_CMPINT (cr.result, ==, SSL_TEST_SUCCESS); - ASSERT_CMPINT (sr.result, ==, SSL_TEST_SUCCESS); -} -#endif - -#endif /* !MONGOC_ENABLE_SSL_SECURE_CHANNEL && !MONGOC_ENABLE_SSL_LIBRESSL */ - -void -test_stream_tls_install (TestSuite *suite) -{ -#if !defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) && \ - !defined(MONGOC_ENABLE_SSL_LIBRESSL) - TestSuite_Add (suite, "/TLS/commonName", test_mongoc_tls_common_name); - TestSuite_Add (suite, "/TLS/altname", test_mongoc_tls_altname); - TestSuite_Add (suite, "/TLS/basic", test_mongoc_tls_basic); - TestSuite_Add (suite, - "/TLS/allow_invalid_hostname", - test_mongoc_tls_allow_invalid_hostname); - TestSuite_Add (suite, "/TLS/wild", test_mongoc_tls_wild); - TestSuite_Add (suite, "/TLS/no_verify", test_mongoc_tls_no_verify); - TestSuite_Add (suite, "/TLS/bad_verify", test_mongoc_tls_bad_verify); - TestSuite_Add (suite, "/TLS/no_certs", test_mongoc_tls_no_certs); - - TestSuite_Add (suite, "/TLS/expired", test_mongoc_tls_expired); - -#ifdef MONGOC_ENABLE_SSL_OPENSSL - TestSuite_Add (suite, "/TLS/ip", test_mongoc_tls_ip); - TestSuite_Add (suite, "/TLS/password", test_mongoc_tls_password); - TestSuite_Add (suite, "/TLS/bad_password", test_mongoc_tls_bad_password); - TestSuite_Add ( - suite, "/TLS/weak_cert_validation", test_mongoc_tls_weak_cert_validation); - TestSuite_Add (suite, "/TLS/crl", test_mongoc_tls_crl); -#endif - -#if !defined(__APPLE__) && !defined(_WIN32) && \ - defined(MONGOC_ENABLE_SSL_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10000000L - TestSuite_Add (suite, "/TLS/trust_dir", test_mongoc_tls_trust_dir); -#endif -#endif -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-stream.c b/lib/mongoc/libmongoc/tests/test-mongoc-stream.c deleted file mode 100644 index cb89e60eca04fddacda1fd3c22fd09eda00d0ea6..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-stream.c +++ /dev/null @@ -1,170 +0,0 @@ - -#include <fcntl.h> -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-stream-private.h> -#include <stdlib.h> - -#include "TestSuite.h" - - -static void -test_buffered_basic (void) -{ - mongoc_stream_t *stream; - mongoc_stream_t *buffered; - mongoc_iovec_t iov; - ssize_t r; - char buf[16236]; - - stream = - mongoc_stream_file_new_for_path (BINARY_DIR "/reply2.dat", O_RDONLY, 0); - BSON_ASSERT (stream); - - /* buffered assumes ownership of stream */ - buffered = mongoc_stream_buffered_new (stream, 1024); - - /* try to read large chunk larger than buffer. */ - iov.iov_len = sizeof buf; - iov.iov_base = buf; - r = mongoc_stream_readv (buffered, &iov, 1, iov.iov_len, -1); - if (r != iov.iov_len) { - char msg[100]; - - bson_snprintf (msg, - 100, - "Expected %lld got %llu", - (long long) r, - (unsigned long long) iov.iov_len); - ASSERT_CMPSTR (msg, "failed"); - } - - /* cleanup */ - mongoc_stream_destroy (buffered); -} - - -static void -test_buffered_oversized (void) -{ - mongoc_stream_t *stream; - mongoc_stream_t *buffered; - mongoc_iovec_t iov; - ssize_t r; - char buf[16236]; - - stream = - mongoc_stream_file_new_for_path (BINARY_DIR "/reply2.dat", O_RDONLY, 0); - BSON_ASSERT (stream); - - /* buffered assumes ownership of stream */ - buffered = mongoc_stream_buffered_new (stream, 20000); - - /* try to read large chunk larger than buffer. */ - iov.iov_len = sizeof buf; - iov.iov_base = buf; - r = mongoc_stream_readv (buffered, &iov, 1, iov.iov_len, -1); - if (r != iov.iov_len) { - char msg[100]; - - bson_snprintf (msg, - 100, - "Expected %lld got %llu", - (long long) r, - (unsigned long long) iov.iov_len); - ASSERT_CMPSTR (msg, "failed"); - } - - /* cleanup */ - mongoc_stream_destroy (buffered); -} - - -typedef struct { - mongoc_stream_t vtable; - ssize_t rval; -} failing_stream_t; - -static ssize_t -failing_stream_writev (mongoc_stream_t *stream, - mongoc_iovec_t *iov, - size_t iovcnt, - int32_t timeout_msec) -{ - failing_stream_t *fstream = (failing_stream_t *) stream; - - return fstream->rval; -} - -void -failing_stream_destroy (mongoc_stream_t *stream) -{ - bson_free (stream); -} - -static mongoc_stream_t * -failing_stream_new (ssize_t rval) -{ - failing_stream_t *stream; - - stream = bson_malloc0 (sizeof *stream); - stream->vtable.type = 999; - stream->vtable.writev = failing_stream_writev; - stream->vtable.destroy = failing_stream_destroy; - stream->rval = rval; - - return (mongoc_stream_t *) stream; -} - - -static void -test_stream_writev_full (void) -{ - mongoc_stream_t *error_stream = failing_stream_new (-1); - mongoc_stream_t *short_stream = failing_stream_new (10); - mongoc_stream_t *success_stream = failing_stream_new (100); - char bufa[20]; - char bufb[80]; - bool r; - mongoc_iovec_t iov[2]; - bson_error_t error = {0}; - const char *error_message = "Failure during socket delivery: "; - const char *short_message = "Failure to send all requested bytes (only " - "sent: 10/100 in 100ms) during socket delivery"; - - iov[0].iov_base = bufa; - iov[0].iov_len = sizeof (bufa); - iov[1].iov_base = bufb; - iov[1].iov_len = sizeof (bufb); - - errno = EINVAL; - r = _mongoc_stream_writev_full (error_stream, iov, 2, 100, &error); - - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_STREAM); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_STREAM_SOCKET); - ASSERT_STARTSWITH (error.message, error_message); - - errno = 0; - r = _mongoc_stream_writev_full (short_stream, iov, 2, 100, &error); - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_STREAM); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_STREAM_SOCKET); - ASSERT_CMPSTR (error.message, short_message); - - errno = 0; - r = _mongoc_stream_writev_full (success_stream, iov, 2, 100, &error); - BSON_ASSERT (r); - - mongoc_stream_destroy (error_stream); - mongoc_stream_destroy (short_stream); - mongoc_stream_destroy (success_stream); -} - - -void -test_stream_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Stream/buffered/basic", test_buffered_basic); - TestSuite_Add (suite, "/Stream/buffered/oversized", test_buffered_oversized); - TestSuite_Add (suite, "/Stream/writev_full", test_stream_writev_full); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-thread.c b/lib/mongoc/libmongoc/tests/test-mongoc-thread.c deleted file mode 100644 index 12a5357914db0067fa9810b313f053868683e28d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-thread.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "mongoc/mongoc-thread-private.h" - -#include "TestSuite.h" - - -static void -test_cond_wait (void) -{ - int64_t start, duration_usec; - bson_mutex_t mutex; - mongoc_cond_t cond; - - bson_mutex_init (&mutex); - mongoc_cond_init (&cond); - - bson_mutex_lock (&mutex); - start = bson_get_monotonic_time (); - mongoc_cond_timedwait (&cond, &mutex, 100); - duration_usec = bson_get_monotonic_time () - start; - bson_mutex_unlock (&mutex); - - if (!((50 * 1000 < duration_usec) && (150 * 1000 > duration_usec))) { - fprintf ( - stderr, "expected to wait 100ms, waited %" PRId64 "\n", duration_usec); - } - - mongoc_cond_destroy (&cond); - bson_mutex_destroy (&mutex); -} - - -void -test_thread_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Thread/cond_wait", test_cond_wait); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-topology-description.c b/lib/mongoc/libmongoc/tests/test-mongoc-topology-description.c deleted file mode 100644 index dbd659b3464f25322c59dc16313eeec85f72d79d..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-topology-description.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "mongoc/mongoc.h" -#include "mongoc/mongoc-set-private.h" -#include "mongoc/mongoc-client-pool-private.h" -#include "mongoc/mongoc-client-private.h" - -#include "TestSuite.h" -#include "test-libmongoc.h" -#include "test-conveniences.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "topology-test" - -static void -_test_has_readable_writable_server (bool pooled) -{ - mongoc_client_t *client = NULL; - mongoc_client_pool_t *pool = NULL; - mongoc_topology_description_t *td; - mongoc_read_prefs_t *prefs; - bool r; - bson_error_t error; - - if (pooled) { - pool = test_framework_client_pool_new (); - td = &_mongoc_client_pool_get_topology (pool)->description; - } else { - client = test_framework_client_new (); - td = &client->topology->description; - } - - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_read_prefs_set_tags (prefs, tmp_bson ("[{'tag': 'does-not-exist'}]")); - - /* not yet connected */ - ASSERT (!mongoc_topology_description_has_writable_server (td)); - ASSERT (!mongoc_topology_description_has_readable_server (td, NULL)); - ASSERT (!mongoc_topology_description_has_readable_server (td, prefs)); - - /* get a client if necessary, and trigger connection */ - if (pooled) { - client = mongoc_client_pool_pop (pool); - } - - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - ASSERT (mongoc_topology_description_has_writable_server (td)); - ASSERT (mongoc_topology_description_has_readable_server (td, NULL)); - - if (test_framework_is_replset ()) { - /* prefs still don't match any server */ - ASSERT (!mongoc_topology_description_has_readable_server (td, prefs)); - } else { - /* topology type single ignores read preference */ - ASSERT (mongoc_topology_description_has_readable_server (td, prefs)); - } - - mongoc_read_prefs_destroy (prefs); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - - -static void -test_has_readable_writable_server_single (void) -{ - _test_has_readable_writable_server (false); -} - - -static void -test_has_readable_writable_server_pooled (void) -{ - _test_has_readable_writable_server (true); -} - - -static mongoc_server_description_t * -_sd_for_host (mongoc_topology_description_t *td, const char *host) -{ - int i; - mongoc_server_description_t *sd; - - for (i = 0; i < (int) td->servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i); - - if (!strcmp (sd->host.host, host)) { - return sd; - } - } - - return NULL; -} - - -static void -test_get_servers (void) -{ - mongoc_uri_t *uri; - mongoc_topology_t *topology; - mongoc_topology_description_t *td; - mongoc_server_description_t *sd_a; - mongoc_server_description_t *sd_c; - mongoc_server_description_t **sds; - size_t n; - - uri = mongoc_uri_new ("mongodb://a,b,c"); - topology = mongoc_topology_new (uri, true /* single-threaded */); - td = &topology->description; - - /* servers "a" and "c" are mongos, but "b" remains unknown */ - sd_a = _sd_for_host (td, "a"); - mongoc_topology_description_handle_ismaster ( - td, sd_a->id, tmp_bson ("{'ok': 1, 'msg': 'isdbgrid'}"), 100, NULL); - - sd_c = _sd_for_host (td, "c"); - mongoc_topology_description_handle_ismaster ( - td, sd_c->id, tmp_bson ("{'ok': 1, 'msg': 'isdbgrid'}"), 100, NULL); - - sds = mongoc_topology_description_get_servers (td, &n); - ASSERT_CMPSIZE_T ((size_t) 2, ==, n); - - /* we don't care which order the servers are returned */ - if (sds[0]->id == sd_a->id) { - ASSERT_CMPSTR ("a", sds[0]->host.host); - ASSERT_CMPSTR ("c", sds[1]->host.host); - } else { - ASSERT_CMPSTR ("c", sds[0]->host.host); - ASSERT_CMPSTR ("a", sds[1]->host.host); - } - - mongoc_server_descriptions_destroy_all (sds, n); - mongoc_topology_destroy (topology); - mongoc_uri_destroy (uri); -} - - -void -test_topology_description_install (TestSuite *suite) -{ - TestSuite_AddLive (suite, - "/TopologyDescription/readable_writable/single", - test_has_readable_writable_server_single); - TestSuite_AddLive (suite, - "/TopologyDescription/readable_writable/pooled", - test_has_readable_writable_server_pooled); - TestSuite_Add (suite, "/TopologyDescription/get_servers", test_get_servers); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-topology-reconcile.c b/lib/mongoc/libmongoc/tests/test-mongoc-topology-reconcile.c deleted file mode 100644 index d8c46f4bc585d34670b5376b50486b474b0c8889..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-topology-reconcile.c +++ /dev/null @@ -1,754 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-client-pool-private.h" -#include "mongoc/mongoc-util-private.h" -#include "mongoc/utlist.h" - -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "mock_server/mock-server.h" -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "topology-reconcile-test" - - -static mongoc_topology_scanner_node_t * -get_node (mongoc_topology_t *topology, const char *host_and_port) -{ - mongoc_topology_scanner_t *ts; - mongoc_topology_scanner_node_t *node; - mongoc_topology_scanner_node_t *sought = NULL; - - bson_mutex_lock (&topology->mutex); - - ts = topology->scanner; - - DL_FOREACH (ts->nodes, node) - { - if (!strcmp (host_and_port, node->host.host_and_port)) { - sought = node; - break; - } - } - - bson_mutex_unlock (&topology->mutex); - - return sought; -} - - -static bool -has_server_description (mongoc_topology_t *topology, const char *host_and_port) -{ - mongoc_set_t *servers = topology->description.servers; - bool found = false; - int i; - mongoc_server_description_t *sd; - - bson_mutex_lock (&topology->mutex); - for (i = 0; i < (int) topology->description.servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (servers, i); - if (!strcmp (sd->host.host_and_port, host_and_port)) { - found = true; - break; - } - } - - bson_mutex_unlock (&topology->mutex); - - return found; -} - - -bool -selects_server (mongoc_client_t *client, - mongoc_read_prefs_t *read_prefs, - mock_server_t *server) -{ - bson_error_t error; - mongoc_server_description_t *sd; - bool result; - - sd = mongoc_topology_select ( - client->topology, MONGOC_SS_READ, read_prefs, &error); - - if (!sd) { - fprintf (stderr, "%s\n", error.message); - return false; - } - - result = (0 == strcmp (mongoc_server_description_host (sd)->host_and_port, - mock_server_get_host_and_port (server))); - - mongoc_server_description_destroy (sd); - - return result; -} - - -static void -_test_topology_reconcile_rs (bool pooled) -{ - mock_server_t *server0; - mock_server_t *server1; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - debug_stream_stats_t debug_stream_stats = {0}; - mongoc_read_prefs_t *secondary_read_prefs; - mongoc_read_prefs_t *primary_read_prefs; - mongoc_read_prefs_t *tag_read_prefs; - - server0 = mock_server_new (); - server1 = mock_server_new (); - mock_server_run (server0); - mock_server_run (server1); - - /* secondary, no tags */ - RS_RESPONSE_TO_ISMASTER (server0, 6, false, false, server0, server1); - /* primary, no tags */ - RS_RESPONSE_TO_ISMASTER (server1, 6, true, false, server0, server1); - - /* provide secondary in seed list */ - uri_str = bson_strdup_printf ("mongodb://%s/?replicaSet=rs", - mock_server_get_host_and_port (server0)); - - uri = mongoc_uri_new (uri_str); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new (uri_str); - } - - if (!pooled) { - test_framework_set_debug_stream (client, &debug_stream_stats); - } - - secondary_read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - primary_read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - tag_read_prefs = mongoc_read_prefs_new (MONGOC_READ_NEAREST); - mongoc_read_prefs_add_tag (tag_read_prefs, tmp_bson ("{'key': 'value'}")); - - /* - * server0 is selected, server1 is discovered and added to scanner. - */ - BSON_ASSERT (selects_server (client, secondary_read_prefs, server0)); - BSON_ASSERT ( - get_node (client->topology, mock_server_get_host_and_port (server1))); - - /* - * select again with mode "primary": server1 is selected. - */ - BSON_ASSERT (selects_server (client, primary_read_prefs, server1)); - - /* - * remove server1 from set. server0 is the primary, with tags. - */ - RS_RESPONSE_TO_ISMASTER ( - server0, 6, true, true, server0); /* server1 absent */ - - BSON_ASSERT (selects_server (client, tag_read_prefs, server0)); - BSON_ASSERT (!client->topology->stale); - - if (!pooled) { - ASSERT_CMPINT (1, ==, debug_stream_stats.n_failed); - } - - /* - * server1 returns as a secondary. its scanner node is un-retired. - */ - RS_RESPONSE_TO_ISMASTER (server0, 6, true, true, server0, server1); - RS_RESPONSE_TO_ISMASTER (server1, 6, false, false, server0, server1); - - BSON_ASSERT (selects_server (client, secondary_read_prefs, server1)); - - if (!pooled) { - /* no additional failed streams */ - ASSERT_CMPINT (1, ==, debug_stream_stats.n_failed); - } - - mongoc_read_prefs_destroy (primary_read_prefs); - mongoc_read_prefs_destroy (secondary_read_prefs); - mongoc_read_prefs_destroy (tag_read_prefs); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); - bson_free (uri_str); - mock_server_destroy (server1); - mock_server_destroy (server0); -} - - -static void -test_topology_reconcile_rs_single (void) -{ - _test_topology_reconcile_rs (false); -} - - -static void -test_topology_reconcile_rs_pooled (void) -{ - _test_topology_reconcile_rs (true); -} - - -static void -_test_topology_reconcile_sharded (bool pooled) -{ - mock_server_t *mongos; - mock_server_t *secondary; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_read_prefs_t *primary_read_prefs; - bson_error_t error; - future_t *future; - request_t *request; - char *secondary_response; - mongoc_server_description_t *sd; - - mongos = mock_server_new (); - secondary = mock_server_new (); - mock_server_run (mongos); - mock_server_run (secondary); - - /* provide both servers in seed list */ - uri_str = bson_strdup_printf ("mongodb://%s,%s", - mock_server_get_host_and_port (mongos), - mock_server_get_host_and_port (secondary)); - - uri = mongoc_uri_new (uri_str); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new (uri_str); - } - - primary_read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_read_prefs, &error); - - /* mongos */ - request = mock_server_receives_ismaster (mongos); - mock_server_replies_simple (request, - "{'ok': 1, 'ismaster': true, 'minWireVersion': " - "2, 'maxWireVersion': 5, 'msg': 'isdbgrid'}"); - - request_destroy (request); - - /* make sure the mongos response is processed first */ - _mongoc_usleep (1000 * 1000); - - /* replica set secondary - topology removes it */ - request = mock_server_receives_ismaster (secondary); - secondary_response = - bson_strdup_printf ("{'ok': 1, " - " 'setName': 'rs'," - " 'ismaster': false," - " 'secondary': true," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s', '%s']" - "}", - mock_server_get_host_and_port (mongos), - mock_server_get_host_and_port (secondary)); - - mock_server_replies_simple (request, secondary_response); - - request_destroy (request); - - /* - * mongos is selected, secondary is removed. - */ - sd = future_get_mongoc_server_description_ptr (future); - ASSERT_CMPSTR (sd->host.host_and_port, - mock_server_get_host_and_port (mongos)); - - if (pooled) { - /* wait a second for scanner thread to remove secondary */ - int64_t start = bson_get_monotonic_time (); - while (get_node (client->topology, - mock_server_get_host_and_port (secondary))) { - ASSERT_CMPTIME ((int) (bson_get_monotonic_time () - start), - (int) 1000000); - } - } else { - BSON_ASSERT (!get_node (client->topology, - mock_server_get_host_and_port (secondary))); - } - - mongoc_server_description_destroy (sd); - bson_free (secondary_response); - mongoc_read_prefs_destroy (primary_read_prefs); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - future_destroy (future); - mongoc_uri_destroy (uri); - bson_free (uri_str); - mock_server_destroy (secondary); - mock_server_destroy (mongos); -} - - -static void -test_topology_reconcile_sharded_single (void) -{ - _test_topology_reconcile_sharded (false); -} - - -static void -test_topology_reconcile_sharded_pooled (void) -{ - _test_topology_reconcile_sharded (true); -} - - -typedef struct { - bson_mutex_t mutex; - size_t servers; -} reconcile_test_data_t; - - -static void -server_opening (const mongoc_apm_server_opening_t *event) -{ - reconcile_test_data_t *data = (reconcile_test_data_t *) event->context; - - bson_mutex_lock (&data->mutex); - data->servers++; - bson_mutex_unlock (&data->mutex); -} - - -static void -test_topology_reconcile_from_handshake (void *ctx) -{ - reconcile_test_data_t data; - mongoc_apm_callbacks_t *callbacks; - char *host_and_port; - char *replset_name; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool; - mongoc_topology_t *topology; - mongoc_client_t *client; - bool r; - bson_error_t error; - int count; - mongoc_topology_scanner_node_t *node; - mongoc_async_cmd_t *cmd; - - bson_mutex_init (&data.mutex); - data.servers = 0; - - callbacks = mongoc_apm_callbacks_new (); - - /* single seed - not the full test_framework_get_uri */ - host_and_port = test_framework_get_host_and_port (); - replset_name = test_framework_replset_name (); - uri_str = bson_strdup_printf ( - "mongodb://%s/?replicaSet=%s", host_and_port, replset_name); - - uri = mongoc_uri_new (uri_str); - pool = mongoc_client_pool_new (uri); - mongoc_apm_set_server_opening_cb (callbacks, server_opening); - mongoc_client_pool_set_apm_callbacks (pool, callbacks, &data); - test_framework_set_pool_ssl_opts (pool); - - /* make the bg thread lose the data race: prevent it starting by pretending - * it already has */ - topology = _mongoc_client_pool_get_topology (pool); - topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_BG_RUNNING; - - /* ordinarily would start bg thread */ - client = mongoc_client_pool_pop (pool); - - /* command in the foreground (ismaster, just because it doesn't need auth) */ - r = mongoc_client_read_command_with_opts (client, - "admin", - tmp_bson ("{'ismaster': 1}"), - NULL, - tmp_bson ("{'serverId': 1}"), - NULL, - &error); - - ASSERT_OR_PRINT (r, error); - - /* added server descriptions */ - ASSERT_CMPSIZE_T (topology->description.servers->items_len, >, (size_t) 1); - - /* didn't add nodes yet, since we're not in the scanner loop */ - DL_COUNT (topology->scanner->nodes, node, count); - ASSERT_CMPINT (count, ==, 1); - - /* if CDRIVER-2073 isn't fixed, then when we discovered the other replicas - * during the handshake, we also created mongoc_async_cmd_t's for them - */ - DL_COUNT (topology->scanner->async->cmds, cmd, count); - ASSERT_CMPINT (count, ==, 0); - - /* allow pool to start scanner thread */ - topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_OFF; - mongoc_client_pool_push (pool, client); - client = mongoc_client_pool_pop (pool); - - /* no serverId, waits for topology scan */ - r = mongoc_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ismaster': 1}"), NULL, NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - bson_mutex_lock (&data.mutex); - ASSERT_CMPSIZE_T (data.servers, ==, test_framework_replset_member_count ()); - bson_mutex_unlock (&data.mutex); - - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - mongoc_apm_callbacks_destroy (callbacks); - mongoc_uri_destroy (uri); - bson_free (uri_str); - bson_free (replset_name); - bson_free (host_and_port); -} - - -/* CDRIVER-2552 in mongoc_topology_scanner_node_setup, assert (!node->retired) - * failed after this sequence in pooled mode: - * - * 1. scanner discovers a replica set with primary and at least one secondary - * 2. cluster opens a new stream to the primary - * 3. cluster handshakes the new connection by calling isMaster on the primary - * 4. the primary, for some reason, suddenly omits the secondary from its host - * list, perhaps because the secondary was removed from the RS configuration - * 5. scanner marks the secondary scanner node "retired" to be destroyed later - * 6. the scanner is disconnected from the secondary for some reason - * 7. on the next scan, mongoc_topology_scanner_node_setup sees that the - * secondary is disconnected, and before creating a new stream it asserts - * !node->retired. - * - * test that between step 5 and 7, mongoc_topology_scanner_reset destroys the - * secondary node, avoiding the assert failure. test both pooled and single - * mode for good measure. - */ -static void -_test_topology_reconcile_retire (bool pooled) -{ - mock_server_t *secondary; - mock_server_t *primary; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_topology_t *topology; - mongoc_read_prefs_t *primary_read_prefs; - mongoc_read_prefs_t *secondary_read_prefs; - mongoc_read_prefs_t *tag_read_prefs; - mongoc_topology_scanner_node_t *node; - bson_error_t error; - future_t *future; - request_t *request; - - secondary = mock_server_new (); - primary = mock_server_new (); - mock_server_run (secondary); - mock_server_run (primary); - - RS_RESPONSE_TO_ISMASTER (primary, 6, true, false, secondary, primary); - RS_RESPONSE_TO_ISMASTER (secondary, 6, false, false, secondary, primary); - - /* selection timeout must be > MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS, - * otherwise we skip second scan in pooled mode and don't hit the assert */ - uri_str = bson_strdup_printf ( - "mongodb://%s,%s/?replicaSet=rs" - "&serverSelectionTimeoutMS=600&heartbeatFrequencyMS=999999999", - mock_server_get_host_and_port (primary), - mock_server_get_host_and_port (secondary)); - - uri = mongoc_uri_new (uri_str); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - topology = _mongoc_client_pool_get_topology (pool); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new (uri_str); - topology = client->topology; - } - - /* step 1: discover both replica set members */ - primary_read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - BSON_ASSERT (selects_server (client, primary_read_prefs, primary)); - secondary_read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - BSON_ASSERT (selects_server (client, secondary_read_prefs, secondary)); - - /* remove secondary from primary's config */ - bson_mutex_lock (&topology->mutex); - RS_RESPONSE_TO_ISMASTER (primary, 6, true, false, primary); - - /* step 2: cluster opens new stream to primary - force new stream in single - * mode by disconnecting scanner nodes (also includes step 6) */ - DL_FOREACH (topology->scanner->nodes, node) - { - BSON_ASSERT (node); - BSON_ASSERT (node->stream); - mongoc_stream_destroy (node->stream); - node->stream = NULL; - } - bson_mutex_unlock (&topology->mutex); - - /* step 3: run "ping" on primary, triggering a connection and handshake, thus - * step 4 & 5: the primary tells the scanner to retire the secondary node */ - future = future_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, &error); - request = mock_server_receives_msg ( - primary, MONGOC_QUERY_NONE, tmp_bson ("{'ping': 1}")); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - - BSON_ASSERT (!has_server_description ( - topology, mock_server_get_host_and_port (secondary))); - - /* server removed from topology description. in pooled mode, the scanner node - * is untouched, in single mode mongoc_cluster_fetch_stream_single scans and - * updates topology */ - node = get_node (topology, mock_server_get_host_and_port (secondary)); - if (pooled) { - BSON_ASSERT (node); - BSON_ASSERT (!node->retired); - } else { - BSON_ASSERT (!node); - } - - /* step 7: trigger a scan by selecting with an unsatisfiable read preference. - * should not crash with BSON_ASSERT. */ - tag_read_prefs = mongoc_read_prefs_new (MONGOC_READ_NEAREST); - mongoc_read_prefs_add_tag (tag_read_prefs, tmp_bson ("{'key': 'value'}")); - BSON_ASSERT ( - !mongoc_client_select_server (client, false, tag_read_prefs, NULL)); - - BSON_ASSERT ( - !get_node (topology, mock_server_get_host_and_port (secondary))); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - future_destroy (future); - mock_server_destroy (primary); - mock_server_destroy (secondary); - mongoc_read_prefs_destroy (primary_read_prefs); - mongoc_read_prefs_destroy (secondary_read_prefs); - mongoc_read_prefs_destroy (tag_read_prefs); - mongoc_uri_destroy (uri); - bson_free (uri_str); -} - - -static void -test_topology_reconcile_retire_single (void) -{ - _test_topology_reconcile_retire (false); -} - - -static void -test_topology_reconcile_retire_pooled (void) -{ - _test_topology_reconcile_retire (true); -} - - -/* CDRIVER-2552 in mongoc_topology_scanner_start, assert (!node->cmd) - * failed after this sequence in libmongoc 1.6.0: - * - * 1. scanner discovers a replica set with primary - * 2. cluster opens a new stream to the primary - * 3. cluster handshakes the new connection by calling isMaster on the primary - * 4. the primary suddenly includes a new secondary in its host list, perhaps - * because the secondary was added - * 5. _mongoc_topology_update_from_handshake adds the secondary to the topology - * and erroneously creates a scanner node with an async_cmd_t for it, - * although it's not in the scanner loop - * 6. on the next mongoc_topology_scanner_start, assert (!node->cmd) fails - * - * test that in step 5 the new node has no new async_cmd_t - */ -static void -_test_topology_reconcile_add (bool pooled) -{ - mock_server_t *secondary; - mock_server_t *primary; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - mongoc_topology_t *topology; - mongoc_read_prefs_t *primary_read_prefs; - mongoc_topology_scanner_node_t *node; - bson_error_t error; - future_t *future; - request_t *request; - - secondary = mock_server_new (); - primary = mock_server_new (); - mock_server_run (secondary); - mock_server_run (primary); - - /* omit secondary from primary's ismaster, to start with */ - RS_RESPONSE_TO_ISMASTER (primary, 6, true, false, primary); - RS_RESPONSE_TO_ISMASTER (secondary, 6, false, false, secondary, primary); - - /* selection timeout must be > MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS, - * otherwise we skip second scan in pooled mode and don't hit the assert */ - uri_str = bson_strdup_printf ( - "mongodb://%s,%s/?replicaSet=rs" - "&serverSelectionTimeoutMS=600&heartbeatFrequencyMS=999999999", - mock_server_get_host_and_port (primary), - mock_server_get_host_and_port (secondary)); - - uri = mongoc_uri_new (uri_str); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - topology = _mongoc_client_pool_get_topology (pool); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new (uri_str); - topology = client->topology; - } - - /* step 1: discover primary */ - primary_read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - BSON_ASSERT (selects_server (client, primary_read_prefs, primary)); - - /* add secondary to primary's config */ - RS_RESPONSE_TO_ISMASTER (primary, 6, true, false, primary, secondary); - - /* step 2: cluster opens new stream to primary - force new stream in single - * mode by disconnecting primary scanner node */ - node = get_node (topology, mock_server_get_host_and_port (primary)); - BSON_ASSERT (node); - BSON_ASSERT (node->stream); - mongoc_stream_destroy (node->stream); - node->stream = NULL; - - /* step 3: run "ping" on primary, triggering a connection and handshake, thus - * step 4 & 5: we add the secondary to the topology description */ - future = future_client_read_command_with_opts ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, NULL, &error); - request = mock_server_receives_msg ( - primary, MONGOC_QUERY_NONE, tmp_bson ("{'ping': 1}")); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - - /* added server description */ - BSON_ASSERT (has_server_description ( - topology, mock_server_get_host_and_port (secondary))); - - node = get_node (topology, mock_server_get_host_and_port (secondary)); - if (pooled) { - /* no asymc_cmd_t is created, since we're not in the scanner loop */ - BSON_ASSERT (!topology->scanner->async->cmds); - BSON_ASSERT (!node); - } else { - /* in single mode the client completes a scan inline and frees all cmds */ - BSON_ASSERT (!topology->scanner->async->cmds); - BSON_ASSERT (node); - } - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - future_destroy (future); - mock_server_destroy (primary); - mock_server_destroy (secondary); - mongoc_read_prefs_destroy (primary_read_prefs); - mongoc_uri_destroy (uri); - bson_free (uri_str); -} - - -static void -test_topology_reconcile_add_single (void) -{ - _test_topology_reconcile_add (false); -} - - -static void -test_topology_reconcile_add_pooled (void) -{ - _test_topology_reconcile_add (true); -} - - -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/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", - test_topology_reconcile_from_handshake, - NULL, - NULL, - test_framework_skip_if_not_replset); - TestSuite_AddMockServerTest (suite, - "/TOPOLOGY/reconcile/retire/pooled", - test_topology_reconcile_retire_pooled, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/TOPOLOGY/reconcile/retire/single", - test_topology_reconcile_retire_single, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/TOPOLOGY/reconcile/add/pooled", - test_topology_reconcile_add_pooled, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/TOPOLOGY/reconcile/add/single", - test_topology_reconcile_add_single, - test_framework_skip_if_slow); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-topology-scanner.c b/lib/mongoc/libmongoc/tests/test-mongoc-topology-scanner.c deleted file mode 100644 index 1ac07f788b2796c40fe81f22f9bec328eae2e3e4..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-topology-scanner.c +++ /dev/null @@ -1,748 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-stream-private.h> -#include <mongoc/mongoc-socket-private.h> -#include <mongoc/mongoc-host-list-private.h> -#include <mongoc/utlist.h> - -#include "mongoc/mongoc-util-private.h" -#include "mongoc/mongoc-client-private.h" - -#include "TestSuite.h" -#include "mock_server/mock-server.h" -#include "mock_server/mock-rs.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "topology-scanner-test" - -#define TIMEOUT 20000 /* milliseconds */ -#define NSERVERS 10 - -static void -test_topology_scanner_helper (uint32_t id, - const bson_t *bson, - int64_t rtt_msec, - void *data, - const bson_error_t *error /* IN */) -{ - bson_iter_t iter; - int *finished = (int *) data; - uint32_t max_wire_version; - - if (error->code) { - fprintf (stderr, "scanner error: %s\n", error->message); - abort (); - } - - /* mock servers are configured to return distinct wire versions */ - BSON_ASSERT (bson); - BSON_ASSERT (bson_iter_init_find (&iter, bson, "maxWireVersion")); - BSON_ASSERT (BSON_ITER_HOLDS_INT32 (&iter)); - max_wire_version = (uint32_t) bson_iter_int32 (&iter); - ASSERT_CMPINT (max_wire_version, ==, id + WIRE_VERSION_MIN); - - (*finished)--; -} - -static void -_test_topology_scanner (bool with_ssl) -{ - mock_server_t *servers[NSERVERS]; - mongoc_topology_scanner_t *topology_scanner; - int i; - bson_t q = BSON_INITIALIZER; - int finished = NSERVERS * 3; - -#ifdef MONGOC_ENABLE_SSL - mongoc_ssl_opt_t sopt = {0}; - mongoc_ssl_opt_t copt = {0}; -#endif - - topology_scanner = mongoc_topology_scanner_new ( - NULL, NULL, &test_topology_scanner_helper, &finished, TIMEOUT); - -#ifdef MONGOC_ENABLE_SSL - if (with_ssl) { - copt.ca_file = CERT_CA; - copt.weak_cert_validation = 1; - - mongoc_topology_scanner_set_ssl_opts (topology_scanner, &copt); - } -#endif - - for (i = 0; i < NSERVERS; i++) { - /* use max wire versions just to distinguish among responses */ - servers[i] = mock_server_with_autoismaster (i + WIRE_VERSION_MIN); - mock_server_set_rand_delay (servers[i], true); - -#ifdef MONGOC_ENABLE_SSL - if (with_ssl) { - sopt.ca_file = CERT_CA; - sopt.pem_file = CERT_SERVER; - - mock_server_set_ssl_opts (servers[i], &sopt); - } -#endif - - mock_server_run (servers[i]); - - mongoc_topology_scanner_add ( - topology_scanner, - mongoc_uri_get_hosts (mock_server_get_uri (servers[i])), - (uint32_t) i); - } - - for (i = 0; i < 3; i++) { - mongoc_topology_scanner_start (topology_scanner, false); - mongoc_topology_scanner_work (topology_scanner); - } - - BSON_ASSERT (finished == 0); - - mongoc_topology_scanner_destroy (topology_scanner); - - bson_destroy (&q); - - for (i = 0; i < NSERVERS; i++) { - mock_server_destroy (servers[i]); - } -} - - -void -test_topology_scanner (void) -{ - _test_topology_scanner (false); -} - - -#ifdef MONGOC_ENABLE_SSL_OPENSSL -void -test_topology_scanner_ssl (void) -{ - _test_topology_scanner (true); -} -#endif - - -/* - * Servers discovered by a scan should be checked during that scan, CDRIVER-751. - */ -void -test_topology_scanner_discovery (void) -{ - mock_server_t *primary; - mock_server_t *secondary; - char *primary_response; - char *secondary_response; - mongoc_client_t *client; - char *uri_str; - mongoc_read_prefs_t *secondary_pref; - bson_error_t error; - future_t *future; - request_t *request; - mongoc_server_description_t *sd; - - primary = mock_server_new (); - secondary = mock_server_new (); - mock_server_run (primary); - mock_server_run (secondary); - - primary_response = - bson_strdup_printf ("{'ok': 1, " - " 'ismaster': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s', '%s']}", - mock_server_get_host_and_port (primary), - mock_server_get_host_and_port (secondary)); - - secondary_response = - bson_strdup_printf ("{'ok': 1, " - " 'ismaster': false," - " 'secondary': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s', '%s']}", - mock_server_get_host_and_port (primary), - mock_server_get_host_and_port (secondary)); - - uri_str = bson_strdup_printf ("mongodb://%s/?" MONGOC_URI_REPLICASET "=rs", - mock_server_get_host_and_port (primary)); - client = mongoc_client_new (uri_str); - secondary_pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY_PREFERRED); - - future = future_topology_select ( - client->topology, MONGOC_SS_READ, secondary_pref, &error); - - /* a single scan discovers *and* checks the secondary */ - request = mock_server_receives_ismaster (primary); - mock_server_replies_simple (request, primary_response); - request_destroy (request); - - /* let client process that response */ - _mongoc_usleep (250 * 1000); - - /* a check of the secondary is scheduled in this scan */ - request = mock_server_receives_ismaster (secondary); - mock_server_replies_simple (request, secondary_response); - - /* scan completes */ - ASSERT_OR_PRINT ((sd = future_get_mongoc_server_description_ptr (future)), - error); - - ASSERT_CMPSTR (sd->host.host_and_port, - mock_server_get_host_and_port (secondary)); - - mongoc_server_description_destroy (sd); - future_destroy (future); - request_destroy (request); - mongoc_read_prefs_destroy (secondary_pref); - bson_free (secondary_response); - bson_free (primary_response); - bson_free (uri_str); - mongoc_client_destroy (client); - mock_server_destroy (secondary); - mock_server_destroy (primary); -} - - -/* scanner shouldn't spin if two primaries point at each other */ -void -test_topology_scanner_oscillate (void) -{ - mock_server_t *server0; - mock_server_t *server1; - char *server0_response; - char *server1_response; - mongoc_client_t *client; - mongoc_topology_scanner_t *scanner; - char *uri_str; - mongoc_read_prefs_t *primary_pref; - bson_error_t error; - future_t *future; - request_t *request; - - server0 = mock_server_new (); - server1 = mock_server_new (); - mock_server_run (server0); - mock_server_run (server1); - - /* server 0 says it's primary, but only server 1 is in the set */ - server0_response = - bson_strdup_printf ("{'ok': 1, " - " 'ismaster': true," - " 'setName': 'rs'," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server1)); - - /* the opposite */ - server1_response = - bson_strdup_printf ("{'ok': 1, " - " 'ismaster': true," - " 'setName': 'rs'," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server0)); - - /* start with server 0 */ - uri_str = bson_strdup_printf ("mongodb://%s/?" MONGOC_URI_REPLICASET "=rs", - mock_server_get_host_and_port (server0)); - client = mongoc_client_new (uri_str); - scanner = client->topology->scanner; - primary_pref = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - BSON_ASSERT (!scanner->async->ncmds); - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - - /* a single scan discovers servers 0 and 1 */ - request = mock_server_receives_ismaster (server0); - mock_server_replies_simple (request, server0_response); - request_destroy (request); - - /* let client process that response */ - _mongoc_usleep (250 * 1000); - - request = mock_server_receives_ismaster (server1); - mock_server_replies_simple (request, server1_response); - - /* we don't schedule another check of server0 */ - _mongoc_usleep (250 * 1000); - - BSON_ASSERT (!future_get_mongoc_server_description_ptr (future)); - BSON_ASSERT (scanner->async->ncmds == 0); - - future_destroy (future); - request_destroy (request); - mongoc_read_prefs_destroy (primary_pref); - bson_free (server1_response); - bson_free (server0_response); - bson_free (uri_str); - mongoc_client_destroy (client); - mock_server_destroy (server1); - mock_server_destroy (server0); -} - - -void -test_topology_scanner_connection_error (void) -{ - mongoc_client_t *client; - bson_error_t error; - - /* assuming nothing is listening on this port */ - client = mongoc_client_new ("mongodb://localhost:9876"); - - ASSERT (!mongoc_client_command_simple ( - client, "db", tmp_bson ("{'foo': 1}"), NULL, NULL, &error)); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "connection refused calling ismaster on " - "'localhost:9876'"); - - mongoc_client_destroy (client); -} - - -void -test_topology_scanner_socket_timeout (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_uri_t *uri; - bson_error_t error; - char *expected_msg; - - server = mock_server_new (); - mock_server_run (server); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_CONNECTTIMEOUTMS, 10); - client = mongoc_client_new_from_uri (uri); - - ASSERT (!mongoc_client_command_simple ( - client, "db", tmp_bson ("{'foo': 1}"), NULL, NULL, &error)); - - /* the mock server did accept connection, but never replied */ - expected_msg = - bson_strdup_printf ("socket timeout calling ismaster on '%s'", - mongoc_uri_get_hosts (uri)->host_and_port); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - expected_msg); - - bson_free (expected_msg); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -typedef struct { - uint16_t slow_port; - mongoc_client_t *client; -} initiator_data_t; - - -static mongoc_stream_t * -slow_initiator (const mongoc_uri_t *uri, - const mongoc_host_list_t *host, - void *user_data, - bson_error_t *err) -{ - initiator_data_t *data; - - data = (initiator_data_t *) user_data; - - if (host->port == data->slow_port) { - _mongoc_usleep (500 * 1000); /* 500 ms is longer than connectTimeoutMS */ - } - - return mongoc_client_default_stream_initiator (uri, host, data->client, err); -} - - -static void -test_topology_scanner_blocking_initiator (void) -{ - mock_rs_t *rs; - mongoc_uri_t *uri; - mongoc_client_t *client; - initiator_data_t data; - bson_error_t error; - - rs = mock_rs_with_autoismaster (WIRE_VERSION_MIN, /* wire version */ - true, /* has primary */ - 1, /* n_secondaries */ - 0 /* n_arbiters */); - - mock_rs_run (rs); - uri = mongoc_uri_copy (mock_rs_get_uri (rs)); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_CONNECTTIMEOUTMS, 100); - client = mongoc_client_new_from_uri (uri); - - /* pretend last host in linked list is slow */ - data.slow_port = mongoc_uri_get_hosts (uri)->next->port; - data.client = client; - mongoc_client_set_stream_initiator (client, slow_initiator, &data); - - ASSERT_OR_PRINT ( - mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ismaster': 1}"), NULL, NULL, &error), - error); - - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_rs_destroy (rs); -} - -static mock_server_t * -_mock_server_listening_on (char *server_bind_to) -{ - mock_server_t *mock_server; - mock_server_bind_opts_t opts = {0}; - struct sockaddr_in ipv4_addr = {0}; - struct sockaddr_in6 ipv6_addr = {0}; - - if (strcmp ("both", server_bind_to) == 0) { - opts.bind_addr_len = sizeof (ipv6_addr); - opts.family = AF_INET6; - opts.ipv6_only = 0; - ipv6_addr.sin6_family = AF_INET6; - ipv6_addr.sin6_port = htons (0); /* any port */ - ipv6_addr.sin6_addr = in6addr_any; /* either IPv4 or IPv6 */ - opts.bind_addr = (struct sockaddr_in *) &ipv6_addr; - } else if (strcmp ("ipv4", server_bind_to) == 0) { - opts.bind_addr_len = sizeof (ipv4_addr); - opts.family = AF_INET; - opts.ipv6_only = 0; - ipv4_addr.sin_family = AF_INET; - ipv4_addr.sin_port = htons (0); - BSON_ASSERT (inet_pton (AF_INET, "127.0.0.1", &ipv4_addr.sin_addr)); - opts.bind_addr = &ipv4_addr; - } else if (strcmp ("ipv6", server_bind_to) == 0) { - opts.bind_addr_len = sizeof (ipv6_addr); - opts.family = AF_INET6; - opts.ipv6_only = 1; - ipv6_addr.sin6_family = AF_INET6; - ipv6_addr.sin6_port = htons (0); - BSON_ASSERT (inet_pton (AF_INET6, "::1", &ipv6_addr.sin6_addr)); - opts.bind_addr = (struct sockaddr_in *) &ipv6_addr; - } else { - fprintf (stderr, "bad value of server_bind_to=%s\n", server_bind_to); - ASSERT (false); - } - mock_server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG); - mock_server_set_bind_opts (mock_server, &opts); - mock_server_run (mock_server); - return mock_server; -} - -typedef struct dns_testcase { - char *server_bind_to; /* ipv4, ipv6, or both */ - char *client_hostname; /* 127.0.0.1, [::1], or localhost */ - bool should_succeed; - int expected_ncmds; - char *expected_client_bind_to; /* ipv4, ipv6, or either */ -} dns_testcase_t; - -static void -_test_topology_scanner_dns_helper (uint32_t id, - const bson_t *bson, - int64_t rtt_msec, - void *data, - const bson_error_t *error /* IN */) -{ - dns_testcase_t *testcase = (dns_testcase_t *) data; - if (testcase->should_succeed) { - ASSERT_OR_PRINT (!error->code, (*error)); - } else { - ASSERT (error->code); - ASSERT_ERROR_CONTAINS ((*error), - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_CONNECT, - "connection refused"); - } -} - -static void -test_topology_scanner_dns_testcase (dns_testcase_t *testcase) -{ - mongoc_host_list_t host; - mock_server_t *server; - mongoc_topology_scanner_t *ts; - char *host_str; - mongoc_socket_t *sock; - mongoc_topology_scanner_node_t *node; - - server = _mock_server_listening_on (testcase->server_bind_to); - ts = mongoc_topology_scanner_new ( - NULL, NULL, &_test_topology_scanner_dns_helper, testcase, TIMEOUT); - host_str = bson_strdup_printf ( - "%s:%d", testcase->client_hostname, mock_server_get_port (server)); - BSON_ASSERT (_mongoc_host_list_from_string (&host, host_str)); - /* we should only have one host. */ - BSON_ASSERT (!host.next); - bson_free (host_str); - - mongoc_topology_scanner_add (ts, &host, 1); - mongoc_topology_scanner_scan (ts, 1 /* any server id is ok. */); - ASSERT_CMPINT ((int) (ts->async->ncmds), ==, testcase->expected_ncmds); - mongoc_topology_scanner_work (ts); - node = mongoc_topology_scanner_get_node (ts, 1); - - /* check the socket that the scanner found. */ - if (testcase->should_succeed) { - ASSERT (node->stream->type == MONGOC_STREAM_SOCKET); - sock = mongoc_stream_socket_get_socket ( - (mongoc_stream_socket_t *) node->stream); - if (strcmp ("ipv4", testcase->expected_client_bind_to) == 0) { - ASSERT (sock->domain == AF_INET); - } else if (strcmp ("ipv6", testcase->expected_client_bind_to) == 0) { - ASSERT (sock->domain == AF_INET6); - } else if (strcmp ("either", testcase->expected_client_bind_to) != 0) { - fprintf (stderr, - "bad value for testcase->expected_client_bind_to=%s\n", - testcase->expected_client_bind_to); - ASSERT (false); - } - } - - mongoc_topology_scanner_destroy (ts); - mock_server_destroy (server); -} - -/* test when clients try connecting to servers varying the DNS results of the - * clients and the socket binding of the server. */ -static void -test_topology_scanner_dns (void) -{ - /* server can bind to: {ipv4 only, ipv6 only, both} - * client can connect to: {127.0.0.1, ::1, localhost} - * there are 9 combinations. */ - int ntests, i; - dns_testcase_t tests[] = {{"ipv4", "127.0.0.1", true, 1, "ipv4"}, - {"ipv4", "[::1]", false, 1, "n/a"}, - {"ipv6", "127.0.0.1", false, 1, "n/a"}, - {"ipv6", "[::1]", true, 1, "ipv6"}, - {"both", "127.0.0.1", true, 1, "ipv4"}, - {"both", "[::1]", true, 1, "ipv6"}}; - /* these tests require a hostname mapping to both IPv4 and IPv6 local. - * this can be localhost normally, but some configurations may have localhost - * only mapping to 127.0.0.1, not ::1. */ - dns_testcase_t tests_with_ipv4_and_ipv6_uri[] = { - {"ipv4", "<placeholder>", true, 2, "ipv4"}, - {"ipv6", "<placeholder>", true, 2, "ipv6"}, - {"both", "<placeholder>", true, 2, "either"}}; - char *ipv4_and_ipv6_host = - test_framework_getenv ("MONGOC_TEST_IPV4_AND_IPV6_HOST"); - - ntests = sizeof (tests) / sizeof (dns_testcase_t); - for (i = 0; i < ntests; ++i) { - test_topology_scanner_dns_testcase (tests + i); - } - - if (ipv4_and_ipv6_host) { - ntests = sizeof (tests_with_ipv4_and_ipv6_uri) / sizeof (dns_testcase_t); - for (i = 0; i < ntests; ++i) { - tests_with_ipv4_and_ipv6_uri[i].client_hostname = ipv4_and_ipv6_host; - test_topology_scanner_dns_testcase (tests_with_ipv4_and_ipv6_uri + i); - } - bson_free (ipv4_and_ipv6_host); - } -} - -static void -_retired_fails_to_initiate_cb (uint32_t id, - const bson_t *bson, - int64_t rtt_msec, - void *data, - const bson_error_t *error /* IN */) -{ - /* this should never get called. */ - BSON_ASSERT (false); -} - -static mongoc_stream_t * -null_initiator (mongoc_async_cmd_t *acmd) -{ - return NULL; -} - -/* test when a retired node fails to initiate a stream. CDRIVER-1972 introduced - * a bug in which the topology callback would be incorrectly called when a - * retired node failed to establish a connection. - */ -static void -test_topology_retired_fails_to_initiate (void) -{ - mock_server_t *server; - mongoc_topology_scanner_t *scanner; - mongoc_async_cmd_t *acmd; - mongoc_host_list_t host_list; - - server = mock_server_with_autoismaster (WIRE_VERSION_MAX); - mock_server_run (server); - - scanner = mongoc_topology_scanner_new ( - NULL, NULL, &_retired_fails_to_initiate_cb, NULL, TIMEOUT); - - BSON_ASSERT (_mongoc_host_list_from_string (&host_list, - mock_server_get_host_and_port (server))); - - mongoc_topology_scanner_add (scanner, &host_list, 1); - mongoc_topology_scanner_start (scanner, false); - BSON_ASSERT (scanner->async->ncmds > 0); - /* retire the node */ - scanner->nodes->retired = true; - /* override the stream initiator of every async command, simulating - * a failed mongoc_socket_new or mongoc_stream_connect. */ - DL_FOREACH (scanner->async->cmds, acmd) - { - scanner->async->cmds->initiator = null_initiator; - } - - mongoc_topology_scanner_work (scanner); - /* we expect the scanner callback not to get called. */ - - mongoc_topology_scanner_destroy (scanner); - mock_server_destroy (server); -} - -static void -heartbeat_failed (const mongoc_apm_server_heartbeat_failed_t *event) -{ - bson_error_t error; - bool *failed = - (bool *) mongoc_apm_server_heartbeat_failed_get_context (event); - - mongoc_apm_server_heartbeat_failed_get_error (event, &error); - - fprintf (stderr, "heartbeat failed: %s\n", error.message); - fflush (stderr); - - *failed = true; -} - -/* CDRIVER-2624: due to a bug, we repeated the TLS handshake on each heartbeat, - * causing some MongoDB versions to hang up */ -static void -_test_topology_scanner_does_not_renegotiate (bool pooled) -{ - mongoc_uri_t *uri; - mongoc_apm_callbacks_t *callbacks; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bool failed = false; - bool r; - bson_error_t error; - - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500); - /* faster pool shutdown to make the test quick */ - mongoc_uri_set_option_as_int32 (uri, "connectTimeoutMS", 1000); - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_server_heartbeat_failed_cb (callbacks, heartbeat_failed); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - test_framework_set_pool_ssl_opts (pool); - mongoc_client_pool_set_apm_callbacks (pool, callbacks, &failed); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - mongoc_client_set_apm_callbacks (client, callbacks, &failed); - test_framework_set_ssl_opts (client); - } - - /* ensure connection */ - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - _mongoc_usleep (1500 * 1000); /* 1.5 seconds */ - - r = mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - ASSERT_OR_PRINT (r, error); - - /* no heartbeats failed */ - BSON_ASSERT (!failed); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_uri_destroy (uri); - mongoc_apm_callbacks_destroy (callbacks); -} - -static void -test_topology_scanner_does_not_renegotiate_single (void *ctx) -{ - _test_topology_scanner_does_not_renegotiate (false); -} - -static void -test_topology_scanner_does_not_renegotiate_pooled (void *ctx) -{ - _test_topology_scanner_does_not_renegotiate (true); -} - -void -test_topology_scanner_install (TestSuite *suite) -{ - TestSuite_AddMockServerTest ( - suite, "/TOPOLOGY/scanner", test_topology_scanner); -#ifdef MONGOC_ENABLE_SSL_OPENSSL - TestSuite_AddMockServerTest ( - suite, "/TOPOLOGY/scanner_ssl", test_topology_scanner_ssl); -#endif - TestSuite_AddMockServerTest ( - suite, "/TOPOLOGY/scanner_discovery", test_topology_scanner_discovery); - TestSuite_AddMockServerTest ( - suite, "/TOPOLOGY/scanner_oscillate", test_topology_scanner_oscillate); - TestSuite_Add (suite, - "/TOPOLOGY/scanner_connection_error", - test_topology_scanner_connection_error); - TestSuite_AddMockServerTest (suite, - "/TOPOLOGY/scanner_socket_timeout", - test_topology_scanner_socket_timeout); - TestSuite_AddMockServerTest (suite, - "/TOPOLOGY/blocking_initiator", - test_topology_scanner_blocking_initiator); - TestSuite_AddMockServerTest (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", - test_topology_scanner_does_not_renegotiate_single, - NULL, - NULL, - test_framework_skip_if_slow_or_live, - test_framework_skip_if_valgrind); - TestSuite_AddFull (suite, - "/TOPOLOGY/scanner/renegotiate/pooled", - test_topology_scanner_does_not_renegotiate_pooled, - NULL, - NULL, - test_framework_skip_if_slow_or_live, - test_framework_skip_if_valgrind); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-topology.c b/lib/mongoc/libmongoc/tests/test-mongoc-topology.c deleted file mode 100644 index c0fc5f4840988c922549b68a2fa5545a5da34b52..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-topology.c +++ /dev/null @@ -1,2138 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-uri-private.h> -#include <mongoc/mongoc-client-pool-private.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-util-private.h" -#include "TestSuite.h" - -#include "test-libmongoc.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "test-conveniences.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "topology-test" - - -static void -test_topology_client_creation (void) -{ - mongoc_uri_t *uri; - mongoc_topology_scanner_node_t *node; - mongoc_topology_t *topology_a; - mongoc_topology_t *topology_b; - mongoc_client_t *client_a; - mongoc_client_t *client_b; - mongoc_stream_t *topology_stream; - mongoc_server_stream_t *server_stream; - bson_error_t error; - - uri = test_framework_get_uri (); - mongoc_uri_set_option_as_int32 (uri, "localThresholdMS", 42); - mongoc_uri_set_option_as_int32 (uri, "connectTimeoutMS", 12345); - mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 54321); - - /* create two clients directly */ - client_a = mongoc_client_new_from_uri (uri); - client_b = mongoc_client_new_from_uri (uri); - BSON_ASSERT (client_a); - BSON_ASSERT (client_b); - -#ifdef MONGOC_ENABLE_SSL - test_framework_set_ssl_opts (client_a); - test_framework_set_ssl_opts (client_b); -#endif - - /* ensure that they are using different topologies */ - topology_a = client_a->topology; - topology_b = client_b->topology; - BSON_ASSERT (topology_a); - BSON_ASSERT (topology_b); - BSON_ASSERT (topology_a != topology_b); - - BSON_ASSERT (topology_a->local_threshold_msec == 42); - BSON_ASSERT (topology_a->connect_timeout_msec == 12345); - BSON_ASSERT (topology_a->server_selection_timeout_msec == 54321); - - /* ensure that their topologies are running in single-threaded mode */ - BSON_ASSERT (topology_a->single_threaded); - BSON_ASSERT (topology_a->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF); - - /* ensure that we are sharing streams with the client */ - server_stream = mongoc_cluster_stream_for_reads ( - &client_a->cluster, NULL, NULL, NULL, &error); - - ASSERT_OR_PRINT (server_stream, error); - node = mongoc_topology_scanner_get_node (client_a->topology->scanner, - server_stream->sd->id); - BSON_ASSERT (node); - topology_stream = node->stream; - BSON_ASSERT (topology_stream); - BSON_ASSERT (topology_stream == server_stream->stream); - - mongoc_server_stream_cleanup (server_stream); - mongoc_client_destroy (client_a); - mongoc_client_destroy (client_b); - mongoc_uri_destroy (uri); -} - -static void -assert_topology_state (mongoc_topology_t *topology, - mongoc_topology_scanner_state_t state) -{ - ASSERT (topology); - - bson_mutex_lock (&topology->mutex); - ASSERT (topology->scanner_state == state); - bson_mutex_unlock (&topology->mutex); -} - -static void -test_topology_thread_start_stop (void) -{ - mongoc_client_pool_t *pool; - mongoc_topology_t *topology; - - pool = test_framework_client_pool_new (); - topology = _mongoc_client_pool_get_topology (pool); - - /* Test starting up the scanner */ - ASSERT (_mongoc_topology_start_background_scanner (topology)); - assert_topology_state (topology, MONGOC_TOPOLOGY_SCANNER_BG_RUNNING); - - /* Test that starting the topology while it is already - running is ok to do. */ - ASSERT (_mongoc_topology_start_background_scanner (topology)); - assert_topology_state (topology, MONGOC_TOPOLOGY_SCANNER_BG_RUNNING); - - /* Test that we can stop the topology */ - _mongoc_topology_background_thread_stop (topology); - assert_topology_state (topology, MONGOC_TOPOLOGY_SCANNER_OFF); - - /* Test that stopping the topology when it is already - stopped is ok to do. */ - _mongoc_topology_background_thread_stop (topology); - assert_topology_state (topology, MONGOC_TOPOLOGY_SCANNER_OFF); - - /* Test that we can start the topology again after stopping it */ - ASSERT (_mongoc_topology_start_background_scanner (topology)); - assert_topology_state (topology, MONGOC_TOPOLOGY_SCANNER_BG_RUNNING); - - mongoc_client_pool_destroy (pool); -} - -static void -test_topology_client_pool_creation (void) -{ - mongoc_client_pool_t *pool; - mongoc_client_t *client_a; - mongoc_client_t *client_b; - mongoc_topology_t *topology_a; - mongoc_topology_t *topology_b; - - /* create two clients through a client pool */ - pool = test_framework_client_pool_new (); - client_a = mongoc_client_pool_pop (pool); - client_b = mongoc_client_pool_pop (pool); - BSON_ASSERT (client_a); - BSON_ASSERT (client_b); - - /* ensure that they are using the same topology */ - topology_a = client_a->topology; - topology_b = client_b->topology; - BSON_ASSERT (topology_a); - BSON_ASSERT (topology_a == topology_b); - - /* ensure that this topology is running in a background thread */ - BSON_ASSERT (!topology_a->single_threaded); - BSON_ASSERT (topology_a->scanner_state != MONGOC_TOPOLOGY_SCANNER_OFF); - - mongoc_client_pool_push (pool, client_a); - mongoc_client_pool_push (pool, client_b); - mongoc_client_pool_destroy (pool); -} - -static void -test_server_selection_try_once_option (void *ctx) -{ - const char *uri_strings[3] = {"mongodb://a", - "mongodb://a/?serverSelectionTryOnce=true", - "mongodb://a/?serverSelectionTryOnce=false"}; - - unsigned long i; - mongoc_client_t *client; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool; - - /* try_once is on by default for non-pooled, can be turned off */ - client = mongoc_client_new (uri_strings[0]); - BSON_ASSERT (client->topology->server_selection_try_once); - mongoc_client_destroy (client); - - client = mongoc_client_new (uri_strings[1]); - BSON_ASSERT (client->topology->server_selection_try_once); - mongoc_client_destroy (client); - - client = mongoc_client_new (uri_strings[2]); - BSON_ASSERT (!client->topology->server_selection_try_once); - mongoc_client_destroy (client); - - /* off for pooled clients, can't be enabled */ - for (i = 0; i < sizeof (uri_strings) / sizeof (char *); i++) { - uri = mongoc_uri_new ("mongodb://a"); - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - BSON_ASSERT (!client->topology->server_selection_try_once); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); - } -} - -static void -_test_server_selection (bool try_once) -{ - mock_server_t *server; - char *secondary_response; - char *primary_response; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_read_prefs_t *primary_pref; - future_t *future; - bson_error_t error; - request_t *request; - mongoc_server_description_t *sd; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - server = mock_server_new (); - mock_server_run (server); - - secondary_response = - bson_strdup_printf ("{'ok': 1, " - " 'ismaster': false," - " 'secondary': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - primary_response = - bson_strdup_printf ("{'ok': 1, " - " 'ismaster': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500); - mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 100); - if (!try_once) { - /* serverSelectionTryOnce is on by default */ - mongoc_uri_set_option_as_bool (uri, "serverSelectionTryOnce", false); - } - - client = mongoc_client_new_from_uri (uri); - primary_pref = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - /* no primary, selection fails after one try */ - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - request = mock_server_receives_ismaster (server); - BSON_ASSERT (request); - mock_server_replies_simple (request, secondary_response); - request_destroy (request); - - /* the selection timeout is 100 ms, and we can't rescan until a half second - * passes, so selection fails without another ismaster call */ - mock_server_set_request_timeout_msec (server, 600); - BSON_ASSERT (!mock_server_receives_ismaster (server)); - mock_server_set_request_timeout_msec (server, get_future_timeout_ms ()); - - /* selection fails */ - BSON_ASSERT (!future_get_mongoc_server_description_ptr (future)); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER_SELECTION); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_SERVER_SELECTION_FAILURE); - ASSERT_STARTSWITH (error.message, "No suitable servers found"); - - if (try_once) { - ASSERT_CONTAINS (error.message, "serverSelectionTryOnce"); - } else { - ASSERT_CONTAINS (error.message, "serverselectiontimeoutms"); - } - - BSON_ASSERT (client->topology->stale); - future_destroy (future); - - _mongoc_usleep (510 * 1000); /* one heartbeat, plus a few milliseconds */ - - /* second selection, now we try ismaster again */ - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - request = mock_server_receives_ismaster (server); - BSON_ASSERT (request); - - /* the secondary is now primary, selection succeeds */ - mock_server_replies_simple (request, primary_response); - sd = future_get_mongoc_server_description_ptr (future); - BSON_ASSERT (sd); - BSON_ASSERT (!client->topology->stale); - request_destroy (request); - future_destroy (future); - - mongoc_server_description_destroy (sd); - mongoc_read_prefs_destroy (primary_pref); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - bson_free (secondary_response); - bson_free (primary_response); - mock_server_destroy (server); -} - -static void -test_server_selection_try_once (void *ctx) -{ - _test_server_selection (true); -} - -static void -test_server_selection_try_once_false (void *ctx) -{ - _test_server_selection (false); -} - -static void -host_list_init (mongoc_host_list_t *host_list, - int family, - const char *host, - uint16_t port) -{ - memset (host_list, 0, sizeof *host_list); - host_list->family = family; - bson_snprintf (host_list->host, sizeof host_list->host, "%s", host); - bson_snprintf (host_list->host_and_port, - sizeof host_list->host_and_port, - "%s:%hu", - host, - port); -} - -static void -_test_topology_invalidate_server (bool pooled) -{ - mongoc_server_description_t *fake_sd; - mongoc_server_description_t *sd; - mongoc_topology_description_t *td; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_client_pool_t *pool = NULL; - bson_error_t error; - mongoc_host_list_t fake_host_list; - uint32_t fake_id = 42; - uint32_t id; - mongoc_server_stream_t *server_stream; - - uri = test_framework_get_uri (); - /* no auto heartbeat */ - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", INT32_MAX); - mongoc_uri_set_option_as_int32 (uri, "connectTimeoutMS", 2000); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - test_framework_set_pool_ssl_opts (pool); - client = mongoc_client_pool_pop (pool); - - /* background scanner complains about failed connection */ - capture_logs (true); - } else { - client = mongoc_client_new_from_uri (uri); - test_framework_set_ssl_opts (client); - } - - td = &client->topology->description; - - /* call explicitly */ - server_stream = mongoc_cluster_stream_for_reads ( - &client->cluster, NULL, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - sd = server_stream->sd; - id = server_stream->sd->id; - BSON_ASSERT (sd->type == MONGOC_SERVER_STANDALONE || - sd->type == MONGOC_SERVER_RS_PRIMARY || - sd->type == MONGOC_SERVER_MONGOS); - - ASSERT_CMPINT64 (sd->round_trip_time_msec, !=, (int64_t) -1); - - bson_set_error ( - &error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "error"); - mongoc_topology_invalidate_server (client->topology, id, &error); - sd = (mongoc_server_description_t *) mongoc_set_get (td->servers, id); - BSON_ASSERT (sd); - BSON_ASSERT (sd->type == MONGOC_SERVER_UNKNOWN); - ASSERT_CMPINT64 (sd->round_trip_time_msec, ==, (int64_t) -1); - - fake_sd = (mongoc_server_description_t *) bson_malloc0 (sizeof (*fake_sd)); - - /* insert a 'fake' server description and ensure that it is invalidated by - * driver */ - host_list_init (&fake_host_list, AF_INET, "fakeaddress", 27033); - mongoc_server_description_init ( - fake_sd, fake_host_list.host_and_port, fake_id); - - fake_sd->type = MONGOC_SERVER_STANDALONE; - mongoc_set_add (td->servers, fake_id, fake_sd); - mongoc_topology_scanner_add ( - client->topology->scanner, &fake_host_list, fake_id); - BSON_ASSERT (!mongoc_cluster_stream_for_server ( - &client->cluster, fake_id, true, NULL, NULL, &error)); - bson_mutex_lock (&client->topology->mutex); - sd = (mongoc_server_description_t *) mongoc_set_get (td->servers, fake_id); - if (!pooled && test_framework_is_replset ()) { - BSON_ASSERT (!sd); - } else { - BSON_ASSERT (sd); - BSON_ASSERT (sd->type == MONGOC_SERVER_UNKNOWN); - BSON_ASSERT (sd->error.domain != 0); - ASSERT_CMPINT64 (sd->round_trip_time_msec, ==, (int64_t) -1); - BSON_ASSERT (bson_empty (&sd->last_is_master)); - BSON_ASSERT (bson_empty (&sd->hosts)); - BSON_ASSERT (bson_empty (&sd->passives)); - BSON_ASSERT (bson_empty (&sd->arbiters)); - BSON_ASSERT (bson_empty (&sd->compressors)); - } - bson_mutex_unlock (&client->topology->mutex); - - mongoc_server_stream_cleanup (server_stream); - mongoc_uri_destroy (uri); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } -} - -static void -test_topology_invalidate_server_single (void *ctx) -{ - _test_topology_invalidate_server (false); -} - -static void -test_topology_invalidate_server_pooled (void *ctx) -{ - _test_topology_invalidate_server (true); -} - -static void -test_invalid_cluster_node (void *ctx) -{ - mongoc_client_pool_t *pool; - mongoc_cluster_node_t *cluster_node; - mongoc_topology_scanner_node_t *scanner_node; - bson_error_t error; - mongoc_client_t *client; - mongoc_cluster_t *cluster; - mongoc_server_stream_t *server_stream; - int64_t scanner_node_ts; - uint32_t id; - - /* use client pool, this test is only valid when multi-threaded */ - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - cluster = &client->cluster; - - _mongoc_usleep (100 * 1000); - - /* load stream into cluster */ - server_stream = mongoc_cluster_stream_for_reads ( - &client->cluster, NULL, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - id = server_stream->sd->id; - mongoc_server_stream_cleanup (server_stream); - - cluster_node = (mongoc_cluster_node_t *) mongoc_set_get (cluster->nodes, id); - BSON_ASSERT (cluster_node); - BSON_ASSERT (cluster_node->stream); - - bson_mutex_lock (&client->topology->mutex); - scanner_node = - mongoc_topology_scanner_get_node (client->topology->scanner, id); - BSON_ASSERT (scanner_node); - ASSERT_CMPINT64 (cluster_node->timestamp, >, scanner_node->timestamp); - - /* update the scanner node's timestamp */ - _mongoc_usleep (1000 * 1000); - scanner_node_ts = scanner_node->timestamp = bson_get_monotonic_time (); - ASSERT_CMPINT64 (cluster_node->timestamp, <, scanner_node_ts); - _mongoc_usleep (1000 * 1000); - bson_mutex_unlock (&client->topology->mutex); - - /* cluster discards node and creates new one */ - server_stream = mongoc_cluster_stream_for_server ( - &client->cluster, id, true, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - cluster_node = (mongoc_cluster_node_t *) mongoc_set_get (cluster->nodes, id); - ASSERT_CMPINT64 (cluster_node->timestamp, >, scanner_node_ts); - - mongoc_server_stream_cleanup (server_stream); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); -} - -static void -test_max_wire_version_race_condition (void *ctx) -{ - mongoc_topology_scanner_node_t *scanner_node; - mongoc_server_description_t *sd; - mongoc_database_t *database; - mongoc_client_pool_t *pool; - mongoc_client_t *client; - bson_error_t error; - mongoc_server_stream_t *server_stream; - uint32_t id; - bool r; - - /* connect directly and add our user, test is only valid with auth */ - client = test_framework_client_new (); - database = mongoc_client_get_database (client, "test"); - (void) mongoc_database_remove_user (database, "pink", &error); - - r = mongoc_database_add_user (database, - "pink", - "panther", - tmp_bson ("[{'role': 'read', 'db': 'test'}]"), - NULL, - &error); - - ASSERT_OR_PRINT (r, error); - mongoc_database_destroy (database); - mongoc_client_destroy (client); - - /* use client pool, test is only valid when multi-threaded */ - pool = test_framework_client_pool_new (); - client = mongoc_client_pool_pop (pool); - - /* load stream into cluster */ - server_stream = mongoc_cluster_stream_for_reads ( - &client->cluster, NULL, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - id = server_stream->sd->id; - mongoc_server_stream_cleanup (server_stream); - - /* "disconnect": invalidate timestamp and reset server description */ - scanner_node = - mongoc_topology_scanner_get_node (client->topology->scanner, id); - BSON_ASSERT (scanner_node); - scanner_node->timestamp = bson_get_monotonic_time (); - sd = (mongoc_server_description_t *) mongoc_set_get ( - client->topology->description.servers, id); - BSON_ASSERT (sd); - mongoc_server_description_reset (sd); - - /* new stream, ensure that we can still auth with cached wire version */ - server_stream = mongoc_cluster_stream_for_server ( - &client->cluster, id, true, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - BSON_ASSERT (server_stream); - - mongoc_server_stream_cleanup (server_stream); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); -} - - -static void -test_cooldown_standalone (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_read_prefs_t *primary_pref; - future_t *future; - bson_error_t error; - request_t *request; - mongoc_server_description_t *sd; - int64_t start; - - server = mock_server_new (); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - primary_pref = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - /* first ismaster fails, selection fails */ - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - request = mock_server_receives_ismaster (server); - BSON_ASSERT (request); - mock_server_hangs_up (request); - BSON_ASSERT (!future_get_mongoc_server_description_ptr (future)); - request_destroy (request); - future_destroy (future); - - /* second selection doesn't try to call ismaster: we're in cooldown */ - start = bson_get_monotonic_time (); - sd = mongoc_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - BSON_ASSERT (!sd); - /* waited less than 500ms (minHeartbeatFrequencyMS), in fact - * didn't wait at all since all nodes are in cooldown */ - ASSERT_CMPINT64 (bson_get_monotonic_time () - start, <, (int64_t) 500000); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "No servers yet eligible for rescan"); - - _mongoc_usleep (1000 * 1000); /* 1 second */ - - /* third selection doesn't try to call ismaster: we're still in cooldown */ - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - mock_server_set_request_timeout_msec (server, 100); - BSON_ASSERT (!mock_server_receives_ismaster (server)); /* no ismaster call */ - BSON_ASSERT (!future_get_mongoc_server_description_ptr (future)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_SERVER_SELECTION, - MONGOC_ERROR_SERVER_SELECTION_FAILURE, - "No suitable servers"); - - future_destroy (future); - mock_server_set_request_timeout_msec (server, get_future_timeout_ms ()); - - _mongoc_usleep (5100 * 1000); /* 5.1 seconds */ - - /* cooldown ends, now we try ismaster again, this time succeeding */ - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - request = mock_server_receives_ismaster (server); /* not in cooldown now */ - BSON_ASSERT (request); - mock_server_replies_simple ( - request, - "{'ok': 1, 'ismaster': true, 'minWireVersion': 2, 'maxWireVersion': 5 }"); - sd = future_get_mongoc_server_description_ptr (future); - BSON_ASSERT (sd); - request_destroy (request); - future_destroy (future); - - mongoc_server_description_destroy (sd); - mongoc_read_prefs_destroy (primary_pref); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_cooldown_rs (void) -{ - mock_server_t *servers[2]; /* two secondaries, no primary */ - char *uri_str; - int i; - mongoc_client_t *client; - mongoc_read_prefs_t *primary_pref; - char *secondary_response; - char *primary_response; - future_t *future; - bson_error_t error; - request_t *request; - mongoc_server_description_t *sd; - - for (i = 0; i < 2; i++) { - servers[i] = mock_server_new (); - mock_server_run (servers[i]); - } - - uri_str = bson_strdup_printf ("mongodb://localhost:%hu/?replicaSet=rs" - "&serverSelectionTimeoutMS=100" - "&connectTimeoutMS=100", - mock_server_get_port (servers[0])); - - client = mongoc_client_new (uri_str); - primary_pref = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - secondary_response = bson_strdup_printf ( - "{'ok': 1, 'ismaster': false, 'minWireVersion': 2, 'maxWireVersion': 5 , " - "'secondary': true, 'setName': 'rs'," - " 'hosts': ['localhost:%hu', 'localhost:%hu']}", - mock_server_get_port (servers[0]), - mock_server_get_port (servers[1])); - - primary_response = - bson_strdup_printf ("{'ok': 1, 'ismaster': true, 'minWireVersion': 2, " - "'maxWireVersion': 5 , 'setName': 'rs'," - " 'hosts': ['localhost:%hu']}", - mock_server_get_port (servers[1])); - - /* server 0 is a secondary. */ - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - - request = mock_server_receives_ismaster (servers[0]); - BSON_ASSERT (request); - mock_server_replies_simple (request, secondary_response); - request_destroy (request); - - /* server 0 told us about server 1. we check it immediately but it's down. */ - request = mock_server_receives_ismaster (servers[1]); - BSON_ASSERT (request); - mock_server_hangs_up (request); - request_destroy (request); - - /* selection fails. */ - BSON_ASSERT (!future_get_mongoc_server_description_ptr (future)); - future_destroy (future); - - _mongoc_usleep (1000 * 1000); /* 1 second */ - - /* second selection doesn't try ismaster on server 1: it's in cooldown */ - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - - request = mock_server_receives_ismaster (servers[0]); - BSON_ASSERT (request); - mock_server_replies_simple (request, secondary_response); - request_destroy (request); - - mock_server_set_request_timeout_msec (servers[1], 100); - BSON_ASSERT ( - !mock_server_receives_ismaster (servers[1])); /* no ismaster call */ - mock_server_set_request_timeout_msec (servers[1], get_future_timeout_ms ()); - - /* still no primary */ - BSON_ASSERT (!future_get_mongoc_server_description_ptr (future)); - future_destroy (future); - - _mongoc_usleep (5100 * 1000); /* 5.1 seconds. longer than 5 sec cooldown. */ - - /* cooldown ends, now we try ismaster on server 1, this time succeeding */ - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - - request = mock_server_receives_ismaster (servers[1]); - BSON_ASSERT (request); - mock_server_replies_simple (request, primary_response); - request_destroy (request); - - /* server 0 doesn't need to respond */ - sd = future_get_mongoc_server_description_ptr (future); - BSON_ASSERT (sd); - future_destroy (future); - - mongoc_server_description_destroy (sd); - mongoc_read_prefs_destroy (primary_pref); - mongoc_client_destroy (client); - bson_free (secondary_response); - bson_free (primary_response); - bson_free (uri_str); - mock_server_destroy (servers[0]); - mock_server_destroy (servers[1]); -} - - -/* test single-threaded client's cooldown with serverSelectionTryOnce false */ -static void -test_cooldown_retry (void) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_read_prefs_t *primary_pref; - future_t *future; - bson_error_t error; - request_t *request; - mongoc_server_description_t *sd; - int64_t start; - int64_t duration; - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_bool (uri, "serverSelectionTryOnce", false); - client = mongoc_client_new_from_uri (uri); - primary_pref = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - future = future_topology_select ( - client->topology, MONGOC_SS_READ, primary_pref, &error); - - /* first ismaster fails */ - request = mock_server_receives_ismaster (server); - BSON_ASSERT (request); - mock_server_hangs_up (request); - request_destroy (request); - - /* after cooldown passes, driver sends another ismaster */ - start = bson_get_monotonic_time (); - request = mock_server_receives_ismaster (server); - BSON_ASSERT (request); - duration = bson_get_monotonic_time () - start; - /* waited at least cooldownMS, but not unreasonably longer than that */ - ASSERT_CMPINT64 (duration, >, (int64_t) 5 * 1000 * 1000); - ASSERT_CMPINT64 (duration, <, (int64_t) 10 * 1000 * 1000); - - mock_server_replies_simple ( - request, - "{'ok': 1, 'ismaster': true, 'minWireVersion': 2, 'maxWireVersion': 5 }"); - sd = future_get_mongoc_server_description_ptr (future); - ASSERT_OR_PRINT (sd, error); - request_destroy (request); - future_destroy (future); - - mongoc_server_description_destroy (sd); - mongoc_read_prefs_destroy (primary_pref); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -static void -_test_select_succeed (bool try_once) -{ - const int32_t connect_timeout_ms = 200; - - mock_server_t *primary; - mock_server_t *secondary; - mongoc_server_description_t *sd; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_t *client; - future_t *future; - int64_t start; - bson_error_t error; - int64_t duration_usec; - - primary = mock_server_new (); - mock_server_run (primary); - - secondary = mock_server_new (); - mock_server_run (secondary); - - /* Note: do not use localhost here. If localhost has both A and AAAA records, - * an attempt to connect to IPv6 occurs first. Most platforms refuse the IPv6 - * attempt immediately, so IPv4 succeeds immediately. Windows is an - * exception, and waits 1 second before refusing: - * https://support.microsoft.com/en-us/help/175523/info-winsock-tcp-connection-performance-to-unused-ports - */ - /* primary auto-responds, secondary never responds */ - mock_server_auto_ismaster (primary, - "{'ok': 1," - " 'ismaster': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['127.0.0.1:%hu', '127.0.0.1:%hu']}", - mock_server_get_port (primary), - mock_server_get_port (secondary)); - - uri_str = bson_strdup_printf ("mongodb://127.0.0.1:%hu,127.0.0.1:%hu/" - "?replicaSet=rs&connectTimeoutMS=%d", - mock_server_get_port (primary), - mock_server_get_port (secondary), - connect_timeout_ms); - - uri = mongoc_uri_new (uri_str); - BSON_ASSERT (uri); - if (!try_once) { - /* override default */ - mongoc_uri_set_option_as_bool (uri, "serverSelectionTryOnce", false); - } - - client = mongoc_client_new_from_uri (uri); - - /* start waiting for a primary (NULL read pref) */ - start = bson_get_monotonic_time (); - future = - future_topology_select (client->topology, MONGOC_SS_READ, NULL, &error); - - /* selection succeeds */ - sd = future_get_mongoc_server_description_ptr (future); - ASSERT_OR_PRINT (sd, error); - future_destroy (future); - - duration_usec = bson_get_monotonic_time () - start; - - if (!test_suite_valgrind ()) { - ASSERT_ALMOST_EQUAL (duration_usec / 1000, connect_timeout_ms); - } - - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - bson_free (uri_str); - mongoc_server_description_destroy (sd); - mock_server_destroy (primary); - mock_server_destroy (secondary); -} - - -/* CDRIVER-1219: a secondary is unavailable, scan should take connectTimeoutMS, - * then we select primary */ -static void -test_select_after_timeout (void) -{ - _test_select_succeed (false); -} - - -/* CDRIVER-1219: a secondary is unavailable, scan should try it once, - * then we select primary */ -static void -test_select_after_try_once (void) -{ - _test_select_succeed (true); -} - - -static void -test_multiple_selection_errors (void *context) -{ - const char *uri = "mongodb://doesntexist,example.com:2/?replicaSet=rs" - "&connectTimeoutMS=100"; - mongoc_client_t *client; - bson_t reply; - bson_error_t error; - - client = mongoc_client_new (uri); - mongoc_client_command_simple ( - client, "test", tmp_bson ("{'ping': 1}"), NULL, &reply, &error); - - ASSERT_CMPINT (MONGOC_ERROR_SERVER_SELECTION, ==, error.domain); - ASSERT_CMPINT (MONGOC_ERROR_SERVER_SELECTION_FAILURE, ==, error.code); - - /* Like: - * "No suitable servers found (`serverselectiontryonce` set): - * [Failed to resolve 'doesntexist'] - * [connection error calling ismaster on 'example.com:2']" - */ - ASSERT_CONTAINS (error.message, "No suitable servers found"); - /* either "connection error" or "connection timeout" calling ismaster */ - ASSERT_CONTAINS (error.message, "calling ismaster on 'example.com:2'"); - ASSERT_CONTAINS (error.message, "[Failed to resolve 'doesntexist']"); - - bson_destroy (&reply); - mongoc_client_destroy (client); -} - - -static void -test_invalid_server_id (void) -{ - mongoc_client_t *client; - bson_error_t error; - - client = test_framework_client_new (); - - BSON_ASSERT ( - !mongoc_topology_server_by_id (client->topology, 99999, &error)); - ASSERT_STARTSWITH (error.message, "Could not find description for node"); - - mongoc_client_destroy (client); -} - - -static bool -auto_ping (request_t *request, void *data) -{ - if (!request->is_command || strcasecmp (request->command_name, "ping")) { - return false; - } - - mock_server_replies_ok_and_destroys (request); - - return true; -} - - -/* Tests CDRIVER-562: after calling ismaster to handshake a new connection we - * must update topology description with the server response. - */ -static void -_test_server_removed_during_handshake (bool pooled) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bool r; - bson_error_t error; - mongoc_server_description_t *sd; - mongoc_server_description_t **sds; - size_t n; - - server = mock_server_new (); - mock_server_run (server); - mock_server_autoresponds (server, auto_ping, NULL, NULL); - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'ismaster': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - /* no auto heartbeat */ - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", INT32_MAX); - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - - if (pooled) { - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - } else { - client = mongoc_client_new_from_uri (uri); - } - - /* initial connection, discover one-node replica set */ - r = mongoc_client_command_simple ( - client, "db", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - - ASSERT_CMPINT (_mongoc_topology_get_type (client->topology), - ==, - MONGOC_TOPOLOGY_RS_WITH_PRIMARY); - sd = mongoc_client_get_server_description (client, 1); - ASSERT_CMPINT ((int) MONGOC_SERVER_RS_PRIMARY, ==, sd->type); - mongoc_server_description_destroy (sd); - - /* primary changes setName */ - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'ismaster': true," - " 'setName': 'BAD NAME'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - /* pretend to close a connection. does NOT affect server description yet */ - mongoc_cluster_disconnect_node ( - &client->cluster, 1, false /* invalidate */, NULL); - sd = mongoc_client_get_server_description (client, 1); - /* still primary */ - ASSERT_CMPINT ((int) MONGOC_SERVER_RS_PRIMARY, ==, sd->type); - mongoc_server_description_destroy (sd); - - /* opens new stream and runs ismaster again, discovers bad setName. */ - capture_logs (true); - r = mongoc_client_command_simple ( - client, "db", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - ASSERT (!r); - ASSERT_CAPTURED_LOG ("topology", - MONGOC_LOG_LEVEL_WARNING, - "Last server removed from topology"); - capture_logs (false); - - if (!pooled) { - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NOT_ESTABLISHED, - "Could not find stream for node"); - } else { - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_STREAM, - MONGOC_ERROR_STREAM_NOT_ESTABLISHED, - "removed from topology"); - } - - sds = mongoc_client_get_server_descriptions (client, &n); - ASSERT_CMPSIZE_T (n, ==, (size_t) 0); - ASSERT_CMPINT (_mongoc_topology_get_type (client->topology), - ==, - MONGOC_TOPOLOGY_RS_NO_PRIMARY); - - if (pooled) { - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - } else { - mongoc_client_destroy (client); - } - - mongoc_server_descriptions_destroy_all (sds, n); - mock_server_destroy (server); - mongoc_uri_destroy (uri); -} - - -static void -test_server_removed_during_handshake_single (void) -{ - _test_server_removed_during_handshake (false); -} - - -static void -test_server_removed_during_handshake_pooled (void) -{ - _test_server_removed_during_handshake (true); -} - - -static void -test_rtt (void *ctx) -{ - mock_server_t *server; - mongoc_client_t *client; - future_t *future; - request_t *request; - bson_error_t error; - mongoc_server_description_t *sd; - int64_t rtt_msec; - - if (!TestSuite_CheckMockServerAllowed ()) { - return; - } - - server = mock_server_new (); - mock_server_run (server); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - future = future_client_command_simple ( - client, "db", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - request = mock_server_receives_ismaster (server); - _mongoc_usleep (1000 * 1000); /* one second */ - mock_server_replies (request, - MONGOC_REPLY_NONE, - 0, - 0, - 1, - "{'ok': 1, 'minWireVersion': 2, 'maxWireVersion': 5}"); - request_destroy (request); - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_SLAVE_OK, "{'ping': 1}"); - mock_server_replies (request, - MONGOC_REPLY_NONE, - 0, - 0, - 1, - "{'ok': 1, 'minWireVersion': 2, 'maxWireVersion': 5}"); - request_destroy (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - - sd = mongoc_topology_server_by_id (client->topology, 1, NULL); - ASSERT (sd); - - /* assert, with plenty of slack, that rtt was calculated in ms, not usec */ - rtt_msec = mongoc_server_description_round_trip_time (sd); - ASSERT_CMPINT64 (rtt_msec, >, (int64_t) 900); /* 900 ms */ - ASSERT_CMPINT64 (rtt_msec, <, (int64_t) 9000); /* 9 seconds */ - - mongoc_server_description_destroy (sd); - future_destroy (future); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -/* mongoc_topology_scanner_add and mongoc_topology_scan are called within the - * topology mutex to add a discovered node and call getaddrinfo on its host - * immediately - test that this doesn't cause a recursive acquire on the - * topology mutex */ -static void -test_add_and_scan_failure (void) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool; - mongoc_client_t *client; - future_t *future; - request_t *request; - bson_error_t error; - mongoc_server_description_t *sd; - - server = mock_server_new (); - mock_server_run (server); - /* client will discover "fake" host and fail to connect */ - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'ismaster': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s', 'fake:1']}", - mock_server_get_host_and_port (server)); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - future = future_client_command_simple ( - client, "db", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, "{'ping': 1}"); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - - sd = mongoc_topology_server_by_id (client->topology, 1, NULL); - ASSERT (sd); - ASSERT_CMPSTR (mongoc_server_description_type (sd), "RSPrimary"); - mongoc_server_description_destroy (sd); - - sd = mongoc_topology_server_by_id (client->topology, 2, NULL); - ASSERT (sd); - ASSERT_CMPSTR (mongoc_server_description_type (sd), "Unknown"); - mongoc_server_description_destroy (sd); - - future_destroy (future); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -typedef struct { - int n_started; - int n_succeeded; - int n_failed; -} checks_t; - - -static void -check_started (const mongoc_apm_server_heartbeat_started_t *event) -{ - checks_t *c; - - c = (checks_t *) mongoc_apm_server_heartbeat_started_get_context (event); - c->n_started++; -} - - -static void -check_succeeded (const mongoc_apm_server_heartbeat_succeeded_t *event) -{ - checks_t *c; - - c = (checks_t *) mongoc_apm_server_heartbeat_succeeded_get_context (event); - c->n_succeeded++; -} - - -static void -check_failed (const mongoc_apm_server_heartbeat_failed_t *event) -{ - checks_t *c; - - c = (checks_t *) mongoc_apm_server_heartbeat_failed_get_context (event); - c->n_failed++; -} - - -static mongoc_apm_callbacks_t * -heartbeat_callbacks (void) -{ - mongoc_apm_callbacks_t *callbacks; - - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_server_heartbeat_started_cb (callbacks, check_started); - mongoc_apm_set_server_heartbeat_succeeded_cb (callbacks, check_succeeded); - mongoc_apm_set_server_heartbeat_failed_cb (callbacks, check_failed); - - return callbacks; -} - - -static future_t * -future_command (mongoc_client_t *client, bson_error_t *error) -{ - return future_client_command_simple ( - client, "admin", tmp_bson ("{'foo': 1}"), NULL, NULL, error); -} - - -static void -receives_command (mock_server_t *server, future_t *future) -{ - request_t *request; - bson_error_t error; - - request = mock_server_receives_command ( - server, "admin", MONGOC_QUERY_NONE, "{'foo': 1}"); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); -} - - -static bool -has_known_server (mongoc_client_t *client) -{ - mongoc_server_description_t *sd; - bool r; - - /* in this test we know the server id is always 1 */ - sd = mongoc_client_get_server_description (client, 1); - r = (sd->type != MONGOC_SERVER_UNKNOWN); - mongoc_server_description_destroy (sd); - return r; -} - - -static void -_test_ismaster_retry_single (bool hangup, int n_failures) -{ - checks_t checks = {0}; - mongoc_apm_callbacks_t *callbacks; - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - char *ismaster; - future_t *future; - request_t *request; - bson_error_t error; - int64_t t; - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 500); - mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_REPLICASET, "rs"); - if (!hangup) { - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_CONNECTTIMEOUTMS, 100); - } - - client = mongoc_client_new_from_uri (uri); - callbacks = heartbeat_callbacks (); - mongoc_client_set_apm_callbacks (client, callbacks, &checks); - - ismaster = bson_strdup_printf ("{'ok': 1," - " 'ismaster': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - /* start a {foo: 1} command, handshake normally */ - future = future_command (client, &error); - request = mock_server_receives_ismaster (server); - mock_server_replies_simple (request, ismaster); - request_destroy (request); - receives_command (server, future); - - /* wait for the next server check */ - _mongoc_usleep (600 * 1000); - - /* start a {foo: 1} command, server check fails and retries immediately */ - future = future_command (client, &error); - request = mock_server_receives_ismaster (server); - t = bson_get_monotonic_time (); - if (hangup) { - mock_server_hangs_up (request); - } - - request_destroy (request); - - /* retry immediately (for testing, "immediately" means less than 250ms */ - request = mock_server_receives_ismaster (server); - ASSERT_CMPINT64 (bson_get_monotonic_time () - t, <, (int64_t) 250 * 1000); - - if (n_failures == 2) { - if (hangup) { - mock_server_hangs_up (request); - } - - BSON_ASSERT (!future_get_bool (future)); - future_destroy (future); - } else { - mock_server_replies_simple (request, ismaster); - /* the {foo: 1} command finishes */ - receives_command (server, future); - } - - request_destroy (request); - - ASSERT_CMPINT (checks.n_started, ==, 3); - WAIT_UNTIL (checks.n_succeeded == 3 - n_failures); - WAIT_UNTIL (checks.n_failed == n_failures); - - if (n_failures == 2) { - BSON_ASSERT (!has_known_server (client)); - } else { - BSON_ASSERT (has_known_server (client)); - } - - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); - bson_free (ismaster); - mongoc_apm_callbacks_destroy (callbacks); -} - - -static void -_test_ismaster_retry_pooled (bool hangup, int n_failures) -{ - checks_t checks = {0}; - mongoc_apm_callbacks_t *callbacks; - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - char *ismaster; - future_t *future; - request_t *request; - bson_error_t error; - int i; - int64_t t; - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 500); - mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_REPLICASET, "rs"); - if (!hangup) { - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_CONNECTTIMEOUTMS, 100); - } - - pool = mongoc_client_pool_new (uri); - callbacks = heartbeat_callbacks (); - mongoc_client_pool_set_apm_callbacks (pool, callbacks, &checks); - client = mongoc_client_pool_pop (pool); - - ismaster = bson_strdup_printf ("{'ok': 1," - " 'ismaster': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['%s']}", - mock_server_get_host_and_port (server)); - - /* start a {foo: 1} command, handshake normally */ - future = future_command (client, &error); - - /* one ismaster from the scanner, another to handshake the connection */ - for (i = 0; i < 2; i++) { - request = mock_server_receives_ismaster (server); - mock_server_replies_simple (request, ismaster); - request_destroy (request); - } - - /* the {foo: 1} command finishes */ - receives_command (server, future); - - /* wait for the next server check */ - request = mock_server_receives_ismaster (server); - t = bson_get_monotonic_time (); - if (hangup) { - mock_server_hangs_up (request); - } - - request_destroy (request); - - /* retry immediately (for testing, "immediately" means less than 250ms */ - request = mock_server_receives_ismaster (server); - ASSERT_CMPINT64 (bson_get_monotonic_time () - t, <, (int64_t) 250 * 1000); - if (n_failures == 2) { - if (hangup) { - mock_server_hangs_up (request); - } - BSON_ASSERT (!has_known_server (client)); - } else { - mock_server_replies_simple (request, ismaster); - WAIT_UNTIL (has_known_server (client)); - } - - request_destroy (request); - - WAIT_UNTIL (checks.n_succeeded == 3 - n_failures); - WAIT_UNTIL (checks.n_failed == n_failures); - ASSERT_CMPINT (checks.n_started, ==, 3); - - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - mongoc_uri_destroy (uri); - mock_server_destroy (server); - bson_free (ismaster); - mongoc_apm_callbacks_destroy (callbacks); -} - - -static void -test_ismaster_retry_single_hangup (void) -{ - _test_ismaster_retry_single (true, 1); -} - - -static void -test_ismaster_retry_single_timeout (void) -{ - _test_ismaster_retry_single (false, 1); -} - -static void -test_ismaster_retry_single_hangup_fail (void) -{ - _test_ismaster_retry_single (true, 2); -} - - -static void -test_ismaster_retry_single_timeout_fail (void) -{ - _test_ismaster_retry_single (false, 2); -} - - -static void -test_ismaster_retry_pooled_hangup (void) -{ - _test_ismaster_retry_pooled (true, 1); -} - - -static void -test_ismaster_retry_pooled_timeout (void) -{ - _test_ismaster_retry_pooled (false, 1); -} - - -static void -test_ismaster_retry_pooled_hangup_fail (void) -{ - _test_ismaster_retry_pooled (true, 2); -} - - -static void -test_ismaster_retry_pooled_timeout_fail (void) -{ - _test_ismaster_retry_pooled (false, 2); -} - - -static void -test_incompatible_error (void) -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_t *client; - bson_error_t error; - char *msg; - - /* incompatible */ - server = mock_server_with_autoismaster (WIRE_VERSION_MIN - 1); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500); - client = mongoc_client_new_from_uri (uri); - - /* trigger connection, fails due to incompatibility */ - ASSERT (!mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ismaster': 1}"), NULL, NULL, &error)); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "reports wire version 2, but this version of" - " libmongoc requires at least 3 (MongoDB 3.0)"); - - mock_server_auto_ismaster (server, - "{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 10," - " 'maxWireVersion': 11}"); - - /* wait until it's time for next heartbeat */ - _mongoc_usleep (600 * 1000); - ASSERT (!mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ismaster': 1}"), NULL, NULL, &error)); - - msg = bson_strdup_printf ("requires wire version 10, but this version" - " of libmongoc only supports up to %d", - WIRE_VERSION_MAX); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_PROTOCOL, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - msg); - - bson_free (msg); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - - -/* ensure there's no invalid access if a null bson_error_t pointer is passed - * to mongoc_topology_compatible () */ -static void -test_compatible_null_error_pointer (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_topology_description_t *td; - bson_error_t error; - - /* incompatible */ - server = mock_server_with_autoismaster (WIRE_VERSION_MIN - 1); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - td = &client->topology->description; - - /* trigger connection, fails due to incompatibility */ - ASSERT (!mongoc_client_command_simple ( - client, "admin", tmp_bson ("{'ismaster': 1}"), NULL, NULL, &error)); - - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, ""); - - /* null error pointer is ok */ - ASSERT (!mongoc_topology_compatible ( - td, NULL /* read prefs */, NULL /* error */)); - - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static char * -cluster_time_fmt (int t) -{ - return bson_strdup_printf ( - "{" - " 'clusterTime': {'$timestamp': {'t': %d, 'i': 1}}," - " 'signature': {" - " 'hash': {'$binary': {'subType': '0', 'base64': 'Yw=='}}," - " 'keyId': {'$numberLong': '6446735049323708417'}" - " }," - " 'operationTime': {'$timestamp': {'t': 1, 'i': 1}}" - "}", - t); -} - -static void -test_cluster_time_updated_during_handshake () -{ - mock_server_t *server; - mongoc_uri_t *uri; - mongoc_client_pool_t *pool = NULL; - mongoc_client_t *client; - bool r; - bson_error_t error; - char *cluster_time; - mongoc_server_description_t *sd; - - server = mock_server_new (); - mock_server_run (server); - mock_server_autoresponds (server, auto_ping, NULL, NULL); - cluster_time = cluster_time_fmt (1); - mock_server_auto_ismaster (server, - "{'ok': 1, 'ismaster': true, 'setName': 'rs', " - "'minWireVersion': 2, 'maxWireVersion': 7, " - "'hosts': ['%s'], '$clusterTime': %s}", - mock_server_get_host_and_port (server), - cluster_time); - - uri = mongoc_uri_copy (mock_server_get_uri (server)); - /* set a large heartbeatFrequencyMS so we don't do a background scan in - * between the first scan and handshake. */ - mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 99999); - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "rs"); - - pool = mongoc_client_pool_new (uri); - client = mongoc_client_pool_pop (pool); - - /* ensure a topology scan has run, populating the topology description - * cluster time. */ - sd = mongoc_client_select_server (client, false, NULL, &error); - ASSERT_OR_PRINT (sd, error); - mongoc_server_description_destroy (sd); - - /* check the cluster time stored on the topology description. */ - bson_mutex_lock (&client->topology->mutex); - ASSERT_MATCH (&client->topology->description.cluster_time, cluster_time); - bson_mutex_unlock (&client->topology->mutex); - bson_free (cluster_time); - cluster_time = cluster_time_fmt (2); - - /* primary changes clusterTime */ - mock_server_auto_ismaster (server, - "{'ok': 1, 'ismaster': true, 'setName': 'rs', " - "'minWireVersion': 2, 'maxWireVersion': 7, " - "'hosts': ['%s'], '$clusterTime': %s}", - mock_server_get_host_and_port (server), - cluster_time); - - /* remove the node from the cluster to trigger an ismaster handshake. */ - mongoc_cluster_disconnect_node ( - &client->cluster, 1, false /* invalidate */, NULL); - - /* opens new stream and does an ismaster handshake (in pooled mode only). */ - r = mongoc_client_command_simple ( - client, "db", tmp_bson ("{'ping': 1}"), NULL, NULL, &error); - - ASSERT_OR_PRINT (r, error); - bson_mutex_lock (&client->topology->mutex); - ASSERT_MATCH (&client->topology->description.cluster_time, cluster_time); - bson_mutex_unlock (&client->topology->mutex); - bson_free (cluster_time); - mongoc_client_pool_push (pool, client); - mongoc_client_pool_destroy (pool); - mock_server_destroy (server); - mongoc_uri_destroy (uri); -} - -/* returns the last time the topology completed a full scan. */ -static int64_t -_get_last_scan (mongoc_client_t *client) -{ - int64_t last_scan; - mongoc_topology_t *topology = client->topology; - bson_mutex_lock (&topology->mutex); - last_scan = topology->last_scan; - bson_mutex_unlock (&topology->mutex); - return last_scan; -} - -typedef struct { - int64_t when_transitioned_to_unknown; - int64_t server_id; -} request_scan_error_ctx_t; - -static void -_server_changed (const mongoc_apm_server_changed_t *event) -{ - const mongoc_server_description_t *sd; - request_scan_error_ctx_t *ctx; - - ctx = (request_scan_error_ctx_t *) mongoc_apm_server_changed_get_context ( - event); - sd = mongoc_apm_server_changed_get_new_description (event); - if (sd->type == MONGOC_SERVER_UNKNOWN) { - ctx->when_transitioned_to_unknown = bson_get_monotonic_time (); - ctx->server_id = sd->id; - } -} - -/* test that when a command receives a "not master" or "node is recovering" - * error that the client takes the appropriate action: - * - a pooled client should mark the server as unknown and request a full scan - * of the topology - * - a single-threaded client should mark the server as unknown and mark the - * topology as stale. - */ -static void -_test_request_scan_on_error (bool pooled, - const char *err_response, - bool should_scan, - bool should_mark_unknown, - const char *server_err) -{ - mock_server_t *primary, *secondary; - char *uri_str; - mongoc_uri_t *uri; - mongoc_client_pool_t *client_pool = NULL; - mongoc_client_t *client = NULL; - bson_t reply; - bson_error_t error = {0}; - future_t *future = NULL; - request_t *request; - const int64_t minHBMS = 50; - int64_t last_scan = 0; - mongoc_read_prefs_t *read_prefs; - mongoc_apm_callbacks_t *callbacks; - request_scan_error_ctx_t ctx = {0}; - - primary = mock_server_new (); - secondary = mock_server_new (); - mock_server_run (primary); - mock_server_run (secondary); - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED); - - RS_RESPONSE_TO_ISMASTER (primary, 6, true, false, primary, secondary); - RS_RESPONSE_TO_ISMASTER (secondary, 6, false, false, primary, secondary); - - /* set a high heartbeatFrequency. Only the first and requested scans run. */ - uri_str = bson_strdup_printf ( - "mongodb://%s,%s/?replicaSet=rs&heartbeatFrequencyMS=999999", - mock_server_get_host_and_port (primary), - mock_server_get_host_and_port (secondary)); - uri = mongoc_uri_new (uri_str); - bson_free (uri_str); - - if (pooled) { - mongoc_topology_t *topology; - client_pool = mongoc_client_pool_new (uri); - topology = _mongoc_client_pool_get_topology (client_pool); - /* set a small minHeartbeatFrequency, so scans don't block for 500ms. */ - topology->min_heartbeat_frequency_msec = minHBMS; - client = mongoc_client_pool_pop (client_pool); - /* upon popping a client, the background monitoring thread is started. */ - /* wait for the initial server selection to finish. */ - WAIT_UNTIL (_get_last_scan (client) > last_scan); - } else { - mongoc_server_description_t *sd; - client = mongoc_client_new_from_uri (uri); - /* set a small minHeartbeatFrequency, so scans don't block for 500ms. */ - client->topology->min_heartbeat_frequency_msec = minHBMS; - sd = mongoc_client_select_server (client, false, NULL, &error); - ASSERT_OR_PRINT (sd, error); - mongoc_server_description_destroy (sd); - } - mongoc_uri_destroy (uri); - /* now that the initial server selection is completed, record the time. */ - last_scan = _get_last_scan (client); - /* listen for transition to UNKNOWN */ - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_server_changed_cb (callbacks, _server_changed); - if (pooled) { - mongoc_client_pool_set_apm_callbacks (client_pool, callbacks, &ctx); - } else { - mongoc_client_set_apm_callbacks (client, callbacks, &ctx); - } - mongoc_apm_callbacks_destroy (callbacks); - /* run a ping command on the primary. */ - future = future_client_command_simple ( - client, "db", tmp_bson ("{'ping': 1}"), read_prefs, &reply, &error); - request = mock_server_receives_msg ( - primary, MONGOC_QUERY_NONE, tmp_bson ("{'ping': 1}")); - - /* Capture logs to swallow warnings about endSessions */ - capture_logs (true); - - mock_server_replies_simple (request, err_response); - request_destroy (request); - /* don't check the return value of future. write concern errors are still - * considered successful results. */ - future_wait (future); - future_destroy (future); - bson_destroy (&reply); - - if (should_mark_unknown) { - mongoc_server_description_t *sd; - /* between sending the 'ping' command and returning, the server should - * have been marked as unknown. */ - ASSERT_CMPINT64 (last_scan, <=, ctx.when_transitioned_to_unknown); - ASSERT_CMPINT64 ( - ctx.when_transitioned_to_unknown, <=, bson_get_monotonic_time ()); - sd = mongoc_client_get_server_description (client, - (uint32_t) ctx.server_id); - /* check that the error on the server description matches the error - * message in the response. */ - if (server_err) { - ASSERT_CMPSTR (server_err, sd->error.message); - } - mongoc_server_description_destroy (sd); - } else { - ASSERT_CMPINT64 (ctx.when_transitioned_to_unknown, ==, (int64_t) 0); - } - - if (pooled) { - if (should_scan) { - /* a scan is requested immediately. wait for the scan to finish. */ - WAIT_UNTIL (_get_last_scan (client) > last_scan); - } else { - /* wait a short while to make sure no scan occurs. */ - _mongoc_usleep (10 * 1000); - } - } else { - /* a single threaded client may mark the topology as stale. if a scan - * should occur, it won't be triggered until the next command. */ - future = future_client_command_simple ( - client, "db", tmp_bson ("{'ping': 1}"), read_prefs, &reply, &error); - if (should_scan || !should_mark_unknown) { - request = mock_server_receives_msg ( - primary, MONGOC_QUERY_NONE, tmp_bson ("{'ping': 1}")); - } else { - /* if the primary was marked as UNKNOWN, and no scan occurred, the ping - * goes to the secondary. */ - request = mock_server_receives_msg ( - secondary, MONGOC_QUERY_NONE, tmp_bson ("{'ping': 1}")); - } - mock_server_replies_simple (request, "{'ok': 1}"); - request_destroy (request); - BSON_ASSERT (future_get_bool (future)); - future_destroy (future); - bson_destroy (&reply); - } - - if (should_scan) { - ASSERT_CMPINT64 (last_scan, <, _get_last_scan (client)); - } else { - ASSERT_CMPINT64 (last_scan, ==, _get_last_scan (client)); - } - - mongoc_read_prefs_destroy (read_prefs); - if (pooled) { - mongoc_client_pool_push (client_pool, client); - mongoc_client_pool_destroy (client_pool); - } else { - mongoc_client_destroy (client); - } - mock_server_destroy (primary); - mock_server_destroy (secondary); -} - -static void -test_last_server_removed_warning () -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_uri_t *uri; - mongoc_server_description_t *description; - mongoc_read_prefs_t *read_prefs; - bson_error_t error; - - server = mock_server_new (); - mock_server_run (server); - uri = mongoc_uri_copy (mock_server_get_uri (server)); - mongoc_uri_set_option_as_utf8 (uri, "replicaSet", "set"); - client = mongoc_client_new_from_uri (uri); - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - mock_server_auto_ismaster (server, - "{'ok': 1," - " 'ismaster': true," - " 'setName': 'rs'," - " 'minWireVersion': 2," - " 'maxWireVersion': 5," - " 'hosts': ['127.0.0.1:%hu']}", - mock_server_get_port (server)); - - capture_logs (true); - description = mongoc_topology_select ( - client->topology, MONGOC_SS_READ, read_prefs, &error); - ASSERT_CAPTURED_LOG ("topology", - MONGOC_LOG_LEVEL_WARNING, - "Last server removed from topology"); - capture_logs (false); - - mongoc_server_description_destroy (description); - mongoc_read_prefs_destroy (read_prefs); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - -static void -test_request_scan_on_error () -{ -#define TEST_POOLED(msg, should_scan, should_mark_unknown, server_err) \ - _test_request_scan_on_error ( \ - true, msg, should_scan, should_mark_unknown, server_err) -#define TEST_SINGLE(msg, should_scan, should_mark_unknown, server_err) \ - _test_request_scan_on_error ( \ - false, msg, should_scan, should_mark_unknown, server_err) -#define TEST_BOTH(msg, should_scan, should_mark_unknown, server_err) \ - TEST_POOLED (msg, should_scan, should_mark_unknown, server_err); \ - TEST_SINGLE (msg, should_scan, should_mark_unknown, server_err) - - TEST_BOTH ("{'ok': 0, 'errmsg': 'not master'}", - true /* should_scan */, - true /* should_mark_unknown */, - "not master"); - /* "node is recovering" behaves differently for single and pooled clients. */ - TEST_SINGLE ("{'ok': 0, 'errmsg': 'node is recovering'}", - false /* should_scan */, - true /* should_mark_unknown */, - "node is recovering"); - TEST_POOLED ("{'ok': 0, 'errmsg': 'node is recovering'}", - true /* should_scan */, - true /* should_mark_unknown */, - "node is recovering"); - TEST_BOTH ("{'ok': 0, 'errmsg': 'random error'}", - false /* should_scan */, - false /* should_mark_unknown */, - "random error"); - /* check the error code for NotMaster, which should be considered a "not - * master" error. */ - TEST_BOTH ("{'ok': 0, 'code': 10107 }", - true /* should_scan */, - true /* should_mark_unknown */, - NULL /* server_err */); - /* for an unknown code, the message should still be checked. */ - TEST_BOTH ("{'ok': 0, 'code': 12345, 'errmsg': 'not master'}", - true /* should_scan */, - true /* should_mark_unknown */, - "not master"); - /* check the error code for InterruptedAtShutdown, which behaves - * much like a "node is recovering" error. */ - TEST_SINGLE ("{'ok': 0, 'code': 11600 }", - false /* should_scan */, - true /* should_mark_unknown */, - NULL /* server_err */); - TEST_POOLED ("{'ok': 0, 'code': 11600 }", - true /* should_scan */, - true /* should_mark_unknown */, - NULL /* server_err */); - /* with a "not master" error code but a "node is recovery" message, the error - * code takes precedence */ - TEST_BOTH ("{'ok': 0, 'code': 10107, 'errmsg': 'node is recovering'}", - true /* should_scan */, - true /* should_mark_unknown */, - "node is recovering"); - /* write concern errors are also checked. */ - TEST_BOTH ("{'ok': 1, 'writeConcernError': { 'errmsg': 'not master' }}", - true, /* should_scan */ - true /* should_mark_unknown */, - "not master"); - TEST_BOTH ("{'ok': 1, 'writeConcernError': { 'code': 10107 }}", - true, /* should_scan */ - true /* should_mark_unknown */, - NULL /* server_err */); - -#undef TEST_BOTH -#undef TEST_POOLED -#undef TEST_SINGLE -} - - -void -test_topology_install (TestSuite *suite) -{ - TestSuite_AddLive ( - suite, "/Topology/client_creation", test_topology_client_creation); - 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", - test_server_selection_try_once_option, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Topology/server_selection_try_once", - test_server_selection_try_once, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Topology/server_selection_try_once_false", - test_server_selection_try_once_false, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Topology/invalidate_server/single", - test_topology_invalidate_server_single, - NULL, - NULL, - test_framework_skip_if_slow_or_live, - test_framework_skip_if_valgrind); - TestSuite_AddFull (suite, - "/Topology/invalidate_server/pooled", - test_topology_invalidate_server_pooled, - NULL, - NULL, - test_framework_skip_if_slow_or_live, - test_framework_skip_if_valgrind); - TestSuite_AddFull (suite, - "/Topology/invalid_cluster_node", - test_invalid_cluster_node, - NULL, - NULL, - test_framework_skip_if_slow_or_live); - TestSuite_AddFull (suite, - "/Topology/max_wire_version_race_condition", - test_max_wire_version_race_condition, - NULL, - NULL, - test_framework_skip_if_no_auth); - 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); - TestSuite_AddMockServerTest (suite, - "/Topology/cooldown/retry", - test_cooldown_retry, - NULL, - NULL, - test_framework_skip_if_slow); - TestSuite_AddFull (suite, - "/Topology/multiple_selection_errors", - test_multiple_selection_errors, - NULL, - NULL, - test_framework_skip_if_offline); - 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_AddMockServerTest ( - suite, "/Topology/add_and_scan_failure", test_add_and_scan_failure); - TestSuite_AddMockServerTest (suite, - "/Topology/ismaster_retry/single/hangup", - test_ismaster_retry_single_hangup, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/ismaster_retry/single/timeout", - test_ismaster_retry_single_timeout, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/ismaster_retry/single/hangup/fail", - test_ismaster_retry_single_hangup_fail, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/ismaster_retry/single/timeout/fail", - test_ismaster_retry_single_timeout_fail, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/ismaster_retry/pooled/hangup", - test_ismaster_retry_pooled_hangup, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/ismaster_retry/pooled/timeout", - test_ismaster_retry_pooled_timeout, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/ismaster_retry/pooled/hangup/fail", - test_ismaster_retry_pooled_hangup_fail, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/ismaster_retry/pooled/timeout/fail", - test_ismaster_retry_pooled_timeout_fail, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/incompatible_error", - test_incompatible_error, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/compatible_null_error_pointer", - test_compatible_null_error_pointer, - test_framework_skip_if_slow); - TestSuite_AddMockServerTest (suite, - "/Topology/handshake/updates_clustertime", - test_cluster_time_updated_during_handshake); - TestSuite_AddMockServerTest ( - suite, "/Topology/request_scan_on_error", test_request_scan_on_error); - TestSuite_AddMockServerTest (suite, - "/Topology/last_server_removed_warning", - test_last_server_removed_warning); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-transactions.c b/lib/mongoc/libmongoc/tests/test-mongoc-transactions.c deleted file mode 100644 index 187fc77adc184e875aa940a462e269e203446103..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-transactions.c +++ /dev/null @@ -1,1246 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-collection-private.h" - -#include "json-test.h" -#include "test-libmongoc.h" -#include "mock_server/mock-rs.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" -#include "json-test-operations.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-host-list-private.h" -#include "mongoc/mongoc-read-concern-private.h" -#include "mongoc/mongoc-write-concern-private.h" - -/* Reset server state by disabling failpoints, killing sessions, and... running - * a distinct command. */ -static void -_reset_server (json_test_ctx_t *ctx, const char *host_str) -{ - mongoc_client_t *client; - bson_error_t error; - bool res; - mongoc_uri_t *uri = _mongoc_uri_copy_and_replace_host_list ( - ctx->test_framework_uri, host_str); - - client = mongoc_client_new_from_uri (uri); - - /* From Transactions tests runner: "Create a MongoClient and call - * client.admin.runCommand({killAllSessions: []}) to clean up any open - * transactions from previous test failures. Ignore a command failure with - * error code 11601 ("Interrupted") to work around SERVER-38335." - */ - res = mongoc_client_command_simple (client, - "admin", - tmp_bson ("{'killAllSessions': []}"), - NULL, - NULL, - &error); - if (!res && error.code != 11601) { - test_error ("Unexpected error: %s from killAllSessions\n", error.message); - } - - /* From Transactions spec test runner: "When testing against a sharded - * cluster run a distinct command on the newly - * created collection on all mongoses. For an explanation see, Why do tests - * that run distinct sometimes fail with StaleDbVersion?" */ - - ASSERT_OR_PRINT ( - mongoc_client_command_simple ( - client, - mongoc_database_get_name (ctx->db), - tmp_bson ("{'distinct': '%s', 'key': 'test', 'query': {}}", - mongoc_collection_get_name (ctx->collection)), - NULL /* read prefs */, - NULL /* reply */, - &error), - error); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); -} - -static void -_disable_failpoints (json_test_ctx_t *ctx, const char *host_str) -{ - mongoc_client_t *client; - bson_error_t error; - int i; - mongoc_uri_t *uri = _mongoc_uri_copy_and_replace_host_list ( - ctx->test_framework_uri, host_str); - - /* Some transactions tests have a failCommand for "isMaster" repeat seven - * times. Repeat this seven times. And set a reduced server selection timeout - * so we don't hang on failed ismaster commands. */ - mongoc_uri_set_option_as_int32 ( - uri, MONGOC_URI_SERVERSELECTIONTIMEOUTMS, 500); - - for (i = 0; i < 7; i++) { - bool ret; - - client = mongoc_client_new_from_uri (uri); - ret = mongoc_client_command_simple ( - client, - "admin", - tmp_bson ("{'configureFailPoint': 'failCommand', 'mode': 'off'}"), - NULL, - NULL, - &error); - if (!ret) { - /* Tests that fail with isMaster also fail to disable the failpoint - * (since we run isMaster when opening the connection). Ignore those - * errors. */ - BSON_ASSERT (NULL != - strstr (error.message, "No suitable servers found")); - } - mongoc_client_destroy (client); - } - mongoc_uri_destroy (uri); -} - -static void -transactions_test_before_test (json_test_ctx_t *ctx, const bson_t *test) -{ - bson_iter_t test_iter; - bool is_multi_mongos; - - _reset_server (ctx, "localhost:27017"); - - is_multi_mongos = - bson_iter_init_find (&test_iter, test, "useMultipleMongoses") && - bson_iter_as_bool (&test_iter); - - if (is_multi_mongos) { - _reset_server (ctx, "localhost:27018"); - } -} - - -static void -transactions_test_after_test (json_test_ctx_t *ctx, const bson_t *test) -{ - bson_iter_t test_iter; - bool is_multi_mongos; - - _disable_failpoints (ctx, "localhost:27017"); - - is_multi_mongos = - bson_iter_init_find (&test_iter, test, "useMultipleMongoses") && - bson_iter_as_bool (&test_iter); - - if (is_multi_mongos) { - _disable_failpoints (ctx, "localhost:27018"); - } -} - - -typedef struct _cb_ctx_t { - bson_t callback; - json_test_ctx_t *ctx; -} cb_ctx_t; - - -static bool -with_transaction_callback_runner (mongoc_client_session_t *session, - void *ctx, - bson_t **reply, - bson_error_t *error) -{ - cb_ctx_t *cb_ctx = (cb_ctx_t *) ctx; - bson_t operation; - bson_t operations; - bson_t *test; - bson_iter_t iter; - bool res = false; - bson_t local_reply; - - test = &(cb_ctx->callback); - - if (bson_has_field (test, "operation")) { - bson_lookup_doc (test, "operation", &operation); - res = json_test_operation (cb_ctx->ctx, - test, - &operation, - cb_ctx->ctx->collection, - session, - &local_reply); - } else { - ASSERT (bson_has_field (test, "operations")); - bson_lookup_doc (test, "operations", &operations); - BSON_ASSERT (bson_iter_init (&iter, &operations)); - - bson_init (&local_reply); - - while (bson_iter_next (&iter)) { - bson_destroy (&local_reply); - bson_iter_bson (&iter, &operation); - res = json_test_operation (cb_ctx->ctx, - test, - &operation, - cb_ctx->ctx->collection, - session, - &local_reply); - if (!res) { - break; - } - } - } - - *reply = bson_copy (&local_reply); - bson_destroy (&local_reply); - - return res; -} - -static bool -transactions_test_run_operation (json_test_ctx_t *ctx, - const bson_t *test, - const bson_t *operation) -{ - mongoc_transaction_opt_t *opts = NULL; - mongoc_client_session_t *session = NULL; - bson_error_t error; - bson_value_t value; - bson_t reply; - bool res; - cb_ctx_t cb_ctx; - - /* If there is a 'callback' field, run the nested operations through - mongoc_client_session_with_transaction(). */ - if (bson_has_field (operation, "arguments.callback")) { - ASSERT (bson_has_field (operation, "object")); - session = session_from_name (ctx, bson_lookup_utf8 (operation, "object")); - ASSERT (session); - - bson_lookup_doc (operation, "arguments.callback", &cb_ctx.callback); - cb_ctx.ctx = ctx; - - if (bson_has_field (operation, "arguments.options")) { - opts = bson_lookup_txn_opts (operation, "arguments.options"); - } - - res = mongoc_client_session_with_transaction ( - session, - with_transaction_callback_runner, - opts, - &cb_ctx, - &reply, - &error); - - value_init_from_doc (&value, &reply); - check_result (test, operation, res, &value, &error); - bson_value_destroy (&value); - - } else { - /* If there is no 'callback' field, then run simply. */ - if (bson_has_field (operation, "arguments.session")) { - session = session_from_name ( - ctx, bson_lookup_utf8 (operation, "arguments.session")); - } - - /* expect some warnings from abortTransaction, but don't suppress others: - * we want to know if any other tests log warnings */ - capture_logs (true); - res = json_test_operation ( - ctx, test, operation, ctx->collection, session, &reply); - assert_all_captured_logs_have_prefix ("Error in abortTransaction:"); - capture_logs (false); - } - - bson_destroy (&reply); - mongoc_transaction_opts_destroy (opts); - - return res; -} - - -static void -test_transactions_cb (bson_t *scenario) -{ - json_test_config_t config = JSON_TEST_CONFIG_INIT; - config.before_test_cb = transactions_test_before_test; - config.run_operation_cb = transactions_test_run_operation; - config.after_test_cb = transactions_test_after_test; - config.scenario = scenario; - config.command_started_events_only = true; - run_json_general_test (&config); -} - - -static void -test_transactions_supported (void *ctx) -{ - mongoc_client_t *client; - mongoc_client_session_t *session; - mongoc_database_t *db; - mongoc_collection_t *collection; - bson_t *majority = tmp_bson ("{'writeConcern': {'w': 'majority'}}"); - bson_t opts = BSON_INITIALIZER; - bson_error_t error; - bool r; - - if (test_framework_is_mongos ()) { - bson_destroy (&opts); - return; - } - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - db = mongoc_client_get_database (client, "transaction-tests"); - - /* drop and create collection outside of transaction */ - mongoc_database_write_command_with_opts ( - db, tmp_bson ("{'drop': 'test'}"), majority, NULL, NULL); - collection = - mongoc_database_create_collection (db, "test", majority, &error); - ASSERT_OR_PRINT (collection, error); - - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - - if ((r = mongoc_client_session_start_transaction (session, NULL, &error))) { - r = mongoc_client_session_append (session, &opts, &error); - ASSERT_OR_PRINT (r, error); - - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), &opts, NULL, &error); - - /* insert should fail if replset has no members */ - BSON_ASSERT (r == test_framework_is_replset ()); - } else { - ASSERT_CMPINT32 (error.domain, ==, MONGOC_ERROR_TRANSACTION); - ASSERT_CONTAINS (error.message, "transaction"); - } - - bson_destroy (&opts); - mongoc_collection_destroy (collection); - - if (!r) { - /* suppress "error in abortTransaction" warning from session_destroy */ - capture_logs (true); - } - - mongoc_client_session_destroy (session); - mongoc_database_destroy (db); - mongoc_client_destroy (client); -} - - -static void -test_in_transaction (void *ctx) -{ - mongoc_client_t *client; - mongoc_client_session_t *session; - mongoc_database_t *db; - mongoc_collection_t *collection; - bson_t *majority = tmp_bson ("{'writeConcern': {'w': 'majority'}}"); - bson_t opts = BSON_INITIALIZER; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - mongoc_client_set_error_api (client, 2); - db = mongoc_client_get_database (client, "transaction-tests"); - /* drop and create collection outside of transaction */ - mongoc_database_write_command_with_opts ( - db, tmp_bson ("{'drop': 'test'}"), majority, NULL, NULL); - collection = - mongoc_database_create_collection (db, "test", majority, &error); - ASSERT_OR_PRINT (collection, error); - - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - r = mongoc_client_session_append (session, &opts, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!mongoc_client_session_in_transaction (session)); - ASSERT_CMPINT (mongoc_client_session_get_transaction_state (session), - ==, - MONGOC_TRANSACTION_NONE); - ASSERT_CMPINT (session->txn.state, ==, MONGOC_INTERNAL_TRANSACTION_NONE); - - /* commit an empty transaction */ - r = mongoc_client_session_start_transaction (session, NULL, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (mongoc_client_session_in_transaction (session)); - ASSERT_CMPINT (mongoc_client_session_get_transaction_state (session), - ==, - MONGOC_TRANSACTION_STARTING); - ASSERT_CMPINT (session->txn.state, ==, MONGOC_INTERNAL_TRANSACTION_STARTING); - r = mongoc_client_session_commit_transaction (session, NULL, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!mongoc_client_session_in_transaction (session)); - ASSERT_CMPINT (mongoc_client_session_get_transaction_state (session), - ==, - MONGOC_TRANSACTION_COMMITTED); - ASSERT_CMPINT ( - session->txn.state, ==, MONGOC_INTERNAL_TRANSACTION_COMMITTED_EMPTY); - - /* commit a transaction with an insert */ - r = mongoc_client_session_start_transaction (session, NULL, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (mongoc_client_session_in_transaction (session)); - ASSERT_CMPINT (mongoc_client_session_get_transaction_state (session), - ==, - MONGOC_TRANSACTION_STARTING); - ASSERT_CMPINT (session->txn.state, ==, MONGOC_INTERNAL_TRANSACTION_STARTING); - r = mongoc_collection_insert_one ( - collection, tmp_bson ("{}"), &opts, NULL, &error); - ASSERT_CMPINT (mongoc_client_session_get_transaction_state (session), - ==, - MONGOC_TRANSACTION_IN_PROGRESS); - ASSERT_CMPINT ( - session->txn.state, ==, MONGOC_INTERNAL_TRANSACTION_IN_PROGRESS); - ASSERT_OR_PRINT (r, error); - r = mongoc_client_session_commit_transaction (session, NULL, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!mongoc_client_session_in_transaction (session)); - ASSERT_CMPINT (mongoc_client_session_get_transaction_state (session), - ==, - MONGOC_TRANSACTION_COMMITTED); - ASSERT_CMPINT ( - session->txn.state, ==, MONGOC_INTERNAL_TRANSACTION_COMMITTED); - - /* abort a transaction */ - r = mongoc_client_session_start_transaction (session, NULL, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (mongoc_client_session_in_transaction (session)); - ASSERT_CMPINT (mongoc_client_session_get_transaction_state (session), - ==, - MONGOC_TRANSACTION_STARTING); - ASSERT_CMPINT (session->txn.state, ==, MONGOC_INTERNAL_TRANSACTION_STARTING); - ASSERT_OR_PRINT (r, error); - r = mongoc_client_session_abort_transaction (session, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!mongoc_client_session_in_transaction (session)); - ASSERT_CMPINT (mongoc_client_session_get_transaction_state (session), - ==, - MONGOC_TRANSACTION_ABORTED); - ASSERT_CMPINT (session->txn.state, ==, MONGOC_INTERNAL_TRANSACTION_ABORTED); - - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_database_destroy (db); - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); -} - - -static bool -hangup_except_ismaster (request_t *request, void *data) -{ - if (!bson_strcasecmp (request->command_name, "ismaster")) { - /* allow default response */ - return false; - } - - mock_server_hangs_up (request); - request_destroy (request); - return true; -} - - -static void -_test_transient_txn_err (bool hangup) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_client_session_t *session; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - mongoc_bulk_operation_t *bulk; - mongoc_find_and_modify_opts_t *fam; - bson_t opts = BSON_INITIALIZER; - bson_error_t error; - bson_t *b; - bson_t *u; - const bson_t *doc_out; - const bson_t *error_doc; - bson_t reply; - bool r; - - server = mock_server_new (); - mock_server_run (server); - rs_response_to_ismaster ( - server, 7, true /* primary */, false /* tags */, server, NULL); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - /* allow fast reconnect */ - client->topology->min_heartbeat_frequency_msec = 0; - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - r = mongoc_client_session_start_transaction (session, NULL, &error); - ASSERT_OR_PRINT (r, error); - r = mongoc_client_session_append (session, &opts, &error); - ASSERT_OR_PRINT (r, error); - collection = mongoc_client_get_collection (client, "db", "collection"); - - if (hangup) { - /* test that network errors have TransientTransactionError */ - mock_server_autoresponds (server, hangup_except_ismaster, NULL, NULL); - } else { - /* test server selection errors have TransientTransactionError */ - mock_server_destroy (server); - server = NULL; - } - - /* warnings when trying to abort the transaction and later, end sessions */ - capture_logs (true); - -#define ASSERT_TRANSIENT_LABEL(_b, _expr) \ - do { \ - if (!mongoc_error_has_label ((_b), "TransientTransactionError")) { \ - test_error ("Reply lacks TransientTransactionError label: %s\n" \ - "Running %s", \ - bson_as_json ((_b), NULL), \ - #_expr); \ - } \ - } while (0) - -#define TEST_CMD_ERR(_expr) \ - do { \ - r = (_expr); \ - BSON_ASSERT (!r); \ - ASSERT_TRANSIENT_LABEL (&reply, _expr); \ - bson_destroy (&reply); \ - /* clean slate for next test */ \ - memset (&reply, 0, sizeof (reply)); \ - } while (0) - - -#define TEST_WRITE_ERR(_expr) \ - do { \ - r = (_expr); \ - ASSERT_TRANSIENT_LABEL (&reply, _expr); \ - bson_destroy (&reply); \ - /* clean slate for next test */ \ - memset (&reply, 0, sizeof (reply)); \ - } while (0) - -#define TEST_CURSOR_ERR(_cursor_expr) \ - do { \ - cursor = (_cursor_expr); \ - r = mongoc_cursor_next (cursor, &doc_out); \ - BSON_ASSERT (!r); \ - r = !mongoc_cursor_error_document (cursor, &error, &error_doc); \ - BSON_ASSERT (!r); \ - BSON_ASSERT (error_doc); \ - ASSERT_TRANSIENT_LABEL (error_doc, _cursor_expr); \ - mongoc_cursor_destroy (cursor); \ - } while (0) - - b = tmp_bson ("{'x': 1}"); - u = tmp_bson ("{'$inc': {'x': 1}}"); - - TEST_CMD_ERR (mongoc_client_command_with_opts ( - client, "db", b, NULL, &opts, &reply, NULL)); - TEST_CMD_ERR (mongoc_client_read_command_with_opts ( - client, "db", b, NULL, &opts, &reply, NULL)); - TEST_CMD_ERR (mongoc_client_write_command_with_opts ( - client, "db", b, &opts, &reply, NULL)); - TEST_CMD_ERR (mongoc_client_read_write_command_with_opts ( - client, "db", b, NULL, &opts, &reply, NULL)); - TEST_CMD_ERR (0 < mongoc_collection_count_documents ( - collection, b, &opts, NULL, &reply, NULL)); - - BEGIN_IGNORE_DEPRECATIONS; - TEST_CMD_ERR (mongoc_collection_create_index_with_opts ( - collection, b, NULL, &opts, &reply, NULL)); - END_IGNORE_DEPRECATIONS - - fam = mongoc_find_and_modify_opts_new (); - mongoc_find_and_modify_opts_append (fam, &opts); - TEST_CMD_ERR (mongoc_collection_find_and_modify_with_opts ( - collection, b, fam, &reply, NULL)); - - TEST_WRITE_ERR ( - mongoc_collection_insert_one (collection, b, &opts, &reply, NULL)); - TEST_WRITE_ERR (mongoc_collection_insert_many ( - collection, (const bson_t **) &b, 1, &opts, &reply, NULL)); - TEST_WRITE_ERR ( - mongoc_collection_update_one (collection, b, u, &opts, &reply, NULL)); - TEST_WRITE_ERR ( - mongoc_collection_update_many (collection, b, u, &opts, &reply, NULL)); - TEST_WRITE_ERR ( - mongoc_collection_replace_one (collection, b, b, &opts, &reply, NULL)); - TEST_WRITE_ERR ( - mongoc_collection_delete_one (collection, b, &opts, &reply, NULL)); - TEST_WRITE_ERR ( - mongoc_collection_delete_many (collection, b, &opts, &reply, NULL)); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts); - mongoc_bulk_operation_insert (bulk, b); - TEST_WRITE_ERR (mongoc_bulk_operation_execute (bulk, &reply, NULL)); - - TEST_CURSOR_ERR (mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, tmp_bson ("[{}]"), &opts, NULL)); - TEST_CURSOR_ERR ( - mongoc_collection_find_with_opts (collection, b, &opts, NULL)); - - mongoc_find_and_modify_opts_destroy (fam); - mongoc_bulk_operation_destroy (bulk); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); - - if (server) { - mock_server_destroy (server); - } -} - - -static void -test_server_selection_error (void) -{ - _test_transient_txn_err (false /* hangup */); -} - - -static void -test_network_error (void) -{ - _test_transient_txn_err (true /* hangup */); -} - - -/* Transactions Spec: Drivers add the "UnknownTransactionCommitResult" to a - * server selection error from commitTransaction, even if this is the first - * attempt to send commitTransaction. It is true in this case that the driver - * knows the result: the transaction is definitely not committed. However, the - * "UnknownTransactionCommitResult" label properly communicates to the - * application that calling commitTransaction again may succeed. - */ -static void -test_unknown_commit_result (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_client_session_t *session; - mongoc_collection_t *collection; - future_t *future; - request_t *request; - bson_t opts = BSON_INITIALIZER; - bson_error_t error; - bson_t reply; - bool r; - - server = mock_server_new (); - mock_server_run (server); - rs_response_to_ismaster ( - server, 7, true /* primary */, false /* tags */, server, NULL); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - /* allow fast reconnect */ - client->topology->min_heartbeat_frequency_msec = 0; - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - r = mongoc_client_session_start_transaction (session, NULL, &error); - ASSERT_OR_PRINT (r, error); - r = mongoc_client_session_append (session, &opts, &error); - ASSERT_OR_PRINT (r, error); - collection = mongoc_client_get_collection (client, "db", "collection"); - future = future_collection_insert_one ( - collection, tmp_bson ("{}"), &opts, NULL, &error); - request = mock_server_receives_msg ( - server, 0, tmp_bson ("{'insert': 'collection'}"), tmp_bson ("{}")); - mock_server_replies_ok_and_destroys (request); - ASSERT_OR_PRINT (future_get_bool (future), error); - future_destroy (future); - - /* test server selection errors have UnknownTransactionCommitResult */ - mock_server_destroy (server); - r = mongoc_client_session_commit_transaction (session, &reply, &error); - BSON_ASSERT (!r); - - if (!mongoc_error_has_label (&reply, "UnknownTransactionCommitResult")) { - test_error ("Reply lacks UnknownTransactionCommitResult label: %s", - bson_as_json (&reply, NULL)); - } - - if (mongoc_error_has_label (&reply, "TransientTransactionError")) { - test_error ("Reply shouldn't have TransientTransactionError label: %s", - bson_as_json (&reply, NULL)); - } - - bson_destroy (&reply); - bson_destroy (&opts); - mongoc_collection_destroy (collection); - - /* warning when trying to end the session */ - capture_logs (true); - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); -} - - -static void -test_cursor_primary_read_pref (void *ctx) -{ - mongoc_client_t *client; - mongoc_client_session_t *session; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - bson_t opts = BSON_INITIALIZER; - mongoc_read_prefs_t *read_prefs; - const bson_t *doc; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - collection = get_test_collection (client, "test_cursor_primary_read_pref"); - - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - - r = mongoc_client_session_start_transaction (session, NULL, &error); - ASSERT_OR_PRINT (r, error); - - r = mongoc_client_session_append (session, &opts, &error); - ASSERT_OR_PRINT (r, error); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); - - cursor = mongoc_collection_find_with_opts ( - collection, tmp_bson ("{}"), &opts, read_prefs); - - bson_destroy (&opts); - mongoc_read_prefs_destroy (read_prefs); - mongoc_collection_destroy (collection); - - ASSERT (!mongoc_cursor_next (cursor, &doc)); - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - - mongoc_cursor_destroy (cursor); - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); -} - - -/* test the fix to CDRIVER-2815. */ -void -test_inherit_from_client (void *ctx) -{ - mongoc_client_t *client; - mongoc_client_session_t *session; - bson_error_t error; - mongoc_uri_t *uri; - mongoc_read_concern_t *rc; - const mongoc_read_concern_t *returned_rc; - mongoc_read_prefs_t *rp; - const mongoc_read_prefs_t *returned_rp; - mongoc_write_concern_t *wc; - const mongoc_write_concern_t *returned_wc; - mongoc_session_opt_t *sopt; - const mongoc_session_opt_t *returned_sopt; - mongoc_transaction_opt_t *topt; - const mongoc_transaction_opt_t *returned_topt; - - uri = test_framework_get_uri (); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); - mongoc_uri_set_read_concern (uri, rc); - - rp = mongoc_read_prefs_new (MONGOC_READ_NEAREST); - mongoc_uri_set_read_prefs_t (uri, rp); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_uri_set_write_concern (uri, wc); - - client = mongoc_client_new_from_uri (uri); - - sopt = mongoc_session_opts_new (); - topt = mongoc_transaction_opts_new (); - - mongoc_transaction_opts_set_read_concern (topt, rc); - mongoc_transaction_opts_set_read_prefs (topt, rp); - mongoc_transaction_opts_set_write_concern (topt, wc); - - mongoc_session_opts_set_default_transaction_opts (sopt, topt); - - session = mongoc_client_start_session (client, sopt, &error); - ASSERT_OR_PRINT (session, error); - - /* test that unacknowledged write concern is actually used, since it should - * result in an error. */ - ASSERT (!mongoc_client_session_start_transaction (session, NULL, &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_TRANSACTION, - MONGOC_ERROR_TRANSACTION_INVALID_STATE, - "Transactions do not support unacknowledged write concern"); - - returned_sopt = mongoc_client_session_get_opts (session); - returned_topt = - mongoc_session_opts_get_default_transaction_opts (returned_sopt); - returned_rc = mongoc_transaction_opts_get_read_concern (returned_topt); - returned_rp = mongoc_transaction_opts_get_read_prefs (returned_topt); - returned_wc = mongoc_transaction_opts_get_write_concern (returned_topt); - - BSON_ASSERT (strcmp (mongoc_read_concern_get_level (returned_rc), - mongoc_read_concern_get_level (rc)) == 0); - BSON_ASSERT (mongoc_write_concern_get_w (returned_wc) == - mongoc_write_concern_get_w (wc)); - BSON_ASSERT (mongoc_read_prefs_get_mode (returned_rp) == - mongoc_read_prefs_get_mode (rp)); - - mongoc_read_concern_destroy (rc); - mongoc_read_prefs_destroy (rp); - mongoc_write_concern_destroy (wc); - mongoc_transaction_opts_destroy (topt); - mongoc_session_opts_destroy (sopt); - mongoc_client_session_destroy (session); - mongoc_uri_destroy (uri); - mongoc_client_destroy (client); -} - -void -test_transaction_fails_on_unsupported_version_or_sharded_cluster (void *ctx) -{ - bson_error_t error; - mongoc_client_session_t *session; - mongoc_client_t *client; - bool r; - - client = test_framework_client_new (); - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - - r = mongoc_client_session_start_transaction (session, NULL, &error); - if (!test_framework_max_wire_version_at_least (7) || - (test_framework_is_mongos () && - !test_framework_max_wire_version_at_least (8))) { - BSON_ASSERT (!r); - ASSERT_CONTAINS (error.message, - "Multi-document transactions are not supported by this " - "server version"); - } else { - ASSERT_OR_PRINT (r, error); - } - - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); -} - - -static void -test_transaction_recovery_token_cleared (void *ctx) -{ - bson_error_t error; - mongoc_client_session_t *session; - mongoc_client_t *client; - mongoc_collection_t *coll; - mongoc_uri_t *uri; - bson_t txn_opts; - - uri = test_framework_get_uri (); - ASSERT_OR_PRINT ( - mongoc_uri_upsert_host_and_port (uri, "localhost:27018", &error), error); - client = mongoc_client_new_from_uri (uri); - mongoc_uri_destroy (uri); - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - coll = get_test_collection (client, "transaction_test"); - - mongoc_client_command_with_opts (client, - "admin", - tmp_bson ("{'killAllSessions': []}"), - NULL, - NULL, - NULL, - &error); - /* Create the collection by inserting a canary document. You cannot create - * inside a transaction */ - ASSERT_OR_PRINT ( - mongoc_collection_insert_one (coll, tmp_bson ("{}"), NULL, NULL, &error), - error); - - bson_init (&txn_opts); - ASSERT_OR_PRINT (mongoc_client_session_append (session, &txn_opts, &error), - error); - - ASSERT_OR_PRINT ( - mongoc_client_session_start_transaction (session, NULL, &error), error); - - /* Initially no recovery token. */ - BSON_ASSERT (!session->recovery_token); - mongoc_collection_insert_one ( - coll, tmp_bson ("{}"), &txn_opts, NULL, &error); - BSON_ASSERT (session->recovery_token); - ASSERT_OR_PRINT ( - mongoc_client_session_commit_transaction (session, NULL, &error), error); - BSON_ASSERT (session->recovery_token); - - /* Starting a new transaction clears the recovery token. */ - ASSERT_OR_PRINT ( - mongoc_client_session_start_transaction (session, NULL, &error), error); - BSON_ASSERT (!session->recovery_token); - - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{}"), &txn_opts, NULL, &error), - error); - BSON_ASSERT (session->recovery_token); - ASSERT_OR_PRINT ( - mongoc_client_session_commit_transaction (session, NULL, &error), error); - BSON_ASSERT (session->recovery_token); - - /* Transitioning to the "none" state (i.e. a new operation outside of a - * transaction), clears the recovery token */ - ASSERT_OR_PRINT (mongoc_collection_insert_one ( - coll, tmp_bson ("{}"), &txn_opts, NULL, &error), - error); - BSON_ASSERT (!session->recovery_token); - - bson_destroy (&txn_opts); - mongoc_collection_destroy (coll); - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); -} - -static void -test_selected_server_is_pinned_to_mongos (void *ctx) -{ - mongoc_uri_t *uri = NULL; - mongoc_client_t *client = NULL; - mongoc_set_t *servers = NULL; - mongoc_transaction_opt_t *txn_opts = NULL; - mongoc_session_opt_t *session_opts = NULL; - mongoc_client_session_t *session = NULL; - mongoc_server_stream_t *server_stream = NULL; - bson_error_t error; - bson_t reply; - bson_t *insert_opts = NULL; - mongoc_database_t *db = NULL; - mongoc_collection_t *coll = NULL; - bool r; - uint32_t expected_id; - uint32_t actual_id; - mongoc_server_description_t *sd = NULL; - int i; - - uri = test_framework_get_uri (); - ASSERT_OR_PRINT ( - mongoc_uri_upsert_host_and_port (uri, "localhost:27018", &error), error); - - client = mongoc_client_new_from_uri (uri); - BSON_ASSERT (client); - - txn_opts = mongoc_transaction_opts_new (); - session_opts = mongoc_session_opts_new (); - - session = mongoc_client_start_session (client, session_opts, &error); - ASSERT_OR_PRINT (session, error); - - /* set the server id to an arbitrary value */ - _mongoc_client_session_pin (session, 42); - BSON_ASSERT (42 == mongoc_client_session_get_server_id (session)); - - /* starting a transaction should clear the server id */ - r = mongoc_client_session_start_transaction (session, txn_opts, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (0 == mongoc_client_session_get_server_id (session)); - - expected_id = mongoc_topology_select_server_id ( - client->topology, MONGOC_SS_WRITE, NULL, &error); - ASSERT_OR_PRINT (expected_id, error); - - /* session should still be unpinned */ - BSON_ASSERT (0 == mongoc_client_session_get_server_id (session)); - - /* should pin to the expected server id */ - server_stream = mongoc_cluster_stream_for_server ( - &client->cluster, expected_id, true, session, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - ASSERT_CMPINT32 ( - expected_id, ==, mongoc_client_session_get_server_id (session)); - - db = mongoc_client_get_database (client, "db"); - coll = mongoc_database_create_collection (db, "coll", NULL, &error); - - insert_opts = bson_new (); - r = mongoc_client_session_append (session, insert_opts, &error); - ASSERT_OR_PRINT (r, error); - - /* this should not override the expected server id */ - r = mongoc_collection_insert_one ( - coll, tmp_bson ("{}"), insert_opts, NULL, &error); - ASSERT_OR_PRINT (r, error); - actual_id = mongoc_client_session_get_server_id (session); - - ASSERT_CMPINT32 (actual_id, ==, expected_id); - - /* get a valid server id that's different from the pinned server id */ - servers = client->topology->description.servers; - for (i = 0; i < servers->items_len; i++) { - sd = (mongoc_server_description_t *) mongoc_set_get_item (servers, i); - if (sd && sd->id != actual_id) { - break; - } - } - - /* attempting to pin to a different but valid server id should fail */ - BSON_ASSERT (sd); - r = mongoc_client_command_with_opts ( - client, - "db", - tmp_bson ("{'ping': 1}"), - NULL, - tmp_bson ("{'serverId': %d, 'sessionId': {'$numberLong': '%ld'}}", - sd->id, - session->client_session_id), - &reply, - &error); - - BSON_ASSERT (!r); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_SERVER_SELECTION_INVALID_ID, - "Requested server id does not matched pinned server id"); - - r = mongoc_client_session_abort_transaction (session, &error); - ASSERT_OR_PRINT (r, error); - - bson_destroy (insert_opts); - bson_destroy (&reply); - mongoc_collection_destroy (coll); - mongoc_database_destroy (db); - mongoc_session_opts_destroy (session_opts); - mongoc_transaction_opts_destroy (txn_opts); - mongoc_server_stream_cleanup (server_stream); - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); -} - -static void -test_get_transaction_opts (void) -{ - mongoc_uri_t *uri = NULL; - mongoc_client_t *client = NULL; - mongoc_client_session_t *session = NULL; - mongoc_transaction_opt_t *expected_txn_opts = NULL; - mongoc_transaction_opt_t *actual_txn_opts = NULL; - mongoc_session_opt_t *session_opts = NULL; - mongoc_read_concern_t *read_concern = NULL; - mongoc_write_concern_t *write_concern = NULL; - mongoc_read_prefs_t *read_prefs = NULL; - mock_server_t *server = NULL; - int64_t max_commit_time_ms = 123; /* arbitrary */ - bson_error_t error; - bool r; - - server = mock_server_new (); - mock_server_run (server); - rs_response_to_ismaster ( - server, 7, true /* primary */, false /* tags */, server, NULL); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - BSON_ASSERT (client); - - read_concern = mongoc_read_concern_new (); - mongoc_read_concern_set_level (read_concern, "snapshot"); - - write_concern = mongoc_write_concern_new (); - mongoc_write_concern_set_w (write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY); - - read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - - expected_txn_opts = mongoc_transaction_opts_new (); - - mongoc_transaction_opts_set_read_concern (expected_txn_opts, read_concern); - mongoc_transaction_opts_set_write_concern (expected_txn_opts, write_concern); - mongoc_transaction_opts_set_read_prefs (expected_txn_opts, read_prefs); - mongoc_transaction_opts_set_max_commit_time_ms (expected_txn_opts, - max_commit_time_ms); - - session_opts = mongoc_session_opts_new (); - session = mongoc_client_start_session (client, session_opts, &error); - ASSERT_OR_PRINT (session, error); - /* outside of a txn this function should return NULL */ - BSON_ASSERT (!mongoc_session_opts_get_transaction_opts (session)); - - r = mongoc_client_session_start_transaction ( - session, expected_txn_opts, &error); - ASSERT_OR_PRINT (r, error); - - actual_txn_opts = mongoc_session_opts_get_transaction_opts (session); - BSON_ASSERT (actual_txn_opts); - BSON_ASSERT ( - 0 == bson_compare ( - _mongoc_read_concern_get_bson (actual_txn_opts->read_concern), - _mongoc_read_concern_get_bson (expected_txn_opts->read_concern))); - - BSON_ASSERT (0 == bson_compare (_mongoc_write_concern_get_bson ( - actual_txn_opts->write_concern), - _mongoc_write_concern_get_bson ( - expected_txn_opts->write_concern))); - - BSON_ASSERT (mongoc_read_prefs_get_mode (actual_txn_opts->read_prefs) == - mongoc_read_prefs_get_mode (expected_txn_opts->read_prefs)); - - BSON_ASSERT (actual_txn_opts->max_commit_time_ms == - expected_txn_opts->max_commit_time_ms); - - r = mongoc_client_session_abort_transaction (session, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (!mongoc_session_opts_get_transaction_opts (session)); - - mongoc_read_concern_destroy (read_concern); - mongoc_write_concern_destroy (write_concern); - mongoc_read_prefs_destroy (read_prefs); - mongoc_transaction_opts_destroy (expected_txn_opts); - mongoc_transaction_opts_destroy (actual_txn_opts); - mongoc_session_opts_destroy (session_opts); - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_server_destroy (server); -} - -static void -test_max_commit_time_ms_is_reset (void *ctx) -{ - mock_rs_t *rs; - mongoc_uri_t *uri = NULL; - mongoc_client_t *client = NULL; - mongoc_transaction_opt_t *txn_opts = NULL; - mongoc_session_opt_t *session_opts = NULL; - mongoc_client_session_t *session = NULL; - bson_error_t error; - bool r; - - rs = mock_rs_with_autoismaster (WIRE_VERSION_4_2, - true /* has primary */, - 2 /* secondaries */, - 0 /* arbiters */); - - mock_rs_run (rs); - uri = mongoc_uri_copy (mock_rs_get_uri (rs)); - - client = mongoc_client_new_from_uri (uri); - BSON_ASSERT (client); - - txn_opts = mongoc_transaction_opts_new (); - session_opts = mongoc_session_opts_new (); - - session = mongoc_client_start_session (client, session_opts, &error); - ASSERT_OR_PRINT (session, error); - - mongoc_transaction_opts_set_max_commit_time_ms (txn_opts, 1); - - r = mongoc_client_session_start_transaction (session, txn_opts, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (1 == session->txn.opts.max_commit_time_ms); - - r = mongoc_client_session_abort_transaction (session, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (DEFAULT_MAX_COMMIT_TIME_MS == - session->txn.opts.max_commit_time_ms); - - mongoc_transaction_opts_set_max_commit_time_ms (txn_opts, - DEFAULT_MAX_COMMIT_TIME_MS); - - r = mongoc_client_session_start_transaction (session, txn_opts, &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (DEFAULT_MAX_COMMIT_TIME_MS == - session->txn.opts.max_commit_time_ms); - - r = mongoc_client_session_abort_transaction (session, &error); - ASSERT_OR_PRINT (r, error); - - mongoc_session_opts_destroy (session_opts); - mongoc_transaction_opts_destroy (txn_opts); - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - mock_rs_destroy (rs); -} - -void -test_transactions_install (TestSuite *suite) -{ - char resolved[PATH_MAX]; - - ASSERT (realpath (JSON_DIR "/transactions", resolved)); - install_json_test_suite_with_check ( - suite, resolved, test_transactions_cb, test_framework_skip_if_no_txns); - - test_framework_resolve_path (JSON_DIR "/with_transaction", resolved); - install_json_test_suite_with_check ( - suite, resolved, test_transactions_cb, test_framework_skip_if_no_txns); - - 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_AddMockServerTest (suite, - "/transactions/server_selection_err", - test_server_selection_error, - test_framework_skip_if_no_crypto); - TestSuite_AddMockServerTest (suite, - "/transactions/network_err", - test_network_error, - test_framework_skip_if_no_crypto); - 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", - 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/" - "transaction_fails_on_unsupported_version_or_sharded_cluster", - test_transaction_fails_on_unsupported_version_or_sharded_cluster, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto); - TestSuite_AddFull (suite, - "/transactions/recovery_token_cleared", - test_transaction_recovery_token_cleared, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto, - test_framework_skip_if_max_wire_version_less_than_8, - test_framework_skip_if_not_mongos); - TestSuite_AddFull (suite, - "/transactions/selected_server_pinned_to_mongos", - test_selected_server_is_pinned_to_mongos, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_max_wire_version_less_than_8, - test_framework_skip_if_not_mongos); - TestSuite_AddMockServerTest (suite, - "/transactions/get_transaction_opts", - test_get_transaction_opts, - test_framework_skip_if_no_crypto); - TestSuite_AddFull (suite, - "/transactions/max_commit_time_ms_is_reset", - test_max_commit_time_ms_is_reset, - NULL, - NULL, - test_framework_skip_if_no_crypto); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-uri.c b/lib/mongoc/libmongoc/tests/test-mongoc-uri.c deleted file mode 100644 index 23aa004c5d88f208945f59a297d5b16f57d0890a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-uri.c +++ /dev/null @@ -1,2625 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-util-private.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-topology-private.h" -#include "mongoc/mongoc-uri-private.h" -#include "mongoc/mongoc-host-list-private.h" - -#include "TestSuite.h" - -#include "test-libmongoc.h" -#include "test-conveniences.h" - -#ifdef _WIN32 -#define snprintf _snprintf -#endif - -static void -test_mongoc_uri_new (void) -{ - const mongoc_host_list_t *hosts; - const bson_t *options; - const bson_t *credentials; - const bson_t *read_prefs_tags; - const mongoc_read_prefs_t *read_prefs; - bson_t properties; - mongoc_uri_t *uri; - bson_iter_t iter; - bson_iter_t child; - - capture_logs (true); - - /* bad uris */ - ASSERT (!mongoc_uri_new ("mongodb://")); - ASSERT (!mongoc_uri_new ("mongodb://\x80")); - ASSERT (!mongoc_uri_new ("mongodb://localhost/\x80")); - ASSERT (!mongoc_uri_new ("mongodb://localhost:\x80/")); - ASSERT (!mongoc_uri_new ("mongodb://localhost/?ipv6=\x80")); - ASSERT (!mongoc_uri_new ("mongodb://localhost/?foo=\x80")); - ASSERT (!mongoc_uri_new ("mongodb://localhost/?\x80=bar")); - ASSERT (!mongoc_uri_new ("mongodb://\x80:pass@localhost")); - ASSERT (!mongoc_uri_new ("mongodb://user:\x80@localhost")); - ASSERT (!mongoc_uri_new ("mongodb://user%40DOMAIN.COM:password@localhost/" - "?" MONGOC_URI_AUTHMECHANISM "=\x80")); - ASSERT (!mongoc_uri_new ("mongodb://user%40DOMAIN.COM:password@localhost/" - "?" MONGOC_URI_AUTHMECHANISM - "=GSSAPI&" MONGOC_URI_AUTHMECHANISMPROPERTIES - "=SERVICE_NAME:\x80")); - ASSERT (!mongoc_uri_new ("mongodb://user%40DOMAIN.COM:password@localhost/" - "?" MONGOC_URI_AUTHMECHANISM - "=GSSAPI&" MONGOC_URI_AUTHMECHANISMPROPERTIES - "=\x80:mongodb")); - ASSERT (!mongoc_uri_new ("mongodb://::")); - ASSERT (!mongoc_uri_new ("mongodb://[::1]::27017/")); - ASSERT (!mongoc_uri_new ("mongodb://localhost::27017")); - ASSERT (!mongoc_uri_new ("mongodb://localhost,localhost::")); - ASSERT (!mongoc_uri_new ("mongodb://local1,local2,local3/d?k")); - ASSERT (!mongoc_uri_new ("")); - ASSERT (!mongoc_uri_new ("mongodb://,localhost:27017")); - ASSERT (!mongoc_uri_new ("mongodb://localhost:27017,,b")); - ASSERT (!mongoc_uri_new ("mongo://localhost:27017")); - ASSERT (!mongoc_uri_new ("mongodb://localhost::27017")); - ASSERT (!mongoc_uri_new ("mongodb://localhost::27017/")); - ASSERT (!mongoc_uri_new ("mongodb://localhost::27017,abc")); - ASSERT (!mongoc_uri_new ("mongodb://localhost:-1")); - ASSERT (!mongoc_uri_new ("mongodb://localhost:65536")); - ASSERT (!mongoc_uri_new ("mongodb://localhost:foo")); - ASSERT (!mongoc_uri_new ("mongodb://localhost:65536/")); - ASSERT (!mongoc_uri_new ("mongodb://localhost:0/")); - ASSERT (!mongoc_uri_new ("mongodb://[::1%lo0]")); - ASSERT (!mongoc_uri_new ("mongodb://[::1]:-1")); - ASSERT (!mongoc_uri_new ("mongodb://[::1]:foo")); - ASSERT (!mongoc_uri_new ("mongodb://[::1]:65536")); - ASSERT (!mongoc_uri_new ("mongodb://[::1]:65536/")); - ASSERT (!mongoc_uri_new ("mongodb://[::1]:0/")); - ASSERT (!mongoc_uri_new ("mongodb://localhost:27017/test?replicaset=")); - - uri = mongoc_uri_new ( - "mongodb://[::1]:27888,[::2]:27999/?ipv6=true&" MONGOC_URI_SAFE "=true"); - BSON_ASSERT (uri); - hosts = mongoc_uri_get_hosts (uri); - BSON_ASSERT (hosts); - ASSERT_CMPSTR (hosts->host, "::1"); - BSON_ASSERT (hosts->port == 27888); - ASSERT_CMPSTR (hosts->host_and_port, "[::1]:27888"); - mongoc_uri_destroy (uri); - - /* should recognize IPv6 "scope" like "::1%lo0", with % escaped */ - uri = mongoc_uri_new ("mongodb://[::1%25lo0]"); - BSON_ASSERT (uri); - hosts = mongoc_uri_get_hosts (uri); - BSON_ASSERT (hosts); - ASSERT_CMPSTR (hosts->host, "::1%lo0"); - BSON_ASSERT (hosts->port == 27017); - ASSERT_CMPSTR (hosts->host_and_port, "[::1%lo0]:27017"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://%2Ftmp%2Fmongodb-27017.sock/?"); - ASSERT (uri); - mongoc_uri_destroy (uri); - - /* should normalize to lowercase */ - uri = mongoc_uri_new ("mongodb://cRaZyHoStNaMe"); - BSON_ASSERT (uri); - hosts = mongoc_uri_get_hosts (uri); - BSON_ASSERT (hosts); - ASSERT_CMPSTR (hosts->host, "crazyhostname"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/?"); - ASSERT (uri); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost:27017/test?replicaset=foo"); - ASSERT (uri); - hosts = mongoc_uri_get_hosts (uri); - ASSERT (hosts); - ASSERT (!hosts->next); - ASSERT_CMPSTR (hosts->host, "localhost"); - ASSERT_CMPINT (hosts->port, ==, 27017); - ASSERT_CMPSTR (hosts->host_and_port, "localhost:27017"); - ASSERT_CMPSTR (mongoc_uri_get_database (uri), "test"); - options = mongoc_uri_get_options (uri); - ASSERT (options); - ASSERT (bson_iter_init_find (&iter, options, "replicaset")); - ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL), "foo"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://local1,local2:999,local3/?replicaset=foo"); - ASSERT (uri); - hosts = mongoc_uri_get_hosts (uri); - ASSERT (hosts); - ASSERT (hosts->next); - ASSERT (hosts->next->next); - ASSERT (!hosts->next->next->next); - ASSERT_CMPSTR (hosts->host, "local1"); - ASSERT_CMPINT (hosts->port, ==, 27017); - ASSERT_CMPSTR (hosts->next->host, "local2"); - ASSERT_CMPINT (hosts->next->port, ==, 999); - ASSERT_CMPSTR (hosts->next->next->host, "local3"); - ASSERT_CMPINT (hosts->next->next->port, ==, 27017); - options = mongoc_uri_get_options (uri); - ASSERT (options); - ASSERT (bson_iter_init_find (&iter, options, "replicaset")); - ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL), "foo"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost:27017/" - "?" MONGOC_URI_READPREFERENCE - "=secondaryPreferred&" MONGOC_URI_READPREFERENCETAGS - "=dc:ny&" MONGOC_URI_READPREFERENCETAGS "="); - ASSERT (uri); - read_prefs = mongoc_uri_get_read_prefs_t (uri); - ASSERT (mongoc_read_prefs_get_mode (read_prefs) == - MONGOC_READ_SECONDARY_PREFERRED); - ASSERT (read_prefs); - read_prefs_tags = mongoc_read_prefs_get_tags (read_prefs); - ASSERT (read_prefs_tags); - ASSERT_CMPINT (bson_count_keys (read_prefs_tags), ==, 2); - ASSERT (bson_iter_init_find (&iter, read_prefs_tags, "0")); - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - ASSERT (bson_iter_recurse (&iter, &child)); - ASSERT (bson_iter_next (&child)); - ASSERT_CMPSTR (bson_iter_key (&child), "dc"); - ASSERT_CMPSTR (bson_iter_utf8 (&child, NULL), "ny"); - ASSERT (!bson_iter_next (&child)); - ASSERT (bson_iter_next (&iter)); - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - ASSERT (bson_iter_recurse (&iter, &child)); - ASSERT (!bson_iter_next (&child)); - ASSERT (!bson_iter_next (&iter)); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/a?" MONGOC_URI_SLAVEOK - "=true&" MONGOC_URI_TLS "=false&" MONGOC_URI_JOURNAL - "=true"); - options = mongoc_uri_get_options (uri); - ASSERT (options); - ASSERT_CMPINT (bson_count_keys (options), ==, 3); - ASSERT (bson_iter_init (&iter, options)); - ASSERT (bson_iter_find_case (&iter, "" MONGOC_URI_SLAVEOK "")); - ASSERT (BSON_ITER_HOLDS_BOOL (&iter)); - ASSERT (bson_iter_bool (&iter)); - ASSERT (bson_iter_find_case (&iter, MONGOC_URI_TLS)); - ASSERT (BSON_ITER_HOLDS_BOOL (&iter)); - ASSERT (!bson_iter_bool (&iter)); - ASSERT (bson_iter_find_case (&iter, MONGOC_URI_JOURNAL)); - ASSERT (BSON_ITER_HOLDS_BOOL (&iter)); - ASSERT (bson_iter_bool (&iter)); - ASSERT (!bson_iter_next (&iter)); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_SAFE - "=false&" MONGOC_URI_JOURNAL "=false"); - options = mongoc_uri_get_options (uri); - ASSERT (options); - ASSERT_CMPINT (bson_count_keys (options), ==, 2); - ASSERT (bson_iter_init (&iter, options)); - ASSERT (bson_iter_find_case (&iter, "" MONGOC_URI_SAFE "")); - ASSERT (BSON_ITER_HOLDS_BOOL (&iter)); - ASSERT (!bson_iter_bool (&iter)); - ASSERT (bson_iter_find_case (&iter, MONGOC_URI_JOURNAL)); - ASSERT (BSON_ITER_HOLDS_BOOL (&iter)); - ASSERT (!bson_iter_bool (&iter)); - ASSERT (!bson_iter_next (&iter)); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ( - "mongodb://%2Ftmp%2Fmongodb-27017.sock/?" MONGOC_URI_TLS "=false"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->host, "/tmp/mongodb-27017.sock"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ( - "mongodb://%2Ftmp%2Fmongodb-27017.sock,localhost:27017/?" MONGOC_URI_TLS - "=false"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->host, "/tmp/mongodb-27017.sock"); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->next->host_and_port, - "localhost:27017"); - ASSERT (!mongoc_uri_get_hosts (uri)->next->next); - mongoc_uri_destroy (uri); - - /* should assign port numbers to correct hosts */ - uri = mongoc_uri_new ("mongodb://host1,host2:30000/foo"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->host_and_port, "host1:27017"); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->next->host_and_port, - "host2:30000"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ( - "mongodb://localhost:27017,%2Ftmp%2Fmongodb-27017.sock/?" MONGOC_URI_TLS - "=false"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->host_and_port, "localhost:27017"); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->next->host, - "/tmp/mongodb-27017.sock"); - ASSERT (!mongoc_uri_get_hosts (uri)->next->next); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_HEARTBEATFREQUENCYMS - "=600"); - ASSERT (uri); - ASSERT_CMPINT32 ( - 600, - ==, - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 0)); - - mongoc_uri_destroy (uri); - - /* heartbeat frequency too short */ - ASSERT (!mongoc_uri_new ( - "mongodb://localhost/?" MONGOC_URI_HEARTBEATFREQUENCYMS "=499")); - - /* should use the " MONGOC_URI_AUTHSOURCE " over db when both are specified - */ - uri = mongoc_uri_new ( - "mongodb://christian:secret@localhost:27017/foo?" MONGOC_URI_AUTHSOURCE - "=abcd"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_username (uri), "christian"); - ASSERT_CMPSTR (mongoc_uri_get_password (uri), "secret"); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), "abcd"); - mongoc_uri_destroy (uri); - - /* should use the default auth source and mechanism */ - uri = mongoc_uri_new ("mongodb://christian:secret@localhost:27017"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), "admin"); - ASSERT (!mongoc_uri_get_auth_mechanism (uri)); - mongoc_uri_destroy (uri); - - /* should use the db when no " MONGOC_URI_AUTHSOURCE " is specified */ - uri = mongoc_uri_new ("mongodb://user:password@localhost/foo"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), "foo"); - mongoc_uri_destroy (uri); - - /* should recognize an empty password */ - uri = mongoc_uri_new ("mongodb://samantha:@localhost"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_username (uri), "samantha"); - ASSERT_CMPSTR (mongoc_uri_get_password (uri), ""); - mongoc_uri_destroy (uri); - - /* should recognize no password */ - uri = mongoc_uri_new ("mongodb://christian@localhost:27017"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_username (uri), "christian"); - ASSERT (!mongoc_uri_get_password (uri)); - mongoc_uri_destroy (uri); - - /* should recognize a url escaped character in the username */ - uri = mongoc_uri_new ("mongodb://christian%40realm:pwd@localhost:27017"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_username (uri), "christian@realm"); - mongoc_uri_destroy (uri); - - /* should fail on invalid escaped characters */ - capture_logs (true); - uri = mongoc_uri_new ("mongodb://u%ser:pwd@localhost:27017"); - ASSERT (!uri); - ASSERT_CAPTURED_LOG ( - "uri", MONGOC_LOG_LEVEL_WARNING, "Invalid % escape sequence"); - - uri = mongoc_uri_new ("mongodb://user:p%wd@localhost:27017"); - ASSERT (!uri); - ASSERT_CAPTURED_LOG ( - "uri", MONGOC_LOG_LEVEL_WARNING, "Invalid % escape sequence"); - - uri = mongoc_uri_new ("mongodb://user:pwd@local% host:27017"); - ASSERT (!uri); - ASSERT_CAPTURED_LOG ( - "uri", MONGOC_LOG_LEVEL_WARNING, "Invalid % escape sequence"); - - uri = mongoc_uri_new ( - "mongodb://christian%40realm@localhost:27017/?replicaset=%20"); - ASSERT (uri); - options = mongoc_uri_get_options (uri); - ASSERT (options); - ASSERT (bson_iter_init_find (&iter, options, "replicaset")); - ASSERT (BSON_ITER_HOLDS_UTF8 (&iter)); - ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL), " "); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ( - "mongodb://christian%40realm@[::6]:27017/?replicaset=%20"); - ASSERT (uri); - options = mongoc_uri_get_options (uri); - ASSERT (options); - ASSERT (bson_iter_init_find (&iter, options, "replicaset")); - ASSERT (BSON_ITER_HOLDS_UTF8 (&iter)); - ASSERT_CMPSTR (bson_iter_utf8 (&iter, NULL), " "); - mongoc_uri_destroy (uri); - - /* GSSAPI-specific options */ - - /* should recognize the GSSAPI mechanism, and use $external as source */ - uri = mongoc_uri_new ("mongodb://user%40DOMAIN.COM:password@localhost/" - "?" MONGOC_URI_AUTHMECHANISM "=GSSAPI"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "GSSAPI"); - /*ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external");*/ - mongoc_uri_destroy (uri); - - /* use $external as source when db is specified */ - uri = mongoc_uri_new ("mongodb://user%40DOMAIN.COM:password@localhost/foo" - "?" MONGOC_URI_AUTHMECHANISM "=GSSAPI"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), "$external"); - mongoc_uri_destroy (uri); - - /* should not accept " MONGOC_URI_AUTHSOURCE " other than $external */ - ASSERT (!mongoc_uri_new ("mongodb://user%40DOMAIN.COM:password@localhost/" - "foo?" MONGOC_URI_AUTHMECHANISM - "=GSSAPI&" MONGOC_URI_AUTHSOURCE "=bar")); - - /* should accept MONGOC_URI_AUTHMECHANISMPROPERTIES */ - uri = mongoc_uri_new ("mongodb://user%40DOMAIN.COM:password@localhost/" - "?" MONGOC_URI_AUTHMECHANISM - "=GSSAPI&" MONGOC_URI_AUTHMECHANISMPROPERTIES - "=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:" - "true"); - ASSERT (uri); - credentials = mongoc_uri_get_credentials (uri); - ASSERT (credentials); - ASSERT (mongoc_uri_get_mechanism_properties (uri, &properties)); - BSON_ASSERT (bson_iter_init_find_case (&iter, &properties, "SERVICE_NAME") && - BSON_ITER_HOLDS_UTF8 (&iter) && - (0 == strcmp (bson_iter_utf8 (&iter, NULL), "other"))); - BSON_ASSERT ( - bson_iter_init_find_case (&iter, &properties, "CANONICALIZE_HOST_NAME") && - BSON_ITER_HOLDS_UTF8 (&iter) && - (0 == strcmp (bson_iter_utf8 (&iter, NULL), "true"))); - mongoc_uri_destroy (uri); - - /* reverse order of arguments to ensure parsing still succeeds */ - uri = mongoc_uri_new ( - "mongodb://user@localhost/?" MONGOC_URI_AUTHMECHANISMPROPERTIES - "=SERVICE_NAME:other&" MONGOC_URI_AUTHMECHANISM "=GSSAPI"); - ASSERT (uri); - mongoc_uri_destroy (uri); - - /* MONGODB-CR */ - - /* should recognize this mechanism */ - uri = mongoc_uri_new ("mongodb://user@localhost/?" MONGOC_URI_AUTHMECHANISM - "=MONGODB-CR"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "MONGODB-CR"); - mongoc_uri_destroy (uri); - - /* X509 */ - - /* should recognize this mechanism, and use $external as the source */ - uri = mongoc_uri_new ("mongodb://user@localhost/?" MONGOC_URI_AUTHMECHANISM - "=MONGODB-X509"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509"); - /*ASSERT_CMPSTR(mongoc_uri_get_auth_source(uri), "$external");*/ - mongoc_uri_destroy (uri); - - /* use $external as source when db is specified */ - uri = mongoc_uri_new ( - "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" - "%2CST%3DmyState%2CC%3DmyCountry@localhost/foo" - "?" MONGOC_URI_AUTHMECHANISM "=MONGODB-X509"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), "$external"); - mongoc_uri_destroy (uri); - - /* should not accept " MONGOC_URI_AUTHSOURCE " other than $external */ - ASSERT (!mongoc_uri_new ( - "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" - "%2CST%3DmyState%2CC%3DmyCountry@localhost/foo" - "?" MONGOC_URI_AUTHMECHANISM "=MONGODB-X509&" MONGOC_URI_AUTHSOURCE - "=bar")); - - /* should recognize the encoded username */ - uri = mongoc_uri_new ( - "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality" - "%2CST%3DmyState%2CC%3DmyCountry@localhost/?" MONGOC_URI_AUTHMECHANISM - "=MONGODB-X509"); - ASSERT (uri); - ASSERT_CMPSTR ( - mongoc_uri_get_username (uri), - "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry"); - mongoc_uri_destroy (uri); - - /* PLAIN */ - - /* should recognize this mechanism */ - uri = mongoc_uri_new ("mongodb://user@localhost/?" MONGOC_URI_AUTHMECHANISM - "=PLAIN"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "PLAIN"); - mongoc_uri_destroy (uri); - - /* SCRAM-SHA1 */ - - /* should recognize this mechanism */ - uri = mongoc_uri_new ("mongodb://user@localhost/?" MONGOC_URI_AUTHMECHANISM - "=SCRAM-SHA1"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "SCRAM-SHA1"); - mongoc_uri_destroy (uri); -} - - -static void -test_mongoc_uri_authmechanismproperties (void) -{ - mongoc_uri_t *uri; - bson_t props; - const bson_t *options; - - capture_logs (true); - - uri = mongoc_uri_new ("mongodb://user@localhost/?" MONGOC_URI_AUTHMECHANISM - "=SCRAM-SHA1" - "&" MONGOC_URI_AUTHMECHANISMPROPERTIES "=a:one,b:two"); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "SCRAM-SHA1"); - ASSERT (mongoc_uri_get_mechanism_properties (uri, &props)); - ASSERT_MATCH (&props, "{'a': 'one', 'b': 'two'}"); - - ASSERT (mongoc_uri_set_auth_mechanism (uri, "MONGODB-CR")); - ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "MONGODB-CR"); - - /* prohibited */ - ASSERT (!mongoc_uri_set_option_as_utf8 ( - uri, MONGOC_URI_AUTHMECHANISM, "SCRAM-SHA1")); - - ASSERT (!mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_AUTHMECHANISM, 1)); - ASSERT_CAPTURED_LOG ("setting authmechanism=1", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported value for \"authmechanism\": 1," - " \"authmechanism\" is not an int32 option"); - - ASSERT (!mongoc_uri_set_option_as_utf8 ( - uri, MONGOC_URI_AUTHMECHANISMPROPERTIES, "a:three")); - - ASSERT ( - mongoc_uri_set_mechanism_properties (uri, tmp_bson ("{'a': 'four'}"))); - - ASSERT (mongoc_uri_get_mechanism_properties (uri, &props)); - ASSERT_MATCH (&props, "{'a': 'four', 'b': {'$exists': false}}"); - - mongoc_uri_destroy (uri); - - /* deprecated gssapiServiceName option */ - uri = mongoc_uri_new ("mongodb://christian%40realm.cc@localhost:27017/" - "?" MONGOC_URI_AUTHMECHANISM - "=GSSAPI&" MONGOC_URI_GSSAPISERVICENAME "=blah"); - ASSERT (uri); - options = mongoc_uri_get_options (uri); - ASSERT (options); - BSON_ASSERT (0 == strcmp (mongoc_uri_get_auth_mechanism (uri), "GSSAPI")); - BSON_ASSERT (0 == - strcmp (mongoc_uri_get_username (uri), "christian@realm.cc")); - ASSERT (mongoc_uri_get_mechanism_properties (uri, &props)); - ASSERT_MATCH (&props, "{'SERVICE_NAME': 'blah'}"); - mongoc_uri_destroy (uri); -} - - -static void -test_mongoc_uri_functions (void) -{ - mongoc_client_t *client; - mongoc_uri_t *uri; - mongoc_database_t *db; - int32_t i; - - uri = mongoc_uri_new ( - "mongodb://foo:bar@localhost:27017/baz?" MONGOC_URI_AUTHSOURCE "=source"); - - ASSERT_CMPSTR (mongoc_uri_get_username (uri), "foo"); - ASSERT_CMPSTR (mongoc_uri_get_password (uri), "bar"); - ASSERT_CMPSTR (mongoc_uri_get_database (uri), "baz"); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), "source"); - - mongoc_uri_set_username (uri, "longer username that should work"); - ASSERT_CMPSTR (mongoc_uri_get_username (uri), - "longer username that should work"); - - mongoc_uri_set_password (uri, "longer password that should also work"); - ASSERT_CMPSTR (mongoc_uri_get_password (uri), - "longer password that should also work"); - - mongoc_uri_set_database (uri, "longer database that should work"); - ASSERT_CMPSTR (mongoc_uri_get_database (uri), - "longer database that should work"); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), "source"); - - mongoc_uri_set_auth_source (uri, "longer authsource that should work"); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), - "longer authsource that should work"); - ASSERT_CMPSTR (mongoc_uri_get_database (uri), - "longer database that should work"); - - client = mongoc_client_new_from_uri (uri); - mongoc_uri_destroy (uri); - - ASSERT_CMPSTR (mongoc_uri_get_username (client->uri), - "longer username that should work"); - ASSERT_CMPSTR (mongoc_uri_get_password (client->uri), - "longer password that should also work"); - ASSERT_CMPSTR (mongoc_uri_get_database (client->uri), - "longer database that should work"); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (client->uri), - "longer authsource that should work"); - mongoc_client_destroy (client); - - - uri = mongoc_uri_new ( - "mongodb://localhost/?" MONGOC_URI_SERVERSELECTIONTIMEOUTMS "=3" - "&" MONGOC_URI_JOURNAL "=true" - "&" MONGOC_URI_WTIMEOUTMS "=42" - "&" MONGOC_URI_CANONICALIZEHOSTNAME "=false"); - - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, "serverselectiontimeoutms", 18), - ==, - 3); - ASSERT ( - mongoc_uri_set_option_as_int32 (uri, "serverselectiontimeoutms", 18)); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, "serverselectiontimeoutms", 19), - ==, - 18); - - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 18), ==, 42); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 18), ==, 42); - ASSERT (mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 18)); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 19), ==, 18); - - ASSERT (mongoc_uri_set_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 20)); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 19), ==, 20); - - ASSERT (mongoc_uri_set_option_as_int32 ( - uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 500)); - - i = mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 1000); - - ASSERT_CMPINT32 (i, ==, 500); - - capture_logs (true); - - /* Server Discovery and Monitoring Spec: "the driver MUST NOT permit users to - * configure it less than minHeartbeatFrequencyMS (500ms)." */ - ASSERT (!mongoc_uri_set_option_as_int32 ( - uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 499)); - - ASSERT_CAPTURED_LOG ( - "mongoc_uri_set_option_as_int32", - MONGOC_LOG_LEVEL_WARNING, - "Invalid \"heartbeatfrequencyms\" of 499: must be at least 500"); - - /* socketcheckintervalms isn't set, return our fallback */ - ASSERT_CMPINT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 123), - ==, - 123); - ASSERT (mongoc_uri_set_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 18)); - ASSERT_CMPINT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 19), - ==, - 18); - - ASSERT (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_JOURNAL, false)); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_CANONICALIZEHOSTNAME, true)); - /* tls isn't set, return out fallback */ - ASSERT (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_TLS, true)); - - client = mongoc_client_new_from_uri (uri); - mongoc_uri_destroy (uri); - - ASSERT ( - mongoc_uri_get_option_as_bool (client->uri, MONGOC_URI_JOURNAL, false)); - ASSERT (!mongoc_uri_get_option_as_bool ( - client->uri, MONGOC_URI_CANONICALIZEHOSTNAME, true)); - /* tls isn't set, return out fallback */ - ASSERT (mongoc_uri_get_option_as_bool (client->uri, MONGOC_URI_TLS, true)); - mongoc_client_destroy (client); - - uri = mongoc_uri_new ("mongodb://localhost/"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 (uri, "replicaset", "default"), - "default"); - ASSERT (mongoc_uri_set_option_as_utf8 (uri, "replicaset", "value")); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 (uri, "replicaset", "default"), - "value"); - - mongoc_uri_destroy (uri); - - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_SOCKETTIMEOUTMS - "=1&" MONGOC_URI_SOCKETCHECKINTERVALMS "=200"); - ASSERT_CMPINT ( - 1, - ==, - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_SOCKETTIMEOUTMS, 0)); - ASSERT_CMPINT (200, - ==, - mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 0)); - - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_SOCKETTIMEOUTMS, 2); - ASSERT_CMPINT ( - 2, - ==, - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_SOCKETTIMEOUTMS, 0)); - - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 202); - ASSERT_CMPINT (202, - ==, - mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 0)); - - - client = mongoc_client_new_from_uri (uri); - ASSERT_CMPINT (2, ==, client->cluster.sockettimeoutms); - ASSERT_CMPINT (202, ==, client->cluster.socketcheckintervalms); - - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - - - uri = mongoc_uri_new ("mongodb://host/dbname0"); - ASSERT_CMPSTR (mongoc_uri_get_database (uri), "dbname0"); - mongoc_uri_set_database (uri, "dbname1"); - client = mongoc_client_new_from_uri (uri); - db = mongoc_client_get_default_database (client); - ASSERT_CMPSTR (mongoc_database_get_name (db), "dbname1"); - - mongoc_database_destroy (db); - mongoc_client_destroy (client); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://%2Ftmp%2FMongoDB-27017.sock/"); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->host, "/tmp/MongoDB-27017.sock"); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->host_and_port, - "/tmp/MongoDB-27017.sock"); - - mongoc_uri_destroy (uri); - - capture_logs (true); - uri = mongoc_uri_new ("mongodb://host/?foobar=1"); - ASSERT (uri); - ASSERT_CAPTURED_LOG ("setting URI option foobar=1", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported URI option \"foobar\""); - - mongoc_uri_destroy (uri); -} - -static void -test_mongoc_uri_new_with_error (void) -{ - bson_error_t error = {0}; - mongoc_uri_t *uri; - - capture_logs (true); - ASSERT (!mongoc_uri_new_with_error ("mongodb://", NULL)); - uri = mongoc_uri_new_with_error ("mongodb://localhost", NULL); - ASSERT (uri); - mongoc_uri_destroy (uri); - - ASSERT (!mongoc_uri_new_with_error ("mongodb://", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid host string in URI"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ("mongo://localhost", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid URI Schema, expecting 'mongodb://'"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ( - "mongodb://localhost/?readPreference=unknown", &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Unsupported readPreference value [readPreference=unknown]"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ( - "mongodb://localhost/" - "?appname=" - "WayTooLongAppnameToBeValidSoThisShouldResultInAnErrorWayToLongAppnameToB" - "eValidSoThisShouldResultInAnErrorWayToLongAppnameToBeValidSoThisShouldRe" - "sultInAnError", - &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Unsupported value for \"appname\""); /* ... */ - - uri = mongoc_uri_new ("mongodb://localhost"); - ASSERT (!mongoc_uri_set_option_as_utf8 ( - uri, - MONGOC_URI_APPNAME, - "WayTooLongAppnameToBeValidSoThisShouldResultInAnErrorWayToLongAppnameToB" - "eValidSoThisShouldResultInAnErrorWayToLongAppnameToBeValidSoThisShouldRe" - "sultInAnError")); - mongoc_uri_destroy (uri); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT ( - !mongoc_uri_new_with_error ("mongodb://user%p:pass@localhost/", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Incorrect URI escapes in username. Percent-encode " - "username and password according to RFC 3986"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ("mongodb://l%oc, alhost/", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid host string in URI"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ("mongodb:///tmp/mongodb.sock", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid host string in URI") - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ("mongodb://localhost/db.na%me", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid database name in URI"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ( - "mongodb://localhost/db?journal=true&w=0", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Journal conflicts with w value [w=0]"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ( - "mongodb://localhost/db?journal=true&w=-1", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Journal conflicts with w value [w=-1]"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ("mongodb://localhost/db?w=-5", &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Unsupported w value [w=-5]"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ( - "mongodb://localhost/db?heartbeatfrequencyms=10", &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid \"heartbeatfrequencyms\" of 10: must be at least 500"); - - memset (&error, 0, sizeof (bson_error_t)); - ASSERT (!mongoc_uri_new_with_error ( - "mongodb://localhost/db?zlibcompressionlevel=10", &error)); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid \"zlibcompressionlevel\" of 10: must be between -1 and 9"); -} - - -#undef ASSERT_SUPPRESS - - -static void -test_mongoc_uri_compound_setters (void) -{ - mongoc_uri_t *uri; - mongoc_read_prefs_t *prefs; - const mongoc_read_prefs_t *prefs_result; - mongoc_read_concern_t *rc; - const mongoc_read_concern_t *rc_result; - mongoc_write_concern_t *wc; - const mongoc_write_concern_t *wc_result; - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_READPREFERENCE - "=nearest&" MONGOC_URI_READPREFERENCETAGS - "=dc:ny&" MONGOC_URI_READCONCERNLEVEL - "=majority&" MONGOC_URI_W "=3"); - - prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); - mongoc_uri_set_read_prefs_t (uri, prefs); - prefs_result = mongoc_uri_get_read_prefs_t (uri); - ASSERT_CMPINT ( - mongoc_read_prefs_get_mode (prefs_result), ==, MONGOC_READ_SECONDARY); - ASSERT (bson_empty (mongoc_read_prefs_get_tags (prefs_result))); - - rc = mongoc_read_concern_new (); - mongoc_read_concern_set_level (rc, "whatever"); - mongoc_uri_set_read_concern (uri, rc); - rc_result = mongoc_uri_get_read_concern (uri); - ASSERT_CMPSTR (mongoc_read_concern_get_level (rc_result), "whatever"); - - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 2); - mongoc_uri_set_write_concern (uri, wc); - wc_result = mongoc_uri_get_write_concern (uri); - ASSERT_CMPINT32 (mongoc_write_concern_get_w (wc_result), ==, (int32_t) 2); - - mongoc_read_prefs_destroy (prefs); - mongoc_read_concern_destroy (rc); - mongoc_write_concern_destroy (wc); - mongoc_uri_destroy (uri); -} - - -static void -test_mongoc_host_list_from_string (void) -{ - mongoc_host_list_t host_list = {0}; - - /* shouldn't be parsable */ - capture_logs (true); - ASSERT (!_mongoc_host_list_from_string (&host_list, ":27017")); - ASSERT_CAPTURED_LOG ("_mongoc_host_list_from_string", - MONGOC_LOG_LEVEL_ERROR, - "Could not parse address"); - capture_logs (true); - ASSERT (!_mongoc_host_list_from_string (&host_list, "example.com:")); - ASSERT_CAPTURED_LOG ("_mongoc_host_list_from_string", - MONGOC_LOG_LEVEL_ERROR, - "Could not parse address"); - capture_logs (true); - ASSERT (!_mongoc_host_list_from_string (&host_list, "localhost:999999999")); - ASSERT_CAPTURED_LOG ("_mongoc_host_list_from_string", - MONGOC_LOG_LEVEL_ERROR, - "Could not parse address"); - capture_logs (true); - ASSERT (!_mongoc_host_list_from_string (&host_list, "::1234")); - ASSERT_CAPTURED_LOG ("_mongoc_host_list_from_string", - MONGOC_LOG_LEVEL_ERROR, - "Could not parse address"); - - capture_logs (true); - ASSERT (!_mongoc_host_list_from_string (&host_list, "]:1234")); - ASSERT_CAPTURED_LOG ("_mongoc_host_list_from_string", - MONGOC_LOG_LEVEL_ERROR, - "Could not parse address"); - - capture_logs (true); - ASSERT (!_mongoc_host_list_from_string (&host_list, "[]:1234")); - ASSERT_CAPTURED_LOG ("_mongoc_host_list_from_string", - MONGOC_LOG_LEVEL_ERROR, - "Could not parse address"); - - capture_logs (true); - ASSERT (!_mongoc_host_list_from_string (&host_list, "[::1] foo")); - ASSERT_CAPTURED_LOG ("_mongoc_host_list_from_string", - MONGOC_LOG_LEVEL_ERROR, - "Could not parse address"); - - /* normal parsing, host and port are split, host is downcased */ - ASSERT (_mongoc_host_list_from_string (&host_list, "localHOST:27019")); - ASSERT_CMPSTR (host_list.host_and_port, "localhost:27019"); - ASSERT_CMPSTR (host_list.host, "localhost"); - ASSERT (host_list.port == 27019); - ASSERT (!host_list.next); - - ASSERT (_mongoc_host_list_from_string (&host_list, "localhost")); - ASSERT_CMPSTR (host_list.host_and_port, "localhost:27017"); - ASSERT_CMPSTR (host_list.host, "localhost"); - ASSERT (host_list.port == 27017); - - ASSERT (_mongoc_host_list_from_string (&host_list, "[::1]")); - ASSERT_CMPSTR (host_list.host_and_port, "[::1]:27017"); - ASSERT_CMPSTR (host_list.host, "::1"); /* no "[" or "]" */ - ASSERT (host_list.port == 27017); - - ASSERT (_mongoc_host_list_from_string (&host_list, "[Fe80::1]:1234")); - ASSERT_CMPSTR (host_list.host_and_port, "[fe80::1]:1234"); - ASSERT_CMPSTR (host_list.host, "fe80::1"); - ASSERT (host_list.port == 1234); - - ASSERT (_mongoc_host_list_from_string (&host_list, "[fe80::1%lo0]:1234")); - ASSERT_CMPSTR (host_list.host_and_port, "[fe80::1%lo0]:1234"); - ASSERT_CMPSTR (host_list.host, "fe80::1%lo0"); - ASSERT (host_list.port == 1234); - - ASSERT (_mongoc_host_list_from_string (&host_list, "[fe80::1%lo0]:1234")); - ASSERT_CMPSTR (host_list.host_and_port, "[fe80::1%lo0]:1234"); - ASSERT_CMPSTR (host_list.host, "fe80::1%lo0"); - ASSERT (host_list.port == 1234); - - /* preserves case */ - ASSERT (_mongoc_host_list_from_string (&host_list, "/Path/to/file.sock")); - ASSERT_CMPSTR (host_list.host_and_port, "/Path/to/file.sock"); - ASSERT_CMPSTR (host_list.host, "/Path/to/file.sock"); - - /* weird cases that should still parse, without crashing */ - ASSERT (_mongoc_host_list_from_string (&host_list, "/Path/to/file.sock:1")); - ASSERT_CMPSTR (host_list.host, "/Path/to/file.sock"); - ASSERT (host_list.family == AF_UNIX); - - ASSERT (_mongoc_host_list_from_string (&host_list, " :1234")); - ASSERT_CMPSTR (host_list.host_and_port, " :1234"); - ASSERT_CMPSTR (host_list.host, " "); - ASSERT (host_list.port == 1234); - - ASSERT (_mongoc_host_list_from_string (&host_list, "[:1234")); - ASSERT_CMPSTR (host_list.host_and_port, "[:1234"); - ASSERT_CMPSTR (host_list.host, "["); - ASSERT (host_list.port == 1234); - - ASSERT (_mongoc_host_list_from_string (&host_list, "[:]")); - ASSERT_CMPSTR (host_list.host_and_port, "[:]:27017"); - ASSERT_CMPSTR (host_list.host, ":"); - ASSERT (host_list.port == 27017); -} - - -static void -test_mongoc_uri_new_for_host_port (void) -{ - mongoc_uri_t *uri; - - uri = mongoc_uri_new_for_host_port ("uber", 555); - ASSERT (uri); - ASSERT (!strcmp ("uber", mongoc_uri_get_hosts (uri)->host)); - ASSERT (!strcmp ("uber:555", mongoc_uri_get_hosts (uri)->host_and_port)); - ASSERT (555 == mongoc_uri_get_hosts (uri)->port); - mongoc_uri_destroy (uri); -} - -static void -test_mongoc_uri_compressors (void) -{ - mongoc_uri_t *uri; - - uri = mongoc_uri_new ("mongodb://localhost/"); - -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - capture_logs (true); - mongoc_uri_set_compressors (uri, "snappy,unknown"); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "snappy")); - ASSERT (!bson_has_field (mongoc_uri_get_compressors (uri), "unknown")); - ASSERT_CAPTURED_LOG ("mongoc_uri_set_compressors", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported compressor: 'unknown'"); -#endif - - -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - capture_logs (true); - mongoc_uri_set_compressors (uri, "snappy"); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "snappy")); - ASSERT (!bson_has_field (mongoc_uri_get_compressors (uri), "unknown")); - ASSERT_NO_CAPTURED_LOGS ("snappy uri"); - - /* Overwrite the previous URI, effectively disabling snappy */ - capture_logs (true); - mongoc_uri_set_compressors (uri, "unknown"); - ASSERT (!bson_has_field (mongoc_uri_get_compressors (uri), "snappy")); - ASSERT (!bson_has_field (mongoc_uri_get_compressors (uri), "unknown")); - ASSERT_CAPTURED_LOG ("mongoc_uri_set_compressors", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported compressor: 'unknown'"); -#endif - - capture_logs (true); - mongoc_uri_set_compressors (uri, ""); - ASSERT (bson_empty (mongoc_uri_get_compressors (uri))); - ASSERT_CAPTURED_LOG ("mongoc_uri_set_compressors", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported compressor: ''"); - - - /* Disable compression */ - capture_logs (true); - mongoc_uri_set_compressors (uri, NULL); - ASSERT (bson_empty (mongoc_uri_get_compressors (uri))); - ASSERT_NO_CAPTURED_LOGS ("Disable compression"); - - - mongoc_uri_destroy (uri); - - -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - uri = mongoc_uri_new ("mongodb://localhost/?compressors=snappy"); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "snappy")); - mongoc_uri_destroy (uri); - - capture_logs (true); - uri = - mongoc_uri_new ("mongodb://localhost/?compressors=snappy,somethingElse"); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "snappy")); - ASSERT (!bson_has_field (mongoc_uri_get_compressors (uri), "somethingElse")); - ASSERT_CAPTURED_LOG ("mongoc_uri_set_compressors", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported compressor: 'somethingElse'"); - mongoc_uri_destroy (uri); -#endif - - -#ifdef MONGOC_ENABLE_COMPRESSION_ZLIB - -#ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY - uri = mongoc_uri_new ("mongodb://localhost/?compressors=snappy,zlib"); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "snappy")); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "zlib")); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/"); - ASSERT (mongoc_uri_set_compressors (uri, "snappy,zlib")); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "snappy")); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "zlib")); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/"); - ASSERT (mongoc_uri_set_compressors (uri, "zlib")); - ASSERT (mongoc_uri_set_compressors (uri, "snappy")); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "snappy")); - ASSERT (!bson_has_field (mongoc_uri_get_compressors (uri), "zlib")); - mongoc_uri_destroy (uri); -#endif - - uri = mongoc_uri_new ("mongodb://localhost/?compressors=zlib"); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "zlib")); - mongoc_uri_destroy (uri); - - capture_logs (true); - uri = mongoc_uri_new ("mongodb://localhost/?compressors=zlib,somethingElse"); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "zlib")); - ASSERT (!bson_has_field (mongoc_uri_get_compressors (uri), "somethingElse")); - ASSERT_CAPTURED_LOG ("mongoc_uri_set_compressors", - MONGOC_LOG_LEVEL_WARNING, - "Unsupported compressor: 'somethingElse'"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ( - "mongodb://localhost/?compressors=zlib&zlibCompressionLevel=-1"); - ASSERT (bson_has_field (mongoc_uri_get_compressors (uri), "zlib")); - ASSERT_CMPINT32 ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 1), - ==, - -1); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ( - "mongodb://localhost/?compressors=zlib&zlibCompressionLevel=9"); - ASSERT_CMPINT32 ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 1), - ==, - 9); - mongoc_uri_destroy (uri); - - capture_logs (true); - uri = mongoc_uri_new ( - "mongodb://localhost/?compressors=zlib&zlibCompressionLevel=-2"); - ASSERT_CAPTURED_LOG ( - "mongoc_uri_set_compressors", - MONGOC_LOG_LEVEL_WARNING, - "Invalid \"zlibcompressionlevel\" of -2: must be between -1 and 9"); - mongoc_uri_destroy (uri); - - capture_logs (true); - uri = mongoc_uri_new ( - "mongodb://localhost/?compressors=zlib&zlibCompressionLevel=10"); - ASSERT_CAPTURED_LOG ( - "mongoc_uri_set_compressors", - MONGOC_LOG_LEVEL_WARNING, - "Invalid \"zlibcompressionlevel\" of 10: must be between -1 and 9"); - mongoc_uri_destroy (uri); - -#endif -} - -static void -test_mongoc_uri_unescape (void) -{ -#define ASSERT_URIDECODE_STR(_s, _e) \ - do { \ - char *str = mongoc_uri_unescape (_s); \ - ASSERT (!strcmp (str, _e)); \ - bson_free (str); \ - } while (0) -#define ASSERT_URIDECODE_FAIL(_s) \ - do { \ - char *str; \ - capture_logs (true); \ - str = mongoc_uri_unescape (_s); \ - ASSERT (!str); \ - ASSERT_CAPTURED_LOG ( \ - "uri", MONGOC_LOG_LEVEL_WARNING, "Invalid % escape sequence"); \ - } while (0) - - ASSERT_URIDECODE_STR ("", ""); - ASSERT_URIDECODE_STR ("%40", "@"); - ASSERT_URIDECODE_STR ("me%40localhost@localhost", "me@localhost@localhost"); - ASSERT_URIDECODE_STR ("%20", " "); - ASSERT_URIDECODE_STR ("%24%21%40%2A%26%5E%21%40%2A%23%26%5E%21%40%23%2A%26" - "%5E%21%40%2A%23%26%5E%21%40%2A%26%23%5E%7D%7B%7D%7B" - "%22%22%27%7D%7B%5B%5D%3C%3E%3F", - "$!@*&^!@*#&^!@#*&^!@*#&^!@*&#^}{}{\"\"'}{[]<>?"); - - ASSERT_URIDECODE_FAIL ("%"); - ASSERT_URIDECODE_FAIL ("%%"); - ASSERT_URIDECODE_FAIL ("%%%"); - ASSERT_URIDECODE_FAIL ("%FF"); - ASSERT_URIDECODE_FAIL ("%CC"); - ASSERT_URIDECODE_FAIL ("%00"); - -#undef ASSERT_URIDECODE_STR -#undef ASSERT_URIDECODE_FAIL -} - - -typedef struct { - const char *uri; - bool parses; - mongoc_read_mode_t mode; - bson_t *tags; - const char *log_msg; -} read_prefs_test; - - -static void -test_mongoc_uri_read_prefs (void) -{ - const mongoc_read_prefs_t *rp; - mongoc_uri_t *uri; - const read_prefs_test *t; - int i; - - bson_t *tags_dcny = BCON_NEW ("0", "{", "dc", "ny", "}"); - bson_t *tags_dcny_empty = - BCON_NEW ("0", "{", "dc", "ny", "}", "1", "{", "}"); - bson_t *tags_dcnyusessd_dcsf_empty = BCON_NEW ("0", - "{", - "dc", - "ny", - "use", - "ssd", - "}", - "1", - "{", - "dc", - "sf", - "}", - "2", - "{", - "}"); - bson_t *tags_empty = BCON_NEW ("0", "{", "}"); - - const char *conflicts = "Invalid readPreferences"; - - const read_prefs_test tests[] = { - {"mongodb://localhost/", true, MONGOC_READ_PRIMARY, NULL}, - {"mongodb://localhost/?" MONGOC_URI_SLAVEOK "=false", - true, - MONGOC_READ_PRIMARY, - NULL}, - {"mongodb://localhost/?" MONGOC_URI_SLAVEOK "=true", - true, - MONGOC_READ_SECONDARY_PREFERRED, - NULL}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE "=primary", - true, - MONGOC_READ_PRIMARY, - NULL}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE "=primaryPreferred", - true, - MONGOC_READ_PRIMARY_PREFERRED, - NULL}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE "=secondary", - true, - MONGOC_READ_SECONDARY, - NULL}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE "=secondaryPreferred", - true, - MONGOC_READ_SECONDARY_PREFERRED, - NULL}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE "=nearest", - true, - MONGOC_READ_NEAREST, - NULL}, - /* MONGOC_URI_READPREFERENCE should take priority over " - MONGOC_URI_SLAVEOK " */ - {"mongodb://localhost/?" MONGOC_URI_SLAVEOK - "=false&" MONGOC_URI_READPREFERENCE "=secondary", - true, - MONGOC_READ_SECONDARY, - NULL}, - /* MONGOC_URI_READPREFERENCETAGS conflict with primary mode */ - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCETAGS "=", - false, - MONGOC_READ_PRIMARY, - NULL, - conflicts}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE - "=primary&" MONGOC_URI_READPREFERENCETAGS "=", - false, - MONGOC_READ_PRIMARY, - NULL, - conflicts}, - {"mongodb://localhost/?" MONGOC_URI_SLAVEOK - "=false&" MONGOC_URI_READPREFERENCETAGS "=", - false, - MONGOC_READ_PRIMARY, - NULL, - conflicts}, - {"mongodb://localhost/" - "?" MONGOC_URI_READPREFERENCE - "=secondaryPreferred&" MONGOC_URI_READPREFERENCETAGS "=", - true, - MONGOC_READ_SECONDARY_PREFERRED, - tags_empty}, - {"mongodb://localhost/" - "?" MONGOC_URI_READPREFERENCE - "=secondaryPreferred&" MONGOC_URI_READPREFERENCETAGS "=dc:ny", - true, - MONGOC_READ_SECONDARY_PREFERRED, - tags_dcny}, - {"mongodb://localhost/" - "?" MONGOC_URI_READPREFERENCE "=nearest&" MONGOC_URI_READPREFERENCETAGS - "=dc:ny&" MONGOC_URI_READPREFERENCETAGS "=", - true, - MONGOC_READ_NEAREST, - tags_dcny_empty}, - {"mongodb://localhost/" - "?" MONGOC_URI_READPREFERENCE "=nearest&" MONGOC_URI_READPREFERENCETAGS - "=dc:ny,use:ssd&" MONGOC_URI_READPREFERENCETAGS - "=dc:sf&" MONGOC_URI_READPREFERENCETAGS "=", - true, - MONGOC_READ_NEAREST, - tags_dcnyusessd_dcsf_empty}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE - "=nearest&" MONGOC_URI_READPREFERENCETAGS "=foo", - false, - MONGOC_READ_NEAREST, - NULL, - "Unsupported value for \"" MONGOC_URI_READPREFERENCETAGS "\": \"foo\""}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE - "=nearest&" MONGOC_URI_READPREFERENCETAGS "=foo,bar", - false, - MONGOC_READ_NEAREST, - NULL, - "Unsupported value for \"" MONGOC_URI_READPREFERENCETAGS - "\": \"foo,bar\""}, - {"mongodb://localhost/?" MONGOC_URI_READPREFERENCE - "=nearest&" MONGOC_URI_READPREFERENCETAGS "=1", - false, - MONGOC_READ_NEAREST, - NULL, - "Unsupported value for \"" MONGOC_URI_READPREFERENCETAGS "\": \"1\""}, - {NULL}}; - - for (i = 0; tests[i].uri; i++) { - t = &tests[i]; - - capture_logs (true); - uri = mongoc_uri_new (t->uri); - if (t->parses) { - BSON_ASSERT (uri); - ASSERT_NO_CAPTURED_LOGS (t->uri); - } else { - BSON_ASSERT (!uri); - if (t->log_msg) { - ASSERT_CAPTURED_LOG (t->uri, MONGOC_LOG_LEVEL_WARNING, t->log_msg); - } - - continue; - } - - rp = mongoc_uri_get_read_prefs_t (uri); - BSON_ASSERT (rp); - - BSON_ASSERT (t->mode == mongoc_read_prefs_get_mode (rp)); - - if (t->tags) { - BSON_ASSERT (bson_equal (t->tags, mongoc_read_prefs_get_tags (rp))); - } - - mongoc_uri_destroy (uri); - } - - bson_destroy (tags_dcny); - bson_destroy (tags_dcny_empty); - bson_destroy (tags_dcnyusessd_dcsf_empty); - bson_destroy (tags_empty); -} - - -typedef struct { - const char *uri; - bool parses; - int32_t w; - const char *wtag; - int64_t wtimeoutms; - const char *log_msg; -} write_concern_test; - - -static void -test_mongoc_uri_write_concern (void) -{ - const mongoc_write_concern_t *wr; - mongoc_uri_t *uri; - const write_concern_test *t; - int i; - static const write_concern_test tests[] = { - {"mongodb://localhost/?" MONGOC_URI_SAFE "=false", - true, - MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED}, - {"mongodb://localhost/?" MONGOC_URI_SAFE "=true", true, 1}, - {"mongodb://localhost/?" MONGOC_URI_W "=-1", - true, - MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED}, - {"mongodb://localhost/?" MONGOC_URI_W "=0", - true, - MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED}, - {"mongodb://localhost/?" MONGOC_URI_W "=1", true, 1}, - {"mongodb://localhost/?" MONGOC_URI_W "=2", true, 2}, - {"mongodb://localhost/?" MONGOC_URI_W "=majority", - true, - MONGOC_WRITE_CONCERN_W_MAJORITY}, - {"mongodb://localhost/?" MONGOC_URI_W "=10", true, 10}, - {"mongodb://localhost/?" MONGOC_URI_W "=", - true, - MONGOC_WRITE_CONCERN_W_DEFAULT}, - {"mongodb://localhost/?" MONGOC_URI_W "=mytag", - true, - MONGOC_WRITE_CONCERN_W_TAG, - "mytag"}, - {"mongodb://localhost/?" MONGOC_URI_W "=mytag&" MONGOC_URI_SAFE "=false", - true, - MONGOC_WRITE_CONCERN_W_TAG, - "mytag"}, - {"mongodb://localhost/?" MONGOC_URI_W "=1&" MONGOC_URI_SAFE "=false", - true, - 1}, - {"mongodb://localhost/?" MONGOC_URI_JOURNAL "=true", - true, - MONGOC_WRITE_CONCERN_W_DEFAULT}, - {"mongodb://localhost/?" MONGOC_URI_W "=1&" MONGOC_URI_JOURNAL "=true", - true, - 1}, - {"mongodb://localhost/?" MONGOC_URI_W "=2&" MONGOC_URI_WTIMEOUTMS "=1000", - true, - 2, - NULL, - 1000}, - {"mongodb://localhost/?" MONGOC_URI_W "=2&" MONGOC_URI_WTIMEOUTMS - "=2147483648", - true, - 2, - NULL, - 2147483648LL}, - {"mongodb://localhost/?" MONGOC_URI_W "=majority&" MONGOC_URI_WTIMEOUTMS - "=1000", - true, - MONGOC_WRITE_CONCERN_W_MAJORITY, - NULL, - 1000}, - {"mongodb://localhost/?" MONGOC_URI_W "=mytag&" MONGOC_URI_WTIMEOUTMS - "=1000", - true, - MONGOC_WRITE_CONCERN_W_TAG, - "mytag", - 1000}, - {"mongodb://localhost/?" MONGOC_URI_W "=0&" MONGOC_URI_JOURNAL "=true", - false, - MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED, - NULL, - 0, - "Journal conflicts with w value [" MONGOC_URI_W "=0]"}, - {"mongodb://localhost/?" MONGOC_URI_W "=-1&" MONGOC_URI_JOURNAL "=true", - false, - MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED, - NULL, - 0, - "Journal conflicts with w value [" MONGOC_URI_W "=-1]"}, - {NULL}}; - - for (i = 0; tests[i].uri; i++) { - t = &tests[i]; - - capture_logs (true); - uri = mongoc_uri_new (t->uri); - - if (tests[i].log_msg) { - ASSERT_CAPTURED_LOG ( - tests[i].uri, MONGOC_LOG_LEVEL_WARNING, tests[i].log_msg); - } else { - ASSERT_NO_CAPTURED_LOGS (tests[i].uri); - } - - capture_logs (false); /* clear captured logs */ - - if (t->parses) { - BSON_ASSERT (uri); - } else { - BSON_ASSERT (!uri); - continue; - } - - wr = mongoc_uri_get_write_concern (uri); - BSON_ASSERT (wr); - - BSON_ASSERT (t->w == mongoc_write_concern_get_w (wr)); - - if (t->wtag) { - BSON_ASSERT (0 == - strcmp (t->wtag, mongoc_write_concern_get_wtag (wr))); - } - - if (t->wtimeoutms) { - BSON_ASSERT (t->wtimeoutms == - mongoc_write_concern_get_wtimeout_int64 (wr)); - } - - mongoc_uri_destroy (uri); - } -} - -static void -test_mongoc_uri_read_concern (void) -{ - const mongoc_read_concern_t *rc; - mongoc_uri_t *uri; - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_READCONCERNLEVEL - "=majority"); - rc = mongoc_uri_get_read_concern (uri); - ASSERT_CMPSTR (mongoc_read_concern_get_level (rc), "majority"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/" - "?" MONGOC_URI_READCONCERNLEVEL - "=" MONGOC_READ_CONCERN_LEVEL_MAJORITY); - rc = mongoc_uri_get_read_concern (uri); - ASSERT_CMPSTR (mongoc_read_concern_get_level (rc), "majority"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/" - "?" MONGOC_URI_READCONCERNLEVEL - "=" MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE); - rc = mongoc_uri_get_read_concern (uri); - ASSERT_CMPSTR (mongoc_read_concern_get_level (rc), "linearizable"); - mongoc_uri_destroy (uri); - - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_READCONCERNLEVEL - "=local"); - rc = mongoc_uri_get_read_concern (uri); - ASSERT_CMPSTR (mongoc_read_concern_get_level (rc), "local"); - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_READCONCERNLEVEL - "=" MONGOC_READ_CONCERN_LEVEL_LOCAL); - rc = mongoc_uri_get_read_concern (uri); - ASSERT_CMPSTR (mongoc_read_concern_get_level (rc), "local"); - mongoc_uri_destroy (uri); - - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_READCONCERNLEVEL - "=randomstuff"); - rc = mongoc_uri_get_read_concern (uri); - ASSERT_CMPSTR (mongoc_read_concern_get_level (rc), "randomstuff"); - mongoc_uri_destroy (uri); - - - uri = mongoc_uri_new ("mongodb://localhost/"); - rc = mongoc_uri_get_read_concern (uri); - ASSERT (mongoc_read_concern_get_level (rc) == NULL); - mongoc_uri_destroy (uri); - - - uri = - mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_READCONCERNLEVEL "="); - rc = mongoc_uri_get_read_concern (uri); - ASSERT_CMPSTR (mongoc_read_concern_get_level (rc), ""); - mongoc_uri_destroy (uri); -} - -static void -test_mongoc_uri_long_hostname (void) -{ - char *host; - char *host_and_port; - size_t len = BSON_HOST_NAME_MAX; - char *uri_str; - mongoc_uri_t *uri; - - /* hostname of exactly maximum length */ - host = bson_malloc (len + 1); - memset (host, 'a', len); - host[len] = '\0'; - host_and_port = bson_strdup_printf ("%s:12345", host); - uri_str = bson_strdup_printf ("mongodb://%s", host_and_port); - uri = mongoc_uri_new (uri_str); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->host_and_port, host_and_port); - - mongoc_uri_destroy (uri); - uri = mongoc_uri_new_for_host_port (host, 12345); - ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_hosts (uri)->host_and_port, host_and_port); - - mongoc_uri_destroy (uri); - bson_free (uri_str); - bson_free (host_and_port); - bson_free (host); - - /* hostname length exceeds maximum by one */ - len++; - host = bson_malloc (len + 1); - memset (host, 'a', len); - host[len] = '\0'; - host_and_port = bson_strdup_printf ("%s:12345", host); - uri_str = bson_strdup_printf ("mongodb://%s", host_and_port); - - capture_logs (true); - ASSERT (!mongoc_uri_new (uri_str)); - ASSERT_CAPTURED_LOG ("mongoc_uri_new", MONGOC_LOG_LEVEL_ERROR, "too long"); - - clear_captured_logs (); - ASSERT (!mongoc_uri_new_for_host_port (host, 12345)); - ASSERT_CAPTURED_LOG ("mongoc_uri_new", MONGOC_LOG_LEVEL_ERROR, "too long"); - - bson_free (uri_str); - bson_free (host_and_port); - bson_free (host); -} - -static void -test_mongoc_uri_tls_ssl (const char *tls, - const char *tlsCertificateKeyFile, - const char *tlsCertificateKeyPassword, - const char *tlsCAFile, - const char *tlsAllowInvalidCertificates, - const char *tlsAllowInvalidHostnames) -{ - const char *tlsalt; - char url_buffer[2048]; - mongoc_uri_t *uri; - bson_error_t err; - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://CN=client,OU=kerneluser,O=10Gen,L=New York City," - "ST=New York,C=US@ldaptest.10gen.cc/?" - "%s=true&authMechanism=MONGODB-X509&" - "%s=tests/x509gen/legacy-x509.pem&" - "%s=tests/x509gen/legacy-ca.crt&" - "%s=true", - tls, - tlsCertificateKeyFile, - tlsCAFile, - tlsAllowInvalidHostnames); - uri = mongoc_uri_new (url_buffer); - - ASSERT_CMPSTR ( - mongoc_uri_get_username (uri), - "CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US"); - ASSERT (!mongoc_uri_get_password (uri)); - ASSERT (!mongoc_uri_get_database (uri)); - ASSERT_CMPSTR (mongoc_uri_get_auth_source (uri), "$external"); - ASSERT_CMPSTR (mongoc_uri_get_auth_mechanism (uri), "MONGODB-X509"); - - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "none"), - "tests/x509gen/legacy-x509.pem"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, "none"), - "none"); - ASSERT_CMPSTR ( - mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCAFILE, "none"), - "tests/x509gen/legacy-ca.crt"); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, false)); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, false)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=true&%s=key.pem&%s=ca.pem", - tls, - tlsCertificateKeyFile, - tlsCAFile); - uri = mongoc_uri_new (url_buffer); - - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE, "none"), - "key.pem"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "none"), - "key.pem"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD, "none"), - "none"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, "none"), - "none"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE, "none"), - "ca.pem"); - ASSERT_CMPSTR ( - mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCAFILE, "none"), - "ca.pem"); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, false)); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, false)); - mongoc_uri_destroy (uri); - - - snprintf ( - url_buffer, sizeof (url_buffer), "mongodb://localhost/?%s=true", tls); - uri = mongoc_uri_new (url_buffer); - - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "none"), - "none"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, "none"), - "none"); - ASSERT_CMPSTR ( - mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCAFILE, "none"), - "none"); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, false)); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, false)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=true&%s=pa$$word!&%s=encrypted.pem", - tls, - tlsCertificateKeyPassword, - tlsCertificateKeyFile); - uri = mongoc_uri_new (url_buffer); - - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE, "none"), - "encrypted.pem"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "none"), - "encrypted.pem"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD, "none"), - "pa$$word!"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, "none"), - "pa$$word!"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE, "none"), - "none"); - ASSERT_CMPSTR ( - mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCAFILE, "none"), - "none"); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, false)); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, false)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=true&%s=true", - tls, - tlsAllowInvalidCertificates); - uri = mongoc_uri_new (url_buffer); - - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "none"), - "none"); - ASSERT_CMPSTR (mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, "none"), - "none"); - ASSERT_CMPSTR ( - mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCAFILE, "none"), - "none"); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES, false)); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, false)); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES, false)); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, false)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=foo.pem", - tlsCertificateKeyFile); - uri = mongoc_uri_new (url_buffer); - ASSERT (mongoc_uri_get_ssl (uri)); - ASSERT (mongoc_uri_get_tls (uri)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=foo.pem", - tlsCAFile); - uri = mongoc_uri_new (url_buffer); - ASSERT (mongoc_uri_get_ssl (uri)); - ASSERT (mongoc_uri_get_tls (uri)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=true", - tlsAllowInvalidCertificates); - uri = mongoc_uri_new (url_buffer); - ASSERT (mongoc_uri_get_ssl (uri)); - ASSERT (mongoc_uri_get_tls (uri)); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES, false)); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, false)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=true", - tlsAllowInvalidHostnames); - uri = mongoc_uri_new (url_buffer); - ASSERT (mongoc_uri_get_ssl (uri)); - ASSERT (mongoc_uri_get_tls (uri)); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES, false)); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, false)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=false&%s=foo.pem", - tls, - tlsCertificateKeyFile); - uri = mongoc_uri_new (url_buffer); - ASSERT (!mongoc_uri_get_ssl (uri)); - ASSERT (!mongoc_uri_get_tls (uri)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=false&%s=foo.pem", - tls, - tlsCertificateKeyFile); - uri = mongoc_uri_new (url_buffer); - ASSERT (!mongoc_uri_get_ssl (uri)); - ASSERT (!mongoc_uri_get_tls (uri)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=false&%s=true", - tls, - tlsAllowInvalidCertificates); - uri = mongoc_uri_new (url_buffer); - ASSERT (!mongoc_uri_get_ssl (uri)); - ASSERT (!mongoc_uri_get_tls (uri)); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES, false)); - ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, false)); - mongoc_uri_destroy (uri); - - - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=false&%s=false", - tls, - tlsAllowInvalidHostnames); - uri = mongoc_uri_new (url_buffer); - ASSERT (!mongoc_uri_get_ssl (uri)); - ASSERT (!mongoc_uri_get_tls (uri)); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES, true)); - ASSERT (!mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, true)); - mongoc_uri_destroy (uri); - - if (!strcmp (tls, "ssl")) { - tlsalt = "tls"; - } else { - tlsalt = "ssl"; - } - - /* Mixing options okay so long as they match */ - capture_logs (true); - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=true&%s=true", - tls, - tlsalt); - uri = mongoc_uri_new (url_buffer); - ASSERT (mongoc_uri_get_option_as_bool (uri, tls, false)); - ASSERT_NO_CAPTURED_LOGS (url_buffer); - mongoc_uri_destroy (uri); - - /* Same option with different values okay, latter overrides */ - capture_logs (true); - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=true&%s=false", - tls, - tls); - uri = mongoc_uri_new (url_buffer); - ASSERT (!mongoc_uri_get_option_as_bool (uri, tls, true)); - if (strcmp (tls, "tls")) { - ASSERT_CAPTURED_LOG ("option: ssl", - MONGOC_LOG_LEVEL_WARNING, - "Overwriting previously provided value for 'ssl'"); - } else { - ASSERT_CAPTURED_LOG ("option: tls", - MONGOC_LOG_LEVEL_WARNING, - "Overwriting previously provided value for 'tls'"); - } - mongoc_uri_destroy (uri); - - /* Mixing options not okay if values differ */ - capture_logs (false); - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb://localhost/?%s=true&%s=false", - tls, - tlsalt); - uri = mongoc_uri_new_with_error (url_buffer, &err); - if (strcmp (tls, "tls")) { - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Deprecated option 'ssl=true' conflicts with " - "canonical name 'tls=false'"); - } else { - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Deprecated option 'ssl=false' conflicts with " - "canonical name 'tls=true'"); - } - mongoc_uri_destroy (uri); - - /* No conflict appears with implicit tls=true via SRV */ - capture_logs (false); - snprintf (url_buffer, - sizeof (url_buffer), - "mongodb+srv://a.b.c/?%s=foo.pem", - tlsCAFile); - uri = mongoc_uri_new (url_buffer); - ASSERT (mongoc_uri_get_option_as_bool (uri, tls, false)); - mongoc_uri_destroy (uri); -} - -static void -test_mongoc_uri_tls () -{ - bson_error_t err = {0}; - mongoc_uri_t *uri; - - test_mongoc_uri_tls_ssl (MONGOC_URI_TLS, - MONGOC_URI_TLSCERTIFICATEKEYFILE, - MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, - MONGOC_URI_TLSCAFILE, - MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, - MONGOC_URI_TLSALLOWINVALIDHOSTNAMES); - - /* tls-only option */ - uri = mongoc_uri_new ("mongodb://localhost/?tlsInsecure=true"); - ASSERT (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_TLSINSECURE, false)); - mongoc_uri_destroy (uri); - - ASSERT (!mongoc_uri_new_with_error ( - "mongodb://localhost/?tlsInsecure=true&tlsAllowInvalidHostnames=false", - &err)); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "tlsinsecure may not be specified with " - "tlsallowinvalidcertificates or " - "tlsallowinvalidhostnames"); - - ASSERT (!mongoc_uri_new_with_error ( - "mongodb://localhost/" - "?tlsInsecure=true&tlsAllowInvalidCertificates=true", - &err)); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "tlsinsecure may not be specified with " - "tlsallowinvalidcertificates or " - "tlsallowinvalidhostnames"); -} - -static void -test_mongoc_uri_ssl () -{ - test_mongoc_uri_tls_ssl (MONGOC_URI_SSL, - MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE, - MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD, - MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE, - MONGOC_URI_SSLALLOWINVALIDCERTIFICATES, - MONGOC_URI_SSLALLOWINVALIDHOSTNAMES); -} - -static void -test_mongoc_uri_local_threshold_ms (void) -{ - mongoc_uri_t *uri; - - uri = mongoc_uri_new ("mongodb://localhost/"); - - /* localthresholdms isn't set, return the default */ - ASSERT_CMPINT (mongoc_uri_get_local_threshold_option (uri), - ==, - MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS); - ASSERT ( - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_LOCALTHRESHOLDMS, 99)); - ASSERT_CMPINT (mongoc_uri_get_local_threshold_option (uri), ==, 99); - - mongoc_uri_destroy (uri); - - uri = - mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_LOCALTHRESHOLDMS "=0"); - - ASSERT_CMPINT (mongoc_uri_get_local_threshold_option (uri), ==, 0); - ASSERT ( - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_LOCALTHRESHOLDMS, 99)); - ASSERT_CMPINT (mongoc_uri_get_local_threshold_option (uri), ==, 99); - - mongoc_uri_destroy (uri); - - uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_LOCALTHRESHOLDMS - "=-1"); - - /* localthresholdms is invalid, return the default */ - capture_logs (true); - ASSERT_CMPINT (mongoc_uri_get_local_threshold_option (uri), - ==, - MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS); - ASSERT_CAPTURED_LOG ("mongoc_uri_get_local_threshold_option", - MONGOC_LOG_LEVEL_WARNING, - "Invalid localThresholdMS: -1"); - - mongoc_uri_destroy (uri); -} - - -#define INVALID(_uri, _host) \ - BSON_ASSERT (!mongoc_uri_upsert_host ((_uri), (_host), 1, &error)); \ - ASSERT_ERROR_CONTAINS (error, \ - MONGOC_ERROR_STREAM, \ - MONGOC_ERROR_STREAM_NAME_RESOLUTION, \ - "must be subdomain") - -#define VALID(_uri, _host) \ - ASSERT_OR_PRINT (mongoc_uri_upsert_host ((_uri), (_host), 1, &error), error) - - -static void -test_mongoc_uri_srv (void) -{ - mongoc_uri_t *uri; - bson_error_t error; - - capture_logs (true); - - ASSERT (!mongoc_uri_new ("mongodb+srv://")); - /* requires a subdomain, domain, and TLD: "a.example.com" */ - ASSERT (!mongoc_uri_new ("mongodb+srv://foo")); - ASSERT (!mongoc_uri_new ("mongodb+srv://foo.")); - ASSERT (!mongoc_uri_new ("mongodb+srv://.foo")); - ASSERT (!mongoc_uri_new ("mongodb+srv://..")); - ASSERT (!mongoc_uri_new ("mongodb+srv://.a.")); - ASSERT (!mongoc_uri_new ("mongodb+srv://a.b.c.com.")); - ASSERT (!mongoc_uri_new ("mongodb+srv://.a.b.c.com")); - ASSERT (!mongoc_uri_new ("mongodb+srv://foo\x08\x00bar")); - ASSERT (!mongoc_uri_new ("mongodb+srv://foo%00bar")); - ASSERT (!mongoc_uri_new ("mongodb+srv://example.com")); - - uri = mongoc_uri_new ("mongodb+srv://c.d.com"); - BSON_ASSERT (uri); - ASSERT_CMPSTR (mongoc_uri_get_service (uri), "c.d.com"); - BSON_ASSERT (mongoc_uri_get_hosts (uri) == NULL); - - /* tls is set to true when we use SRV */ - ASSERT_MATCH (mongoc_uri_get_options (uri), "{'tls': true}"); - - /* but we can override tls */ - mongoc_uri_destroy (uri); - uri = mongoc_uri_new ("mongodb+srv://c.d.com/?tls=false"); - BSON_ASSERT (uri); - ASSERT_MATCH (mongoc_uri_get_options (uri), "{'tls': false}"); - - INVALID (uri, "com"); - INVALID (uri, "foo.com"); - INVALID (uri, "d.com"); - INVALID (uri, "cd.com"); - VALID (uri, "c.d.com"); - VALID (uri, "bc.d.com"); - VALID (uri, "longer-string.d.com"); - INVALID (uri, ".c.d.com"); - VALID (uri, "b.c.d.com"); - INVALID (uri, ".b.c.d.com"); - INVALID (uri, "..b.c.d.com"); - VALID (uri, "a.b.c.d.com"); - - mongoc_uri_destroy (uri); - uri = mongoc_uri_new ("mongodb+srv://b.c.d.com"); - - INVALID (uri, "foo.com"); - INVALID (uri, "a.b.d.com"); - INVALID (uri, "d.com"); - VALID (uri, "b.c.d.com"); - VALID (uri, "a.b.c.d.com"); - VALID (uri, "foo.a.b.c.d.com"); - - mongoc_uri_destroy (uri); -} - - -#define PROHIBITED(_key, _value, _type, _where) \ - do { \ - const char *option = _key "=" #_value; \ - char *lkey = bson_strdup (_key); \ - mongoc_lowercase (lkey, lkey); \ - mongoc_uri_parse_options (uri, option, true /* from dns */, &error); \ - ASSERT_ERROR_CONTAINS (error, \ - MONGOC_ERROR_COMMAND, \ - MONGOC_ERROR_COMMAND_INVALID_ARG, \ - "prohibited in TXT record"); \ - BSON_ASSERT (!bson_has_field (mongoc_uri_get_##_where (uri), lkey)); \ - bson_free (lkey); \ - } while (0) - - -static void -test_mongoc_uri_dns_options (void) -{ - mongoc_uri_t *uri; - bson_error_t error; - - uri = mongoc_uri_new ("mongodb+srv://a.b.c"); - BSON_ASSERT (uri); - - BSON_ASSERT (!mongoc_uri_parse_options ( - uri, "tls=false", true /* from dsn */, &error)); - - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "prohibited in TXT record"); - - ASSERT_MATCH (mongoc_uri_get_options (uri), "{'tls': true}"); - - /* key we want to set, value, value type, whether it's option/credential */ - PROHIBITED (MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, true, bool, options); - PROHIBITED (MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, true, bool, options); - PROHIBITED (MONGOC_URI_GSSAPISERVICENAME, malicious, utf8, credentials); - - /* the two options allowed in TXT records, case-insensitive */ - BSON_ASSERT (mongoc_uri_parse_options (uri, "authsource=db", true, NULL)); - BSON_ASSERT (mongoc_uri_parse_options (uri, "RepLIcaSET=rs", true, NULL)); - - /* test that URI string overrides TXT record options */ - mongoc_uri_destroy (uri); - uri = mongoc_uri_new ( - "mongodb+srv://user@a.b.c/?authSource=db1&replicaSet=rs1"); - - capture_logs (true); - /* parse_options returns true, but logs warnings */ - BSON_ASSERT (mongoc_uri_parse_options ( - uri, "authSource=db2&replicaSet=db2", true, NULL)); - ASSERT_CAPTURED_LOG ("parsing TXT record", - MONGOC_LOG_LEVEL_WARNING, - "Cannot override URI option \"authSource\""); - ASSERT_CAPTURED_LOG ("parsing TXT record", - MONGOC_LOG_LEVEL_WARNING, - "Cannot override URI option \"replicaSet\""); - capture_logs (false); - ASSERT_MATCH (mongoc_uri_get_credentials (uri), "{'authsource': 'db1'}"); - ASSERT_MATCH (mongoc_uri_get_options (uri), "{'replicaset': 'rs1'}"); - - mongoc_uri_destroy (uri); -} - - -/* test some invalid accesses and a crash, found with a fuzzer */ -static void -test_mongoc_uri_utf8 (void) -{ - bson_error_t err; - - /* start of 3-byte character, but it's incomplete */ - BSON_ASSERT (!mongoc_uri_new_with_error ("mongodb://\xe8\x03", &err)); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid UTF-8 in URI"); - - /* start of 6-byte CESU-8 character, but it's incomplete */ - BSON_ASSERT (!mongoc_uri_new_with_error ("mongodb://\xfa", &err)); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid UTF-8 in URI"); - - - /* "a<NIL>z" with NIL expressed as two-byte sequence */ - BSON_ASSERT (!mongoc_uri_new_with_error ("mongodb://a\xc0\x80z", &err)); - ASSERT_ERROR_CONTAINS (err, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid UTF-8 in URI"); -} - - -/* test behavior on duplicate values for an options. */ -static void -test_mongoc_uri_duplicates (void) -{ - mongoc_uri_t *uri = NULL; - bson_error_t err; - const char *str; - const mongoc_write_concern_t *wc; - const mongoc_read_concern_t *rc; - const bson_t *bson; - const mongoc_read_prefs_t *rp; - bson_iter_t iter = {0}; - -#define RECREATE_URI(opts) \ - mongoc_uri_destroy (uri); \ - uri = mongoc_uri_new_with_error ("mongodb://user:pwd@localhost/test?" opts, \ - &err); \ - ASSERT_OR_PRINT (uri, err); - -#define ASSERT_LOG_DUPE(opt) \ - ASSERT_CAPTURED_LOG ("option: " opt, \ - MONGOC_LOG_LEVEL_WARNING, \ - "Overwriting previously provided value for '" opt \ - "'"); - -/* iterate iter to key, and check that no other occurrences exist. */ -#define BSON_ITER_UNIQUE(key) \ - do { \ - bson_iter_t tmp; \ - BSON_ASSERT (bson_iter_init_find (&iter, bson, key)); \ - tmp = iter; \ - while (bson_iter_next (&tmp)) { \ - if (strcmp (bson_iter_key (&tmp), key) == 0) { \ - ASSERT_WITH_MSG (false, "bson has duplicate keys for: " key); \ - } \ - } \ - } while (0); - - capture_logs (true); - - /* test all URI options, in the order they are defined in mongoc-uri.h. */ - RECREATE_URI (MONGOC_URI_APPNAME "=a&" MONGOC_URI_APPNAME "=b"); - ASSERT_LOG_DUPE (MONGOC_URI_APPNAME); - str = mongoc_uri_get_appname (uri); - BSON_ASSERT (strcmp (str, "b") == 0); - - RECREATE_URI (MONGOC_URI_AUTHMECHANISM "=a&" MONGOC_URI_AUTHMECHANISM "=b"); - ASSERT_LOG_DUPE (MONGOC_URI_AUTHMECHANISM); - bson = mongoc_uri_get_credentials (uri); - BSON_ITER_UNIQUE (MONGOC_URI_AUTHMECHANISM); - BSON_ASSERT (strcmp (bson_iter_utf8 (&iter, NULL), "b") == 0); - - RECREATE_URI (MONGOC_URI_AUTHMECHANISMPROPERTIES - "=a:x&" MONGOC_URI_AUTHMECHANISMPROPERTIES "=b:y"); - ASSERT_LOG_DUPE (MONGOC_URI_AUTHMECHANISMPROPERTIES); - bson = mongoc_uri_get_credentials (uri); - BSON_ASSERT ( - bson_compare ( - bson, tmp_bson ("{'authmechanismproperties': {'b': 'y' }}")) == 0); - - RECREATE_URI (MONGOC_URI_AUTHSOURCE "=a&" MONGOC_URI_AUTHSOURCE "=b"); - ASSERT_LOG_DUPE (MONGOC_URI_AUTHSOURCE); - str = mongoc_uri_get_auth_source (uri); - BSON_ASSERT (strcmp (str, "b") == 0); - - RECREATE_URI (MONGOC_URI_CANONICALIZEHOSTNAME - "=false&" MONGOC_URI_CANONICALIZEHOSTNAME "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_CANONICALIZEHOSTNAME); - BSON_ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_CANONICALIZEHOSTNAME, false)); - - RECREATE_URI (MONGOC_URI_CONNECTTIMEOUTMS "=1&" MONGOC_URI_CONNECTTIMEOUTMS - "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_CONNECTTIMEOUTMS); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_CONNECTTIMEOUTMS, 0) == 2); - -#if defined(MONGOC_ENABLE_COMPRESSION_SNAPPY) && \ - defined(MONGOC_ENABLE_COMPRESSION_ZLIB) - RECREATE_URI (MONGOC_URI_COMPRESSORS "=snappy&" MONGOC_URI_COMPRESSORS - "=zlib"); - ASSERT_LOG_DUPE (MONGOC_URI_COMPRESSORS); - bson = mongoc_uri_get_compressors (uri); - BSON_ASSERT (bson_compare (bson, tmp_bson ("{'zlib': 'yes'}")) == 0); -#endif - - /* exception: GSSAPISERVICENAME does not overwrite. */ - RECREATE_URI (MONGOC_URI_GSSAPISERVICENAME "=a&" MONGOC_URI_GSSAPISERVICENAME - "=b"); - ASSERT_CAPTURED_LOG ( - "option: " MONGOC_URI_GSSAPISERVICENAME, - MONGOC_LOG_LEVEL_WARNING, - "Overwriting previously provided value for 'gssapiservicename'"); - bson = mongoc_uri_get_credentials (uri); - BSON_ASSERT ( - bson_compare ( - bson, - tmp_bson ("{'authmechanismproperties': {'SERVICE_NAME': 'b' }}")) == - 0); - - RECREATE_URI (MONGOC_URI_HEARTBEATFREQUENCYMS - "=500&" MONGOC_URI_HEARTBEATFREQUENCYMS "=501"); - ASSERT_LOG_DUPE (MONGOC_URI_HEARTBEATFREQUENCYMS); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_HEARTBEATFREQUENCYMS, 0) == 501); - - RECREATE_URI (MONGOC_URI_JOURNAL "=false&" MONGOC_URI_JOURNAL "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_JOURNAL); - BSON_ASSERT (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_JOURNAL, false)); - - RECREATE_URI (MONGOC_URI_LOCALTHRESHOLDMS "=1&" MONGOC_URI_LOCALTHRESHOLDMS - "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_LOCALTHRESHOLDMS); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_LOCALTHRESHOLDMS, 0) == 2); - - RECREATE_URI (MONGOC_URI_MAXIDLETIMEMS "=1&" MONGOC_URI_MAXIDLETIMEMS "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_MAXIDLETIMEMS); - BSON_ASSERT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_MAXIDLETIMEMS, 0) == 2); - - RECREATE_URI (MONGOC_URI_MAXPOOLSIZE "=1&" MONGOC_URI_MAXPOOLSIZE "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_MAXPOOLSIZE); - BSON_ASSERT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_MAXPOOLSIZE, 0) == 2); - - RECREATE_URI (MONGOC_URI_READPREFERENCE - "=secondary&" MONGOC_URI_MAXSTALENESSSECONDS - "=1&" MONGOC_URI_MAXSTALENESSSECONDS "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_MAXSTALENESSSECONDS); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_MAXSTALENESSSECONDS, 0) == 2); - - RECREATE_URI (MONGOC_URI_MINPOOLSIZE "=1&" MONGOC_URI_MINPOOLSIZE "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_MINPOOLSIZE); - BSON_ASSERT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_MINPOOLSIZE, 0) == 2); - - RECREATE_URI (MONGOC_URI_READCONCERNLEVEL - "=local&" MONGOC_URI_READCONCERNLEVEL "=majority"); - ASSERT_LOG_DUPE (MONGOC_URI_READCONCERNLEVEL); - rc = mongoc_uri_get_read_concern (uri); - BSON_ASSERT (strcmp (mongoc_read_concern_get_level (rc), "majority") == 0); - - RECREATE_URI (MONGOC_URI_READPREFERENCE - "=secondary&" MONGOC_URI_READPREFERENCE "=primary"); - ASSERT_LOG_DUPE (MONGOC_URI_READPREFERENCE); - rp = mongoc_uri_get_read_prefs_t (uri); - BSON_ASSERT (mongoc_read_prefs_get_mode (rp) == MONGOC_READ_PRIMARY); - - /* exception: read preference tags get appended. */ - RECREATE_URI (MONGOC_URI_READPREFERENCE - "=secondary&" MONGOC_URI_READPREFERENCETAGS - "=a:x&" MONGOC_URI_READPREFERENCETAGS "=b:y"); - bson = mongoc_uri_get_read_prefs (uri); - BSON_ASSERT (bson_compare ( - bson, tmp_bson ("{'0': {'a': 'x'}, '1': {'b': 'y'}}")) == 0); - - RECREATE_URI (MONGOC_URI_REPLICASET "=a&" MONGOC_URI_REPLICASET "=b"); - ASSERT_LOG_DUPE (MONGOC_URI_REPLICASET); - str = mongoc_uri_get_replica_set (uri); - BSON_ASSERT (strcmp (str, "b") == 0); - - RECREATE_URI (MONGOC_URI_RETRYREADS "=false&" MONGOC_URI_RETRYREADS "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_RETRYREADS); - BSON_ASSERT ( - mongoc_uri_get_option_as_bool (uri, MONGOC_URI_RETRYREADS, false)); - - RECREATE_URI (MONGOC_URI_RETRYWRITES "=false&" MONGOC_URI_RETRYWRITES - "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_RETRYWRITES); - BSON_ASSERT ( - mongoc_uri_get_option_as_bool (uri, MONGOC_URI_RETRYWRITES, false)); - - RECREATE_URI (MONGOC_URI_SAFE "=false&" MONGOC_URI_SAFE "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_SAFE); - BSON_ASSERT (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_SAFE, false)); - - RECREATE_URI (MONGOC_URI_SERVERSELECTIONTIMEOUTMS - "=1&" MONGOC_URI_SERVERSELECTIONTIMEOUTMS "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_SERVERSELECTIONTIMEOUTMS); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_SERVERSELECTIONTIMEOUTMS, 0) == 2); - - RECREATE_URI (MONGOC_URI_SERVERSELECTIONTRYONCE - "=false&" MONGOC_URI_SERVERSELECTIONTRYONCE "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_SERVERSELECTIONTRYONCE); - BSON_ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_SERVERSELECTIONTRYONCE, false)); - - RECREATE_URI (MONGOC_URI_SLAVEOK "=false&" MONGOC_URI_SLAVEOK "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_SLAVEOK); - BSON_ASSERT (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_SLAVEOK, false)); - - RECREATE_URI (MONGOC_URI_SOCKETCHECKINTERVALMS - "=1&" MONGOC_URI_SOCKETCHECKINTERVALMS "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_SOCKETCHECKINTERVALMS); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_SOCKETCHECKINTERVALMS, 0) == 2); - - RECREATE_URI (MONGOC_URI_SOCKETTIMEOUTMS "=1&" MONGOC_URI_SOCKETTIMEOUTMS - "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_SOCKETTIMEOUTMS); - BSON_ASSERT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_SOCKETTIMEOUTMS, 0) == 2); - - RECREATE_URI (MONGOC_URI_TLS "=false&" MONGOC_URI_TLS "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_TLS); - BSON_ASSERT (mongoc_uri_get_tls (uri)); - - RECREATE_URI (MONGOC_URI_TLSCERTIFICATEKEYFILE - "=a&" MONGOC_URI_TLSCERTIFICATEKEYFILE "=b"); - ASSERT_LOG_DUPE (MONGOC_URI_TLSCERTIFICATEKEYFILE); - str = - mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, ""); - BSON_ASSERT (strcmp (str, "b") == 0); - - RECREATE_URI (MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD - "=a&" MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD "=b"); - ASSERT_LOG_DUPE (MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD); - str = mongoc_uri_get_option_as_utf8 ( - uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, ""); - BSON_ASSERT (strcmp (str, "b") == 0); - - RECREATE_URI (MONGOC_URI_TLSCAFILE "=a&" MONGOC_URI_TLSCAFILE "=b"); - ASSERT_LOG_DUPE (MONGOC_URI_TLSCAFILE); - str = mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_TLSCAFILE, ""); - BSON_ASSERT (strcmp (str, "b") == 0); - - RECREATE_URI (MONGOC_URI_TLSALLOWINVALIDCERTIFICATES - "=false&" MONGOC_URI_TLSALLOWINVALIDCERTIFICATES "=true"); - ASSERT_LOG_DUPE (MONGOC_URI_TLSALLOWINVALIDCERTIFICATES); - BSON_ASSERT (mongoc_uri_get_option_as_bool ( - uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, false)); - - RECREATE_URI (MONGOC_URI_W "=1&" MONGOC_URI_W "=0"); - ASSERT_LOG_DUPE (MONGOC_URI_W); - wc = mongoc_uri_get_write_concern (uri); - BSON_ASSERT (mongoc_write_concern_get_w (wc) == 0); - - /* exception: a string write concern takes precedence over an int */ - RECREATE_URI (MONGOC_URI_W "=majority&" MONGOC_URI_W "=0"); - ASSERT_LOG_DUPE (MONGOC_URI_W); - wc = mongoc_uri_get_write_concern (uri); - BSON_ASSERT (mongoc_write_concern_get_w (wc) == - MONGOC_WRITE_CONCERN_W_MAJORITY); - - RECREATE_URI (MONGOC_URI_WAITQUEUEMULTIPLE "=1&" MONGOC_URI_WAITQUEUEMULTIPLE - "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_WAITQUEUEMULTIPLE); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_WAITQUEUEMULTIPLE, 0) == 2); - - RECREATE_URI (MONGOC_URI_WAITQUEUETIMEOUTMS - "=1&" MONGOC_URI_WAITQUEUETIMEOUTMS "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_WAITQUEUETIMEOUTMS); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_WAITQUEUETIMEOUTMS, 0) == 2); - - RECREATE_URI (MONGOC_URI_WTIMEOUTMS "=1&" MONGOC_URI_WTIMEOUTMS "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_WTIMEOUTMS); - BSON_ASSERT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 0) == 2); - BSON_ASSERT ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 0) == 2); - - RECREATE_URI (MONGOC_URI_ZLIBCOMPRESSIONLEVEL - "=1&" MONGOC_URI_ZLIBCOMPRESSIONLEVEL "=2"); - ASSERT_LOG_DUPE (MONGOC_URI_ZLIBCOMPRESSIONLEVEL); - BSON_ASSERT (mongoc_uri_get_option_as_int32 ( - uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 0) == 2); - - mongoc_uri_destroy (uri); -} - - -/* Tests behavior of int32 and int64 options */ -static void -test_mongoc_uri_int_options (void) -{ - mongoc_uri_t *uri; - - capture_logs (true); - - uri = mongoc_uri_new ("mongodb://localhost/"); - - /* Set an int64 option as int64 succeeds */ - ASSERT (mongoc_uri_set_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 10)); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 0), ==, 10); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 0), ==, 10); - - /* Set an int64 option as int32 succeeds */ - ASSERT (mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 15)); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 0), ==, 15); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 0), ==, 15); - - /* Setting an int32 option through _as_int64 succeeds for 32-bit values but - * emits a warning */ - ASSERT ( - mongoc_uri_set_option_as_int64 (uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 9)); - ASSERT_CAPTURED_LOG ("option: " MONGOC_URI_ZLIBCOMPRESSIONLEVEL, - MONGOC_LOG_LEVEL_WARNING, - "Setting value for 32-bit option " - "\"zlibcompressionlevel\" through 64-bit method"); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 0), - ==, - 9); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 0), - ==, - 9); - - clear_captured_logs (); - - ASSERT (!mongoc_uri_set_option_as_int64 ( - uri, MONGOC_URI_CONNECTTIMEOUTMS, 2147483648LL)); - ASSERT_CAPTURED_LOG ( - "option: " MONGOC_URI_CONNECTTIMEOUTMS, - MONGOC_LOG_LEVEL_WARNING, - "Unsupported value for \"connecttimeoutms\": 2147483648," - " \"connecttimeoutms\" is not an int64 option"); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_CONNECTTIMEOUTMS, 0), - ==, - 0); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_CONNECTTIMEOUTMS, 0), - ==, - 0); - - clear_captured_logs (); - - /* Setting an int32 option as int32 succeeds */ - ASSERT ( - mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 9)); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 0), - ==, - 9); - ASSERT_CMPINT ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, 0), - ==, - 9); - - /* Truncating a 64-bit value when fetching as 32-bit emits a warning */ - ASSERT (mongoc_uri_set_option_as_int64 ( - uri, MONGOC_URI_WTIMEOUTMS, 2147483648LL)); - ASSERT_CMPINT32 ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 5), ==, 5); - ASSERT_CAPTURED_LOG ( - "option: " MONGOC_URI_WTIMEOUTMS " with 64-bit value", - MONGOC_LOG_LEVEL_WARNING, - "Cannot read 64-bit value for \"wtimeoutms\": 2147483648"); - ASSERT_CMPINT64 ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 5), - ==, - 2147483648LL); - - clear_captured_logs (); - - ASSERT (mongoc_uri_set_option_as_int64 ( - uri, MONGOC_URI_WTIMEOUTMS, -2147483649LL)); - ASSERT_CMPINT32 ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 5), ==, 5); - ASSERT_CAPTURED_LOG ( - "option: " MONGOC_URI_WTIMEOUTMS " with 64-bit value", - MONGOC_LOG_LEVEL_WARNING, - "Cannot read 64-bit value for \"wtimeoutms\": -2147483649"); - ASSERT_CMPINT64 ( - mongoc_uri_get_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, 5), - ==, - -2147483649LL); - - clear_captured_logs (); - - /* Setting a INT_MAX and INT_MIN values doesn't cause truncation errors */ - ASSERT ( - mongoc_uri_set_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, INT32_MAX)); - ASSERT_CMPINT32 ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 0), - ==, - INT32_MAX); - ASSERT_NO_CAPTURED_LOGS ("INT_MAX"); - ASSERT ( - mongoc_uri_set_option_as_int64 (uri, MONGOC_URI_WTIMEOUTMS, INT32_MIN)); - ASSERT_CMPINT32 ( - mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_WTIMEOUTMS, 0), - ==, - INT32_MIN); - ASSERT_NO_CAPTURED_LOGS ("INT_MIN"); - - mongoc_uri_destroy (uri); -} - - -void -test_uri_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Uri/new", test_mongoc_uri_new); - TestSuite_Add (suite, "/Uri/new_with_error", test_mongoc_uri_new_with_error); - TestSuite_Add ( - suite, "/Uri/new_for_host_port", test_mongoc_uri_new_for_host_port); - TestSuite_Add (suite, "/Uri/compressors", test_mongoc_uri_compressors); - TestSuite_Add (suite, "/Uri/unescape", test_mongoc_uri_unescape); - TestSuite_Add (suite, "/Uri/read_prefs", test_mongoc_uri_read_prefs); - TestSuite_Add (suite, "/Uri/read_concern", test_mongoc_uri_read_concern); - TestSuite_Add (suite, "/Uri/write_concern", test_mongoc_uri_write_concern); - TestSuite_Add ( - suite, "/HostList/from_string", test_mongoc_host_list_from_string); - TestSuite_Add (suite, - "/Uri/auth_mechanism_properties", - test_mongoc_uri_authmechanismproperties); - TestSuite_Add (suite, "/Uri/functions", test_mongoc_uri_functions); - TestSuite_Add (suite, "/Uri/ssl", test_mongoc_uri_ssl); - TestSuite_Add (suite, "/Uri/tls", test_mongoc_uri_tls); - TestSuite_Add ( - suite, "/Uri/compound_setters", test_mongoc_uri_compound_setters); - TestSuite_Add (suite, "/Uri/long_hostname", test_mongoc_uri_long_hostname); - TestSuite_Add ( - suite, "/Uri/local_threshold_ms", test_mongoc_uri_local_threshold_ms); - TestSuite_Add (suite, "/Uri/srv", test_mongoc_uri_srv); - TestSuite_Add (suite, "/Uri/dns_options", test_mongoc_uri_dns_options); - TestSuite_Add (suite, "/Uri/utf8", test_mongoc_uri_utf8); - TestSuite_Add (suite, "/Uri/duplicates", test_mongoc_uri_duplicates); - TestSuite_Add (suite, "/Uri/int_options", test_mongoc_uri_int_options); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-usleep.c b/lib/mongoc/libmongoc/tests/test-mongoc-usleep.c deleted file mode 100644 index 49a94abc164ce066e75381afa69dd71c9866e829..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-usleep.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "mongoc/mongoc-util-private.h" -#include "TestSuite.h" - - -static void -test_mongoc_usleep_basic (void) -{ - int64_t start; - int64_t duration; - - start = bson_get_monotonic_time (); - _mongoc_usleep (50 * 1000); /* 50 ms */ - duration = bson_get_monotonic_time () - start; - ASSERT_CMPINT ((int) duration, >, 0); - ASSERT_CMPTIME ((int) duration, 200 * 1000); -} - -void -test_usleep_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Sleep/basic", test_mongoc_usleep_basic); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-util.c b/lib/mongoc/libmongoc/tests/test-mongoc-util.c deleted file mode 100644 index 26a7369d64b6512a7dde1b89a5e22f09f39cb836..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-util.c +++ /dev/null @@ -1,73 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-util-private.h> - -#include "TestSuite.h" -#include "test-conveniences.h" - -#undef MONGOC_LOG_DOMAIN -#define MONGOC_LOG_DOMAIN "test-util" - - -static void -test_command_name (void) -{ - bson_t *commands[] = { - tmp_bson ("{'foo': 1}"), - tmp_bson ("{'query': {'foo': 1}}"), - tmp_bson ("{'query': {'foo': 1}, '$readPreference': 1}"), - tmp_bson ("{'$query': {'foo': 1}}"), - tmp_bson ("{'$query': {'foo': 1}, '$readPreference': 1}"), - tmp_bson ("{'$readPreference': 1, '$query': {'foo': 1}}"), - }; - - size_t i; - - for (i = 0; i < sizeof (commands) / sizeof (bson_t *); i++) { - ASSERT_CMPSTR ("foo", _mongoc_get_command_name (commands[i])); - } -} - - -static void -test_rand_simple (void) -{ - int i; - unsigned int seed = 0; - int value, first_value; - - first_value = _mongoc_rand_simple (&seed); - - for (i = 0; i < 1000; i++) { - value = _mongoc_rand_simple (&seed); - if (value != first_value) { - /* success */ - break; - } - } -} - -static void -test_lowercase_utf8 (void) -{ - char *snowman = "\xE2\x9b\x84"; - char *letters = "aBcDe"; - char *buf = bson_malloc0 (strlen (snowman) + 1); - - mongoc_lowercase (snowman, buf); - ASSERT_CMPSTR (snowman, buf); - bson_free (buf); - - buf = bson_malloc0 (strlen (letters) + 1); - mongoc_lowercase (letters, buf); - ASSERT_CMPSTR ("abcde", buf); - bson_free (buf); -} - - -void -test_util_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Util/command_name", test_command_name); - TestSuite_Add (suite, "/Util/rand_simple", test_rand_simple); - TestSuite_Add (suite, "/Util/lowercase_utf8", test_lowercase_utf8); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-version.c b/lib/mongoc/libmongoc/tests/test-mongoc-version.c deleted file mode 100644 index 51d93daa965739dda58f6afa50666d0e290b2432..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-version.c +++ /dev/null @@ -1,24 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "TestSuite.h" - -static void -test_mongoc_version (void) -{ - ASSERT_CMPINT (mongoc_get_major_version (), ==, MONGOC_MAJOR_VERSION); - ASSERT_CMPINT (mongoc_get_minor_version (), ==, MONGOC_MINOR_VERSION); - ASSERT_CMPINT (mongoc_get_micro_version (), ==, MONGOC_MICRO_VERSION); - ASSERT_CMPSTR (mongoc_get_version (), MONGOC_VERSION_S); - - ASSERT (mongoc_check_version ( - MONGOC_MAJOR_VERSION, MONGOC_MINOR_VERSION, MONGOC_MICRO_VERSION)); - - ASSERT (!mongoc_check_version ( - MONGOC_MAJOR_VERSION, MONGOC_MINOR_VERSION + 1, MONGOC_MICRO_VERSION)); -} - -void -test_version_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/Version", test_mongoc_version); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-with-transaction.c b/lib/mongoc/libmongoc/tests/test-mongoc-with-transaction.c deleted file mode 100644 index a8fc0ad54bc6d7b4b122b4c16aec226ad8f547af..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-with-transaction.c +++ /dev/null @@ -1,89 +0,0 @@ -#include <mongoc/mongoc.h> - -#include "json-test.h" -#include "mongoc/mongoc-client-session-private.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" - -/* Note, the with_transaction spec tests are in test-mongoc-transactions.c, - * since it shares the same test runner with the transactions test runner. */ - -static bool -with_transaction_fail_transient_txn (mongoc_client_session_t *session, - void *ctx, - bson_t **reply, - bson_error_t *error) -{ - bson_t labels; - - _mongoc_usleep (session->with_txn_timeout_ms * 1000); - - *reply = bson_new (); - BSON_APPEND_ARRAY_BEGIN (*reply, "errorLabels", &labels); - BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR); - - return false; -} - -static bool -with_transaction_do_nothing (mongoc_client_session_t *session, - void *ctx, - bson_t **reply, - bson_error_t *error) -{ - return true; -} - -static void -test_with_transaction_timeout (void *ctx) -{ - mongoc_client_t *client; - mongoc_client_session_t *session; - bson_error_t error; - bool res; - - client = test_framework_client_new (); - - session = mongoc_client_start_session (client, NULL, &error); - ASSERT_OR_PRINT (session, error); - - session->with_txn_timeout_ms = 10; - - /* Test Case 1: Test that if the callback returns an - error with the TransientTransactionError label and - we have exceeded the timeout, withTransaction fails. */ - res = mongoc_client_session_with_transaction ( - session, with_transaction_fail_transient_txn, NULL, NULL, NULL, &error); - ASSERT (!res); - - /* Test Case 2: If committing returns an error with the - UnknownTransactionCommitResult label and we have exceeded - the timeout, withTransaction fails. */ - session->fail_commit_label = UNKNOWN_COMMIT_RESULT; - res = mongoc_client_session_with_transaction ( - session, with_transaction_do_nothing, NULL, NULL, NULL, &error); - ASSERT (!res); - - /* Test Case 3: If committing returns an error with the - TransientTransactionError label and we have exceeded the - timeout, withTransaction fails. */ - session->fail_commit_label = TRANSIENT_TXN_ERR; - res = mongoc_client_session_with_transaction ( - session, with_transaction_do_nothing, NULL, NULL, NULL, &error); - ASSERT (!res); - - mongoc_client_session_destroy (session); - mongoc_client_destroy (client); -} - -void -test_with_transaction_install (TestSuite *suite) -{ - TestSuite_AddFull (suite, - "/with_transaction/timeout_tests", - test_with_transaction_timeout, - NULL, - NULL, - test_framework_skip_if_no_sessions, - test_framework_skip_if_no_crypto); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-write-commands.c b/lib/mongoc/libmongoc/tests/test-mongoc-write-commands.c deleted file mode 100644 index 58ced4e69499460d2d9028aadfa6a456b4538cc9..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-write-commands.c +++ /dev/null @@ -1,602 +0,0 @@ -#include <bson/bcon.h> -#include <mongoc/mongoc.h> - -#include "mongoc/mongoc-client-private.h" -#include "mongoc/mongoc-collection-private.h" -#include "mongoc/mongoc-write-command-private.h" -#include "mongoc/mongoc-write-concern-private.h" - -#include "TestSuite.h" - -#include "test-libmongoc.h" -#include "test-conveniences.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" - - -static void -test_split_insert (void) -{ - mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; - mongoc_write_command_t command; - mongoc_write_result_t result; - mongoc_collection_t *collection; - mongoc_client_t *client; - bson_oid_t oid; - bson_t **docs; - bson_t reply = BSON_INITIALIZER; - bson_error_t error; - mongoc_server_stream_t *server_stream; - int i; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_split_insert"); - BSON_ASSERT (collection); - - docs = (bson_t **) bson_malloc (sizeof (bson_t *) * 3000); - - for (i = 0; i < 3000; i++) { - docs[i] = bson_new (); - bson_oid_init (&oid, NULL); - BSON_APPEND_OID (docs[i], "_id", &oid); - } - - _mongoc_write_result_init (&result); - - _mongoc_write_command_init_insert (&command, - docs[0], - NULL, - write_flags, - ++client->cluster.operation_id); - - for (i = 1; i < 3000; i++) { - _mongoc_write_command_insert_append (&command, docs[i]); - } - - server_stream = - mongoc_cluster_stream_for_writes (&client->cluster, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - _mongoc_write_command_execute (&command, - client, - server_stream, - collection->db, - collection->collection, - NULL, - 0, - NULL, - &result); - - r = MONGOC_WRITE_RESULT_COMPLETE (&result, - 2, - collection->write_concern, - (mongoc_error_domain_t) 0, - &reply, - &error); - ASSERT_OR_PRINT (r, error); - BSON_ASSERT (result.nInserted == 3000); - - _mongoc_write_command_destroy (&command); - _mongoc_write_result_destroy (&result); - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - for (i = 0; i < 3000; i++) { - bson_destroy (docs[i]); - } - - bson_destroy (&reply); - bson_free (docs); - mongoc_server_stream_cleanup (server_stream); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - - -static void -test_invalid_write_concern (void) -{ - mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; - mongoc_write_command_t command; - mongoc_write_result_t result; - mongoc_collection_t *collection; - mongoc_client_t *client; - mongoc_write_concern_t *write_concern; - mongoc_server_stream_t *server_stream; - bson_t *doc; - bson_t reply = BSON_INITIALIZER; - bson_error_t error; - bool r; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - collection = get_test_collection (client, "test_invalid_write_concern"); - BSON_ASSERT (collection); - - write_concern = mongoc_write_concern_new (); - BSON_ASSERT (write_concern); - mongoc_write_concern_set_w (write_concern, 0); - mongoc_write_concern_set_journal (write_concern, true); - BSON_ASSERT (!mongoc_write_concern_is_valid (write_concern)); - - doc = BCON_NEW ("_id", BCON_INT32 (0)); - - _mongoc_write_command_init_insert ( - &command, doc, NULL, write_flags, ++client->cluster.operation_id); - _mongoc_write_result_init (&result); - server_stream = - mongoc_cluster_stream_for_writes (&client->cluster, NULL, NULL, &error); - ASSERT_OR_PRINT (server_stream, error); - _mongoc_write_command_execute (&command, - client, - server_stream, - collection->db, - collection->collection, - write_concern, - 0, - NULL, - &result); - - r = MONGOC_WRITE_RESULT_COMPLETE (&result, - 2, - collection->write_concern, - (mongoc_error_domain_t) 0, - &reply, - &error); - - BSON_ASSERT (!r); - ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_COMMAND); - ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_COMMAND_INVALID_ARG); - - _mongoc_write_command_destroy (&command); - _mongoc_write_result_destroy (&result); - - bson_destroy (doc); - bson_destroy (&reply); - mongoc_server_stream_cleanup (server_stream); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mongoc_write_concern_destroy (write_concern); -} - -static void -test_bypass_validation (void *context) -{ - mongoc_collection_t *collection2; - mongoc_collection_t *collection; - bson_t reply; - mongoc_bulk_operation_t *bulk; - mongoc_database_t *database; - mongoc_write_concern_t *wr; - mongoc_client_t *client; - bson_error_t error; - bson_t *options; - char *collname; - char *dbname; - int r; - int i; - - client = test_framework_client_new (); - BSON_ASSERT (client); - - dbname = gen_collection_name ("dbtest"); - collname = gen_collection_name ("bypass"); - database = mongoc_client_get_database (client, dbname); - collection = mongoc_database_get_collection (database, collname); - BSON_ASSERT (collection); - - options = tmp_bson ( - "{'validator': {'number': {'$gte': 5}}, 'validationAction': 'error'}"); - collection2 = - mongoc_database_create_collection (database, collname, options, &error); - ASSERT_OR_PRINT (collection2, error); - mongoc_collection_destroy (collection2); - - /* {{{ Default fails validation */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - for (i = 0; i < 3; i++) { - bson_t *doc = tmp_bson ("{'number': 3, 'high': %d }", i); - - mongoc_bulk_operation_insert (bulk, doc); - } - r = mongoc_bulk_operation_execute (bulk, &reply, &error); - bson_destroy (&reply); - ASSERT (!r); - - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, 121, "Document failed validation"); - mongoc_bulk_operation_destroy (bulk); - /* }}} */ - - /* {{{ bypass_document_validation=false Fails validation */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - mongoc_bulk_operation_set_bypass_document_validation (bulk, false); - for (i = 0; i < 3; i++) { - bson_t *doc = tmp_bson ("{'number': 3, 'high': %d }", i); - - mongoc_bulk_operation_insert (bulk, doc); - } - r = mongoc_bulk_operation_execute (bulk, &reply, &error); - bson_destroy (&reply); - ASSERT (!r); - - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_COMMAND, 121, "Document failed validation"); - mongoc_bulk_operation_destroy (bulk); - /* }}} */ - - /* {{{ bypass_document_validation=true ignores validation */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - mongoc_bulk_operation_set_bypass_document_validation (bulk, true); - for (i = 0; i < 3; i++) { - bson_t *doc = tmp_bson ("{'number': 3, 'high': %d }", i); - - mongoc_bulk_operation_insert (bulk, doc); - } - r = mongoc_bulk_operation_execute (bulk, &reply, &error); - bson_destroy (&reply); - ASSERT_OR_PRINT (r, error); - mongoc_bulk_operation_destroy (bulk); - /* }}} */ - - /* {{{ w=0 and bypass_document_validation=set fails */ - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - wr = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wr, 0); - mongoc_bulk_operation_set_write_concern (bulk, wr); - mongoc_bulk_operation_set_bypass_document_validation (bulk, true); - for (i = 0; i < 3; i++) { - bson_t *doc = tmp_bson ("{'number': 3, 'high': %d }", i); - - mongoc_bulk_operation_insert (bulk, doc); - } - r = mongoc_bulk_operation_execute (bulk, &reply, &error); - bson_destroy (&reply); - ASSERT_OR_PRINT (!r, error); - ASSERT_ERROR_CONTAINS ( - error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Cannot set bypassDocumentValidation for unacknowledged writes"); - mongoc_bulk_operation_destroy (bulk); - mongoc_write_concern_destroy (wr); - /* }}} */ - - ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); - - bson_free (dbname); - bson_free (collname); - mongoc_database_destroy (database); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); -} - -static void -test_bypass_command_started (const mongoc_apm_command_started_t *event) -{ - ASSERT_HAS_NOT_FIELD (mongoc_apm_command_started_get_command (event), - "bypassDocumentValidation"); -} - -static void -test_bypass_not_sent () -{ - mongoc_collection_t *collection; - mongoc_bulk_operation_t *bulk; - mongoc_find_and_modify_opts_t *opts; - mongoc_client_t *client; - mongoc_database_t *database; - mongoc_apm_callbacks_t *callbacks; - bson_error_t error; - bool r; - bson_t *doc; - const bson_t *agg_doc; - bson_t reply; - bson_t *update; - bson_t *query; - bson_t *pipeline; - bson_t *agg_opts; - mongoc_cursor_t *cursor; - char *collname; - char *dbname; - - client = test_framework_client_new (); - - /* set up command monitoring for started commands */ - callbacks = mongoc_apm_callbacks_new (); - mongoc_apm_set_command_started_cb (callbacks, test_bypass_command_started); - mongoc_client_set_apm_callbacks (client, callbacks, NULL); - mongoc_apm_callbacks_destroy (callbacks); - - dbname = "test"; - collname = gen_collection_name ("bypass"); - database = mongoc_client_get_database (client, dbname); - collection = mongoc_database_get_collection (database, collname); - - bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL); - - /* we explicitly set this to false to test that it isn't sent */ - mongoc_bulk_operation_set_bypass_document_validation (bulk, false); - - /* insert a doc */ - doc = BCON_NEW ("x", BCON_INT32 (31)); - mongoc_bulk_operation_insert (bulk, doc); - bson_destroy (doc); - r = (bool) mongoc_bulk_operation_execute (bulk, &reply, &error); - bson_destroy (&reply); - ASSERT_OR_PRINT (r, error); - mongoc_bulk_operation_destroy (bulk); - - opts = mongoc_find_and_modify_opts_new (); - - /* we explicitly set this to false to test that it isn't sent */ - mongoc_find_and_modify_opts_set_bypass_document_validation (opts, false); - - /* find the doc we inserted earlier and modify it */ - update = BCON_NEW ("$set", "{", "x", BCON_INT32 (32), "}"); - mongoc_find_and_modify_opts_set_update (opts, update); - bson_destroy (update); - query = BCON_NEW ("x", BCON_INT32 (31)); - r = mongoc_collection_find_and_modify_with_opts ( - collection, query, opts, &reply, &error); - bson_destroy (&reply); - ASSERT_OR_PRINT (r, error); - bson_destroy (query); - mongoc_find_and_modify_opts_destroy (opts); - - /* we explicitly set this to false to test that it isn't sent */ - agg_opts = BCON_NEW ("bypassDocumentValidation", BCON_BOOL (false)); - - /* aggregate match */ - pipeline = BCON_NEW ("pipeline", "[", "]"); - cursor = mongoc_collection_aggregate ( - collection, MONGOC_QUERY_NONE, pipeline, agg_opts, NULL); - bson_destroy (pipeline); - bson_destroy (agg_opts); - - /* iterate through aggregation results */ - while (mongoc_cursor_next (cursor, &agg_doc)) { - } - - mongoc_cursor_destroy (cursor); - - /* cleanup */ - bson_free (collname); - mongoc_collection_destroy (collection); - mongoc_database_destroy (database); - mongoc_client_destroy (client); -} - -static void -test_split_opquery_with_options (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *coll; - bson_t **docs; - int i; - bson_error_t error; - future_t *future; - request_t *request; - const bson_t *insert; - bson_t opts; - mongoc_write_concern_t *wc; - int n_docs; - - /* Use a reduced maxBsonObjectSize, and wire version for OP_QUERY */ - const char *ismaster = "{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 0," - " 'maxWireVersion': 5," - " 'maxBsonObjectSize': 100}"; - - server = mock_server_new (); - mock_server_auto_ismaster (server, ismaster); - mock_server_run (server); - - /* Create an insert with two batches. Because of the reduced - * maxBsonObjectSize, each document must be less than 100 bytes. - * Because of the hardcoded allowance (see SERVER-10643), and our current - * incorrect batching logic (see CDRIVER-3310) the complete insert - * command can be can be 16k + 100 bytes. - * After CDRIVER-3310, update this test, since the allowance will not be - * taken into consideration for document batching. - * So create enough documents to fill up at least one batch. - */ - n_docs = ((BSON_OBJECT_ALLOWANCE) / tmp_bson ("{ '_id': 1 }")->len) + - 1; /* inexact, but errs towards more than enough documents. */ - docs = bson_malloc (sizeof (bson_t *) * n_docs); - for (i = 0; i < n_docs; i++) { - docs[i] = BCON_NEW ("_id", BCON_INT64 (i)); - } - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - coll = mongoc_client_get_collection (client, "db", "coll"); - - /* Add a write concern, to ensure that it is taken into account during - * splitting. */ - bson_init (&opts); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_wmajority (wc, 100); - mongoc_write_concern_append (wc, &opts); - - future = future_collection_insert_many ( - coll, (const bson_t **) docs, n_docs, &opts, NULL, &error); - /* Mock server recieves first insert. */ - request = mock_server_receives_request (server); - BSON_ASSERT (request); - insert = request_get_doc (request, 0); - /* The total command size is just a hair under BSON_OBJECT_ALLOWANCE (16384) - * + 100 */ - BSON_ASSERT (insert->len == 16482); - mock_server_replies_ok_and_destroys (request); - - /* Mock server recieves second insert. */ - request = mock_server_receives_request (server); - BSON_ASSERT (request); - insert = request_get_doc (request, 0); - /* The size doesn't really matter for the purpose of the test, but check it - * anyway. */ - BSON_ASSERT (insert->len == 10433); - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - - future_destroy (future); - for (i = 0; i < n_docs; i++) { - bson_destroy (docs[i]); - } - bson_free (docs); - bson_destroy (&opts); - mongoc_collection_destroy (coll); - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_opmsg_disconnect_mid_batch_helper (int wire_version) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *coll; - bson_t **docs; - int i; - bson_error_t error; - future_t *future; - request_t *request; - int n_docs; - - /* Use a reduced maxBsonObjectSize, and wire version for OP_QUERY */ - const char *ismaster = "{'ok': 1.0," - " 'ismaster': true," - " 'minWireVersion': 0," - " 'maxWireVersion': %d," - " 'maxBsonObjectSize': 100}"; - - server = mock_server_new (); - mock_server_auto_ismaster (server, ismaster, wire_version); - mock_server_run (server); - - /* create enough documents for two batches. Note, because of our wonky - * batch splitting behavior (to be fixed in CDRIVER-3310) we need add 16K - * of documents. After CDRIVER-3310, we'll need to update this test. */ - n_docs = ((BSON_OBJECT_ALLOWANCE) / tmp_bson ("{ '_id': 1 }")->len) + 1; - docs = bson_malloc (sizeof (bson_t *) * n_docs); - for (i = 0; i < n_docs; i++) { - docs[i] = BCON_NEW ("_id", BCON_INT64 (i)); - } - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - mongoc_client_set_error_api (client, MONGOC_ERROR_API_VERSION_2); - coll = mongoc_client_get_collection (client, "db", "coll"); - - future = future_collection_insert_many ( - coll, (const bson_t **) docs, n_docs, NULL, NULL, &error); - /* Mock server recieves first insert. */ - request = mock_server_receives_request (server); - BSON_ASSERT (request); - mock_server_hangs_up (request); - request_destroy (request); - - BSON_ASSERT (!future_get_bool (future)); - future_destroy (future); - ASSERT_ERROR_CONTAINS ( - error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "socket error"); - - for (i = 0; i < n_docs; i++) { - bson_destroy (docs[i]); - } - bson_free (docs); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -static void -test_opmsg_disconnect_mid_batch (void) -{ - test_opmsg_disconnect_mid_batch_helper (WIRE_VERSION_OP_MSG); - test_opmsg_disconnect_mid_batch_helper (WIRE_VERSION_OP_MSG - 1); -} - -static void -test_w0_legacy_insert_many (void) -{ - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *coll; - bson_t **docs; - bson_error_t error; - future_t *future; - request_t *request; - bson_t opts; - mongoc_write_concern_t *wc; - - /* wire version will use OP_INSERT for w:0 insert many (since no OP_MSG) */ - server = mock_server_new (); - mock_server_auto_ismaster (server, - "{'ismaster': true," - " 'maxWireVersion': 5}"); - mock_server_run (server); - - docs = bson_malloc (sizeof (bson_t *) * 2); - docs[0] = BCON_NEW ("x", BCON_INT32 (1)); - docs[1] = BCON_NEW ("x", BCON_INT32 (2)); - - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - coll = mongoc_client_get_collection (client, "db", "coll"); - - /* Add unacknowldged write concern */ - bson_init (&opts); - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, 0); - mongoc_write_concern_append (wc, &opts); - mongoc_write_concern_destroy (wc); - - future = future_collection_insert_many ( - coll, (const bson_t **) docs, 2, &opts, NULL, &error); - /* Mock server receives one OP_INSERT with two documents */ - request = mock_server_receives_bulk_insert (server, "db.coll", 0, 2); - BSON_ASSERT (request); - - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - - future_destroy (future); - bson_destroy (docs[0]); - bson_destroy (docs[1]); - bson_free (docs); - bson_destroy (&opts); - mongoc_collection_destroy (coll); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - -void -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, - test_framework_skip_if_max_wire_version_less_than_4); - TestSuite_AddMockServerTest (suite, - "/WriteCommand/split_opquery_with_options", - test_split_opquery_with_options); - TestSuite_AddMockServerTest (suite, - "/WriteCommand/insert_disconnect_mid_batch", - test_opmsg_disconnect_mid_batch); - TestSuite_AddMockServerTest (suite, - "/WriteCommand/w0_legacy_insert_many", - test_w0_legacy_insert_many); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-write-concern.c b/lib/mongoc/libmongoc/tests/test-mongoc-write-concern.c deleted file mode 100644 index 137e94bd6f158e7251628519b27632769a30e386..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-write-concern.c +++ /dev/null @@ -1,633 +0,0 @@ -#include <mongoc/mongoc.h> -#include <mongoc/mongoc-write-concern-private.h> -#include <mongoc/mongoc-util-private.h> - -#include "TestSuite.h" -#include "test-conveniences.h" -#include "test-libmongoc.h" -#include "mock_server/mock-server.h" -#include "mock_server/future.h" -#include "mock_server/future-functions.h" - - -static void -test_write_concern_append (void) -{ - mongoc_write_concern_t *wc; - bson_t *cmd; - - cmd = tmp_bson ("{'foo': 1}"); - capture_logs (true); - - /* cannot append invalid writeConcern */ - wc = NULL; - BSON_ASSERT (!mongoc_write_concern_append (wc, cmd)); - - /* append default writeConcern */ - wc = mongoc_write_concern_new (); - ASSERT (mongoc_write_concern_is_default (wc)); - ASSERT_MATCH (cmd, "{'foo': 1, 'writeConcern': {'$exists': false}}"); - - /* append writeConcern with w */ - mongoc_write_concern_set_w (wc, 1); - BSON_ASSERT (mongoc_write_concern_append (wc, cmd)); - - ASSERT (match_bson ( - cmd, tmp_bson ("{'foo': 1, 'writeConcern': {'w': 1}}"), true)); - - mongoc_write_concern_destroy (wc); -} - -static void -test_write_concern_basic (void) -{ - mongoc_write_concern_t *write_concern; - const bson_t *bson; - bson_iter_t iter; - - write_concern = mongoc_write_concern_new (); - - BEGIN_IGNORE_DEPRECATIONS; - - /* - * Test defaults. - */ - ASSERT (write_concern); - ASSERT (!mongoc_write_concern_get_fsync (write_concern)); - ASSERT (!mongoc_write_concern_get_journal (write_concern)); - ASSERT (mongoc_write_concern_get_w (write_concern) == - MONGOC_WRITE_CONCERN_W_DEFAULT); - ASSERT (!mongoc_write_concern_get_wtimeout_int64 (write_concern)); - ASSERT (!mongoc_write_concern_get_wmajority (write_concern)); - - mongoc_write_concern_set_fsync (write_concern, true); - ASSERT (mongoc_write_concern_get_fsync (write_concern)); - mongoc_write_concern_set_fsync (write_concern, false); - ASSERT (!mongoc_write_concern_get_fsync (write_concern)); - - mongoc_write_concern_set_journal (write_concern, true); - ASSERT (mongoc_write_concern_get_journal (write_concern)); - mongoc_write_concern_set_journal (write_concern, false); - ASSERT (!mongoc_write_concern_get_journal (write_concern)); - - /* - * Test changes to w. - */ - mongoc_write_concern_set_w (write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY); - ASSERT (mongoc_write_concern_get_wmajority (write_concern)); - mongoc_write_concern_set_w (write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT); - ASSERT (!mongoc_write_concern_get_wmajority (write_concern)); - mongoc_write_concern_set_wmajority (write_concern, 1000); - ASSERT (mongoc_write_concern_get_wmajority (write_concern)); - ASSERT (mongoc_write_concern_get_wtimeout (write_concern) == 1000); - mongoc_write_concern_set_wtimeout (write_concern, 0); - ASSERT (!mongoc_write_concern_get_wtimeout (write_concern)); - mongoc_write_concern_set_wtimeout_int64 (write_concern, INT64_MAX); - ASSERT (mongoc_write_concern_get_wtimeout_int64 (write_concern) == INT64_MAX); - mongoc_write_concern_set_w (write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT); - ASSERT (mongoc_write_concern_get_w (write_concern) == - MONGOC_WRITE_CONCERN_W_DEFAULT); - mongoc_write_concern_set_w (write_concern, 3); - ASSERT (mongoc_write_concern_get_w (write_concern) == 3); - - /* - * Check generated bson. - */ - mongoc_write_concern_set_fsync (write_concern, true); - mongoc_write_concern_set_journal (write_concern, true); - - bson = _mongoc_write_concern_get_bson (write_concern); - ASSERT (bson); - ASSERT (bson_iter_init_find (&iter, bson, "fsync") && - BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)); - ASSERT (bson_iter_init_find (&iter, bson, "j") && - BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)); - ASSERT (bson_iter_init_find (&iter, bson, "w") && - BSON_ITER_HOLDS_INT32 (&iter) && bson_iter_int32 (&iter) == 3); - - mongoc_write_concern_destroy (write_concern); - - END_IGNORE_DEPRECATIONS; -} - - -static void -test_write_concern_bson_omits_defaults (void) -{ - mongoc_write_concern_t *write_concern; - const bson_t *bson; - bson_iter_t iter; - - write_concern = mongoc_write_concern_new (); - - /* - * Check generated bson. - */ - ASSERT (write_concern); - - bson = _mongoc_write_concern_get_bson (write_concern); - ASSERT (bson); - ASSERT (!bson_iter_init_find (&iter, bson, "fsync")); - ASSERT (!bson_iter_init_find (&iter, bson, "j")); - - mongoc_write_concern_destroy (write_concern); -} - - -static void -test_write_concern_bson_includes_false_fsync_and_journal (void) -{ - mongoc_write_concern_t *write_concern; - const bson_t *bson; - bson_iter_t iter; - - write_concern = mongoc_write_concern_new (); - - /* - * Check generated bson. - */ - ASSERT (write_concern); - mongoc_write_concern_set_fsync (write_concern, false); - mongoc_write_concern_set_journal (write_concern, false); - - bson = _mongoc_write_concern_get_bson (write_concern); - ASSERT (bson); - ASSERT (bson_iter_init_find (&iter, bson, "fsync") && - BSON_ITER_HOLDS_BOOL (&iter) && !bson_iter_bool (&iter)); - ASSERT (bson_iter_init_find (&iter, bson, "j") && - BSON_ITER_HOLDS_BOOL (&iter) && !bson_iter_bool (&iter)); - ASSERT (!bson_iter_init_find (&iter, bson, "w")); - - mongoc_write_concern_destroy (write_concern); -} - - -static void -test_write_concern_fsync_and_journal_w1_and_validity (void) -{ - mongoc_write_concern_t *write_concern = mongoc_write_concern_new (); - - /* - * Journal and fsync should imply w=1 regardless of w; however, journal and - * fsync logically conflict with w=0 and w=-1, so a write concern with such - * a combination of options will be considered invalid. - */ - - /* No write concern needs GLE, but not "valid" */ - ASSERT (mongoc_write_concern_is_acknowledged (NULL)); - ASSERT (!mongoc_write_concern_is_valid (NULL)); - - /* Default write concern needs GLE and is valid */ - ASSERT (write_concern); - ASSERT (mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (mongoc_write_concern_is_valid (write_concern)); - ASSERT (!mongoc_write_concern_journal_is_set (write_concern)); - - /* w=0 does not need GLE and is valid */ - mongoc_write_concern_set_w (write_concern, - MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); - ASSERT (!mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (mongoc_write_concern_is_valid (write_concern)); - ASSERT (!mongoc_write_concern_journal_is_set (write_concern)); - - /* fsync=true needs GLE, but it conflicts with w=0 */ - mongoc_write_concern_set_fsync (write_concern, true); - ASSERT (mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (!mongoc_write_concern_is_valid (write_concern)); - ASSERT (!mongoc_write_concern_journal_is_set (write_concern)); - mongoc_write_concern_set_fsync (write_concern, false); - - /* journal=true needs GLE, but it conflicts with w=0 */ - mongoc_write_concern_set_journal (write_concern, true); - ASSERT (mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (!mongoc_write_concern_is_valid (write_concern)); - ASSERT (mongoc_write_concern_journal_is_set (write_concern)); - mongoc_write_concern_set_journal (write_concern, false); - - /* w=-1 does not need GLE and is valid */ - mongoc_write_concern_set_w (write_concern, - MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED); - ASSERT (!mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (mongoc_write_concern_is_valid (write_concern)); - ASSERT (mongoc_write_concern_journal_is_set (write_concern)); - - /* fsync=true needs GLE, but it conflicts with w=-1 */ - mongoc_write_concern_set_fsync (write_concern, true); - ASSERT (mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (!mongoc_write_concern_is_valid (write_concern)); - ASSERT (mongoc_write_concern_journal_is_set (write_concern)); - - /* journal=true needs GLE, but it conflicts with w=-1 */ - mongoc_write_concern_set_fsync (write_concern, false); - mongoc_write_concern_set_journal (write_concern, true); - ASSERT (mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (mongoc_write_concern_journal_is_set (write_concern)); - - /* fsync=true with w=default needs GLE and is valid */ - mongoc_write_concern_set_journal (write_concern, false); - mongoc_write_concern_set_fsync (write_concern, true); - mongoc_write_concern_set_w (write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT); - ASSERT (mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (mongoc_write_concern_is_valid (write_concern)); - ASSERT (mongoc_write_concern_journal_is_set (write_concern)); - - /* journal=true with w=default needs GLE and is valid */ - mongoc_write_concern_set_journal (write_concern, false); - mongoc_write_concern_set_fsync (write_concern, true); - mongoc_write_concern_set_w (write_concern, MONGOC_WRITE_CONCERN_W_DEFAULT); - ASSERT (mongoc_write_concern_is_acknowledged (write_concern)); - ASSERT (mongoc_write_concern_is_valid (write_concern)); - ASSERT (mongoc_write_concern_journal_is_set (write_concern)); - - mongoc_write_concern_destroy (write_concern); -} - -static void -test_write_concern_wtimeout_validity (void) -{ - mongoc_write_concern_t *write_concern = mongoc_write_concern_new (); - - /* Test defaults */ - ASSERT (write_concern); - ASSERT (mongoc_write_concern_get_w (write_concern) == - MONGOC_WRITE_CONCERN_W_DEFAULT); - ASSERT (mongoc_write_concern_get_wtimeout_int64 (write_concern) == 0); - ASSERT (!mongoc_write_concern_get_wmajority (write_concern)); - - /* mongoc_write_concern_set_wtimeout_int64() ignores invalid wtimeout */ - mongoc_write_concern_set_wtimeout_int64 (write_concern, -1); - ASSERT (mongoc_write_concern_get_w (write_concern) == - MONGOC_WRITE_CONCERN_W_DEFAULT); - ASSERT (mongoc_write_concern_get_wtimeout_int64 (write_concern) == 0); - ASSERT (!mongoc_write_concern_get_wmajority (write_concern)); - ASSERT (mongoc_write_concern_is_valid (write_concern)); - - /* mongoc_write_concern_set_wmajority() ignores invalid wtimeout */ - mongoc_write_concern_set_wmajority (write_concern, -1); - ASSERT (mongoc_write_concern_get_w (write_concern) == - MONGOC_WRITE_CONCERN_W_MAJORITY); - ASSERT (mongoc_write_concern_get_wtimeout_int64 (write_concern) == 0); - ASSERT (mongoc_write_concern_get_wmajority (write_concern)); - ASSERT (mongoc_write_concern_is_valid (write_concern)); - - /* Manually assigning a negative wtimeout will make the write concern invalid - */ - write_concern->wtimeout = -1; - ASSERT (!mongoc_write_concern_is_valid (write_concern)); - - mongoc_write_concern_destroy (write_concern); -} - -static void -_test_write_concern_from_iterator (const char *swc, bool ok, bool is_default) -{ - bson_t *bson = tmp_bson (swc); - const bson_t *bson2; - mongoc_write_concern_t *wc; - bson_iter_t iter; - bson_error_t error; - - if (test_suite_debug_output ()) { - fprintf (stdout, " - %s\n", swc); - fflush (stdout); - } - - bson_iter_init_find (&iter, bson, "writeConcern"); - wc = _mongoc_write_concern_new_from_iter (&iter, &error); - if (ok) { - BSON_ASSERT (wc); - ASSERT (mongoc_write_concern_is_default (wc) == is_default); - bson2 = _mongoc_write_concern_get_bson (wc); - ASSERT (bson_compare (bson, bson2)); - mongoc_write_concern_destroy (wc); - } else { - BSON_ASSERT (!wc); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_COMMAND_INVALID_ARG, - "Invalid writeConcern"); - } -} - -static void -test_write_concern_from_iterator (void) -{ - _test_write_concern_from_iterator ("{'writeConcern': {}}", true, true); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 'majority'}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 'majority', 'j': true}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 'sometag'}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 'sometag', 'j': true}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 'sometag', 'j': false}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 1, 'j': true}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 1, 'j': false}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 0, 'j': true}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 0, 'j': false}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 42}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 1}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'j': true}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'j': false}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': -1}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': -2}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': -3}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': -4}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': -5}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 'majority', 'wtimeout': 42}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 'sometag', 'wtimeout': 42}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'wtimeout': 42}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'wtimeout': -42}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'wtimeout': {'$numberLong': '123'}}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'wtimeout': {'$numberLong': '2147483648'}}}", - true, - false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 1, 'wtimeout': 42}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 0, 'wtimeout': 42}}", true, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': 1.0}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': {'some': 'stuff'}}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'w': []}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'wtimeout': 'never'}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'j': 'never'}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'j': 1.0}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'fsync': 1.0}}", false, false); - _test_write_concern_from_iterator ( - "{'writeConcern': {'fsync': true}}", true, false); -} - - -static void -test_write_concern_always_mutable (void) -{ - mongoc_write_concern_t *write_concern; - - write_concern = mongoc_write_concern_new (); - - ASSERT (write_concern); - - mongoc_write_concern_set_fsync (write_concern, true); - ASSERT_MATCH (_mongoc_write_concern_get_bson (write_concern), - "{'fsync': true}"); - - mongoc_write_concern_set_journal (write_concern, true); - ASSERT_MATCH (_mongoc_write_concern_get_bson (write_concern), - "{'fsync': true, 'j': true}"); - - mongoc_write_concern_set_w (write_concern, 2); - ASSERT_MATCH (_mongoc_write_concern_get_bson (write_concern), - "{'w': 2, 'fsync': true, 'j': true}"); - - mongoc_write_concern_set_wtimeout_int64 (write_concern, 100); - ASSERT_MATCH (_mongoc_write_concern_get_bson (write_concern), - "{'w': 2, 'fsync': true, 'j': true, 'wtimeout': 100}"); - - mongoc_write_concern_set_wmajority (write_concern, 200); - ASSERT_MATCH ( - _mongoc_write_concern_get_bson (write_concern), - "{'w': 'majority', 'fsync': true, 'j': true, 'wtimeout': 200}"); - - mongoc_write_concern_set_wtag (write_concern, "MultipleDC"); - ASSERT_MATCH ( - _mongoc_write_concern_get_bson (write_concern), - "{'w': 'MultipleDC', 'fsync': true, 'j': true, 'wtimeout': 200}"); - - mongoc_write_concern_destroy (write_concern); -} - - -static void -_test_wc_request (future_t *future, - mock_server_t *server, - bson_error_t *error, - bool allow) -{ - request_t *request; - - if (allow) { - request = mock_server_receives_command ( - server, "db", MONGOC_QUERY_NONE, "{'writeConcern': {'w': 2}}"); - mock_server_replies_ok_and_destroys (request); - BSON_ASSERT (future_get_bool (future)); - } else { - BSON_ASSERT (!future_get_bool (future)); - ASSERT_ERROR_CONTAINS ((*error), - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "does not support writeConcern"); - } - - future_destroy (future); -} - - -static void -_test_write_concern_wire_version (bool allow) -{ - bson_t *opts; - mock_server_t *server; - mongoc_client_t *client; - mongoc_collection_t *collection; - mongoc_cursor_t *cursor; - future_t *future; - bson_error_t error; - - opts = tmp_bson ("{'writeConcern': {'w': 2}}"); - server = mock_server_with_autoismaster ( - allow ? WIRE_VERSION_CMD_WRITE_CONCERN - : WIRE_VERSION_CMD_WRITE_CONCERN - 1); - mock_server_run (server); - client = mongoc_client_new_from_uri (mock_server_get_uri (server)); - collection = mongoc_client_get_collection (client, "db", "collection"); - - /* - * aggregate with $out - */ - cursor = mongoc_collection_aggregate (collection, - MONGOC_QUERY_NONE, - tmp_bson ("[{'$out': 'foo'}]"), - opts, - NULL); - if (allow) { - ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error); - } else { - BSON_ASSERT (mongoc_cursor_error (cursor, &error)); - ASSERT_ERROR_CONTAINS (error, - MONGOC_ERROR_COMMAND, - MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, - "does not support writeConcern"); - } - - /* - * generic mongoc_client_write_command_with_opts - */ - future = future_client_write_command_with_opts ( - client, "db", tmp_bson ("{'foo': 1}"), opts, NULL, &error); - _test_wc_request (future, server, &error, allow); - - /* - * drop - */ - future = future_collection_drop_with_opts (collection, opts, &error); - _test_wc_request (future, server, &error, allow); - - mongoc_cursor_destroy (cursor); - mongoc_collection_destroy (collection); - mongoc_client_destroy (client); - mock_server_destroy (server); -} - - -static void -test_write_concern_allowed (void) -{ - _test_write_concern_wire_version (true); -} - - -static void -test_write_concern_prohibited (void) -{ - _test_write_concern_wire_version (false); -} - -/* Test that CDRIVER-2902 has been fixed. - * The bug was that we did not correctly swab for the flagBits in OP_MSG. */ -static void -test_write_concern_unacknowledged (void) -{ - mongoc_client_t *client; - mongoc_write_concern_t *wc; - mongoc_collection_t *coll; - bson_error_t error; - bool r; - bson_t reply; - bson_t opts; - const bson_t **docs; - - client = test_framework_client_new (); - coll = mongoc_client_get_collection (client, "db", "coll"); - - /* w:0 in OP_MSG is indicated by setting the moreToCome flag in OP_MSG. That - * tells the recipient not to send a response. */ - wc = mongoc_write_concern_new (); - mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); - bson_init (&opts); - mongoc_write_concern_append (wc, &opts); - - /* In this insert_one with w:0, we write an OP_MSG on the socket, but don't - * read a reply. Before CDRIVER-2902 was fixed, since we forget to set - * moreToCome, the server still sends a reply. */ - r = mongoc_collection_insert_one ( - coll, tmp_bson ("{}"), &opts, &reply, &error); - ASSERT_OR_PRINT (r, error); - ASSERT (bson_empty (&reply)); - bson_destroy (&reply); - bson_destroy (&opts); - - docs = bson_malloc0 (sizeof (bson_t *) * 2); - docs[0] = tmp_bson ("{}"); - docs[1] = tmp_bson ("{}"); - - /* In the next insert_many, before CDRIVER-2902 was fixed, we would read that - * old reply. */ - r = mongoc_collection_insert_many (coll, docs, 2, NULL, &reply, &error); - bson_free (docs); - ASSERT_OR_PRINT (r, error); - - /* The replies are distinguished by the insertedCount. */ - ASSERT_MATCH (&reply, "{'insertedCount': 2}"); - - bson_destroy (&reply); - mongoc_collection_destroy (coll); - mongoc_write_concern_destroy (wc); - mongoc_client_destroy (client); -} - - -/* Regression test to to demonstrate that a 64-bit wtimeoutms value is properly - * preserved. */ -static void -test_write_concern_wtimeout_preserved (void) -{ - mongoc_write_concern_t *write_concern = mongoc_write_concern_new (); - bson_t *cmd = tmp_bson ("{}"); - bson_iter_t iter; - bson_iter_t child; - - ASSERT (write_concern); - - mongoc_write_concern_set_wtimeout_int64 (write_concern, INT64_MAX); - mongoc_write_concern_append (write_concern, cmd); - - ASSERT (bson_iter_init_find (&iter, cmd, "writeConcern")); - ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); - ASSERT (bson_iter_recurse (&iter, &child)); - ASSERT (bson_iter_next (&child)); - ASSERT_CMPSTR (bson_iter_key (&child), "wtimeout"); - ASSERT_CMPINT64 (bson_iter_int64 (&child), ==, INT64_MAX); - - mongoc_write_concern_destroy (write_concern); -} - - -void -test_write_concern_install (TestSuite *suite) -{ - TestSuite_Add (suite, "/WriteConcern/append", test_write_concern_append); - TestSuite_Add (suite, "/WriteConcern/basic", test_write_concern_basic); - TestSuite_Add (suite, - "/WriteConcern/bson_omits_defaults", - test_write_concern_bson_omits_defaults); - TestSuite_Add (suite, - "/WriteConcern/bson_includes_false_fsync_and_journal", - test_write_concern_bson_includes_false_fsync_and_journal); - TestSuite_Add (suite, - "/WriteConcern/fsync_and_journal_gle_and_validity", - test_write_concern_fsync_and_journal_w1_and_validity); - TestSuite_Add (suite, - "/WriteConcern/wtimeout_validity", - test_write_concern_wtimeout_validity); - TestSuite_Add ( - suite, "/WriteConcern/from_iterator", test_write_concern_from_iterator); - TestSuite_Add ( - suite, "/WriteConcern/always_mutable", test_write_concern_always_mutable); - TestSuite_Add (suite, - "/WriteConcern/wtimeout_preserved", - test_write_concern_wtimeout_preserved); - TestSuite_AddMockServerTest ( - suite, "/WriteConcern/allowed", test_write_concern_allowed); - TestSuite_AddMockServerTest ( - suite, "/WriteConcern/prohibited", test_write_concern_prohibited); - TestSuite_AddLive ( - suite, "/WriteConcern/unacknowledged", test_write_concern_unacknowledged); -} diff --git a/lib/mongoc/libmongoc/tests/test-mongoc-x509.c b/lib/mongoc/libmongoc/tests/test-mongoc-x509.c deleted file mode 100644 index ffb61ee245ecbd7a0dce22957287efc694fa3f82..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/test-mongoc-x509.c +++ /dev/null @@ -1,32 +0,0 @@ -#include <mongoc/mongoc.h> -#include "mongoc/mongoc-ssl-private.h" - -#include "TestSuite.h" - -#if defined(MONGOC_ENABLE_SSL) && !defined(MONGOC_ENABLE_SSL_LIBRESSL) -static void -test_extract_subject (void) -{ - char *subject; - - subject = mongoc_ssl_extract_subject (CERT_SERVER, NULL); - ASSERT_CMPSTR ( - subject, - "C=US,ST=New York,L=New York City,O=MongoDB,OU=Drivers,CN=localhost"); - bson_free (subject); - - subject = mongoc_ssl_extract_subject (CERT_CLIENT, NULL); - ASSERT_CMPSTR ( - subject, "C=US,ST=New York,L=New York City,O=MDB,OU=Drivers,CN=client"); - bson_free (subject); -} -#endif - - -void -test_x509_install (TestSuite *suite) -{ -#if defined(MONGOC_ENABLE_SSL) && !defined(MONGOC_ENABLE_SSL_LIBRESSL) - TestSuite_Add (suite, "/X509/extract_subject", test_extract_subject); -#endif -} diff --git a/lib/mongoc/libmongoc/tests/x509gen/82e9b7a6.0 b/lib/mongoc/libmongoc/tests/x509gen/82e9b7a6.0 deleted file mode 100644 index 6ac86cfcc1ee3129aab684f1093e204190aee7e5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/82e9b7a6.0 +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDfzCCAmegAwIBAgIDB1MGMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIwMjMxMVoXDTM5MDUyMjIwMjMxMVoweTEb -MBkGA1UEAxMSRHJpdmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAw -DgYDVQQKEwdNb25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQI -EwhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCl7VN+WsQfHlwapcOpTLZVoeMAl1LTbWTFuXSAavIyy0W1Ytky1UP/ -bxCSW0mSWwCgqoJ5aXbAvrNRp6ArWu3LsTQIEcD3pEdrFIVQhYzWUs9fXqPyI9k+ -QNNQ+MRFKeGteTPYwF2eVEtPzUHU5ws3+OKp1m6MCLkwAG3RBFUAfddUnLvGoZiT -pd8/eNabhgHvdrCw+tYFCWvSjz7SluEVievpQehrSEPKe8DxJq/IM3tSl3tdylzT -zeiKNO7c7LuQrgjAfrZl7n2SriHIlNmqiDR/kdd8+TxBuxjFlcf2WyHCO3lIcIgH -KXTlhUCg50KfHaxHu05Qw0x8869yIzqbAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADggEBAEHuhTL8KQZcKCTSJbYA9MgZj7U32arMGBbc1hiq -VBREwvdVz4+9tIyWMzN9R/YCKmUTnCq8z3wTlC8kBtxYn/l4Tj8nJYcgLJjQ0Fwe -gT564CmvkUat8uXPz6olOCdwkMpJ9Sj62i0mpgXJdBfxKQ6TZ9yGz6m3jannjZpN -LchB7xSAEWtqUgvNusq0dApJsf4n7jZ+oBZVaQw2+tzaMfaLqHgMwcu1FzA8UKCD -sxCgIsZUs8DdxaD418Ot6nPfheOTqe24n+TTa+Z6O0W0QtnofJBx7tmAo1aEc57i -77s89pfwIJetpIlhzNSMKurCAocFCJMJLAASJFuu6dyDvPo= ------END CERTIFICATE----- \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/x509gen/altname.pem b/lib/mongoc/libmongoc/tests/x509gen/altname.pem deleted file mode 100644 index ff0fd61e67017ea2bdf6efe9addcde0df97bdc52..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/altname.pem +++ /dev/null @@ -1,49 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAgyOELJgWP2akoidBdtchvdRF8gZrR8rwORDmST1tmH5aKiH2 -e/lkWf+pxmXnvmLXoOKk3HHGgyZ7v1sDDB0z7/rAimECqxnqJ90GFq8rGR60jCL/ -hs+30m0U9CNAvjzD5yFruaisPeCZuZXEA06QbTbTaSD4u/n7fgZVGSnj2m+DFel5 -S7dgL4Pa7Vh2nua8QPfczLLQI/uP9Ma5ZXjk2C2V+QBkmK64OanGY6yXn8+m5Lp1 -cKhhQUiXVVO1BgFHw65FapTrhG2zgyuaqvb5F062V+XGIwZhWhDz4cTgCx0dFKU+ -WQGXuEDDY3EzaOd6Ds3h6WkCRDs9cn2i0j4taQIDAQABAoIBAHeCTXkKXPQIia6Q -0dMIuWIy6k9nVCtIIWYQJZ3HUnJva6IL84IFxFNUcBczVV+m2lVvVsjjEwMAdjPs -MDnA/00LGp7BS9o8Mq2DeoH/vuoUlntDhdUIxcAJ0teurNjxraKcTX0T32xAnDeJ -6ekNlwdAuKeM+cDtTykJglH9X/324eOT8sEkpohkTJaszs3PEqgN9jrHttVatmft -KGT06aANBrEH61xr/nfBehd3R7WyVsIUmlihlIIBwbxyycdMSxHIiE1Qno252Ek7 -GJp/dPqO2pwIH47cop48SsZLFVosqaZs3jkEIDkQkyd7tvmVG69aFBPz5+PTvdRv -fufuvXUCgYEA1gTnvln9/PmC9mKFTDGdKLhFIypyOhKl1lUoDgcmCencjwu28yTA -+A2fKZQFupiHYvSg5kbvmr7FGVtKLNPJWocvr7jqPvrVLCzvs6l94LhGCTVyOmgn -e09xyDx3xQTuJmpg+4LD1jImL3OLO3fplbslwisip2CWzHZR6h3QRVMCgYEAnNy5 -F81xbimMVcubQve6LPzZq1pYaUM5ppkejNdBoEKR28+GP0NQ7YbN6iu2LXlbpWk/ -IrAyUmDUpnXFsiRDDWnPol6JzYTovzeZG+NCMJWkaQEOzm8BpUsC2UBvsX55ddxt -WM4CkLOxo7KXfQwYAMKc/H8tFE7DXloH82U7jtMCgYB+PuiBFc7IYlrJgjZFSuL8 -+S33X3uAHC3tL9Bv7fGXWXd8fhmOdfjKmiZwPVvfxUffrJQZInEGpE/Z9EreBJQ7 -LZGIo5iyS/5hj6RaI7oYTDssBXX7VCMuDx/8UQcJli3xRUEuO+XPvUdfKFZSXxrP -81SDpDRN7aEmvQj3BF0t9wKBgCgX5ptl4HtG1V7MhufMB+Md0ckRc42cKC0j8AIR -tu1udneXiHm9C/9aOGGFQLBI15rk1sVYAdS6eT/+1EQfLqBMDk0zGsfUE+VkIZdW -NAHVDcvlAFLVXrdP/+9ln+bfK85rQ+ux5Ef2Fg6ARGYq5Cu1koibPPt20krYejXF -Bz8PAoGBAKbCmptnjdu4QF+rGLfYyVnrtyUuRgN+Q0MCIag1dBTag6rC17xDYJ6g -3Txzzb9xAZ35pSHroB7TSr32vRUQVrAcfldW4mousr9A0pDoc/E2axtE1YmzSYwk -jqgu3PeWrtwBthUEoRXbQAed97bKW+gUU677u9IFRCS2YIfwDV5R ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDnTCCAoWgAwIBAgIDCRkUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIyMzQzNloXDTM5MDUyMjIyMzQzNlowcDES -MBAGA1UEAxMJbG9jYWxob3N0MRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdN -b25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9y -azELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCD -I4QsmBY/ZqSiJ0F21yG91EXyBmtHyvA5EOZJPW2YfloqIfZ7+WRZ/6nGZee+Yteg -4qTcccaDJnu/WwMMHTPv+sCKYQKrGeon3QYWrysZHrSMIv+Gz7fSbRT0I0C+PMPn -IWu5qKw94Jm5lcQDTpBtNtNpIPi7+ft+BlUZKePab4MV6XlLt2Avg9rtWHae5rxA -99zMstAj+4/0xrlleOTYLZX5AGSYrrg5qcZjrJefz6bkunVwqGFBSJdVU7UGAUfD -rkVqlOuEbbODK5qq9vkXTrZX5cYjBmFaEPPhxOALHR0UpT5ZAZe4QMNjcTNo53oO -zeHpaQJEOz1yfaLSPi1pAgMBAAGjNzA1MDMGA1UdEQQsMCqCCWxvY2FsaG9zdIcE -fwAAAYIXYWx0ZXJuYXRpdmUubW9uZ29kYi5jb20wDQYJKoZIhvcNAQELBQADggEB -AADOro10g1QReF0QVX2w+yVwCWy8FUzuksX0RI0RCFRJPo79SH7o2IZFGbLlBL8K -MMsgSrzRW/HcyE91fv0R2b7kvqfD3Eo1W1ocufjVg+3e4uuwm9k9SLjSI6mE4hEf -H6BeFoZhUdbrq9l/ez+NK+3ToHAl1bGLkipfnB522gRO1CjkpiY2knaaNQtjd/a9 -7QXqUs+KMJx42yqjBbVE6MdA2ypNMMIc8AgI5kRKEBGHpS4Z6VNZN4Pus1atGlRW -OwkjHK5pnT1TAKSODjfFw5VlXGztGTPKuJhM2/X7Qi0bO8b7NmH7cjDBATmZF5O8 -FAxIQ8+3qUPMXYkb1ipLOdQ= ------END CERTIFICATE----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/ca.pem b/lib/mongoc/libmongoc/tests/x509gen/ca.pem deleted file mode 100644 index 6ac86cfcc1ee3129aab684f1093e204190aee7e5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/ca.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDfzCCAmegAwIBAgIDB1MGMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIwMjMxMVoXDTM5MDUyMjIwMjMxMVoweTEb -MBkGA1UEAxMSRHJpdmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAw -DgYDVQQKEwdNb25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQI -EwhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCl7VN+WsQfHlwapcOpTLZVoeMAl1LTbWTFuXSAavIyy0W1Ytky1UP/ -bxCSW0mSWwCgqoJ5aXbAvrNRp6ArWu3LsTQIEcD3pEdrFIVQhYzWUs9fXqPyI9k+ -QNNQ+MRFKeGteTPYwF2eVEtPzUHU5ws3+OKp1m6MCLkwAG3RBFUAfddUnLvGoZiT -pd8/eNabhgHvdrCw+tYFCWvSjz7SluEVievpQehrSEPKe8DxJq/IM3tSl3tdylzT -zeiKNO7c7LuQrgjAfrZl7n2SriHIlNmqiDR/kdd8+TxBuxjFlcf2WyHCO3lIcIgH -KXTlhUCg50KfHaxHu05Qw0x8869yIzqbAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADggEBAEHuhTL8KQZcKCTSJbYA9MgZj7U32arMGBbc1hiq -VBREwvdVz4+9tIyWMzN9R/YCKmUTnCq8z3wTlC8kBtxYn/l4Tj8nJYcgLJjQ0Fwe -gT564CmvkUat8uXPz6olOCdwkMpJ9Sj62i0mpgXJdBfxKQ6TZ9yGz6m3jannjZpN -LchB7xSAEWtqUgvNusq0dApJsf4n7jZ+oBZVaQw2+tzaMfaLqHgMwcu1FzA8UKCD -sxCgIsZUs8DdxaD418Ot6nPfheOTqe24n+TTa+Z6O0W0QtnofJBx7tmAo1aEc57i -77s89pfwIJetpIlhzNSMKurCAocFCJMJLAASJFuu6dyDvPo= ------END CERTIFICATE----- \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/x509gen/client-private.pem b/lib/mongoc/libmongoc/tests/x509gen/client-private.pem deleted file mode 100644 index 551a43a75c98c58fca4bdc28f8bddddee5969d9a..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/client-private.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAsNS8UEuin7/K29jXfIOLpIoh1jEyWVqxiie2Onx7uJJKcoKo -khA3XeUnVN0k6X5MwYWcN52xcns7LYtyt06nRpTG2/emoV44w9uKTuHsvUbiOwSV -m/ToKQQ4FUFZoqorXH+ZmJuIpJNfoW+3CkE1vEDCIecIq6BNg5ySsPtvSuSJHGjp -mc7/5ZUDvFE2aJ8QbJU3Ws0HXiEb6ymi048LlzEL2VKX3w6mqqh+7dcZGAy7qYk2 -5FZ9ktKvCeQau7mTyU1hsPrKFiKtMN8Q2ZAItX13asw5/IeSTq2LgLFHlbj5Kpq4 -GmLdNCshzH5X7Ew3IYM8EHmsX8dmD6mhv7vpVwIDAQABAoIBABOdpb4qhcG+3twA -c/cGCKmaASLnljQ/UU6IFTjrsjXJVKTbRaPeVKX/05sgZQXZ0t3s2mV5AsQ2U1w8 -Cd+3w+qaemzQThW8hAOGCROzEDX29QWi/o2sX0ydgTMqaq0Wv3SlWv6I0mGfT45y -/BURIsrdTCvCmz2erLqa1dL4MWJXRFjT9UTs5twlecIOM2IHKoGGagFhymRK4kDe -wTRC9fpfoAgyfus3pCO/wi/F8yKGPDEwY+zgkhrJQ+kSeki7oKdGD1H540vB8gRt -EIqssE0Y6rEYf97WssQlxJgvoJBDSftOijS6mwvoasDUwfFqyyPiirawXWWhHXkc -DjIi/XECgYEA5xfjilw9YyM2UGQNESbNNunPcj7gDZbN347xJwmYmi9AUdPLt9xN -3XaMqqR22k1DUOxC/5hH0uiXir7mDfqmC+XS/ic/VOsa3CDWejkEnyGLiwSHY502 -wD/xWgHwUiGVAG9HY64vnDGm6L3KGXA2oqxanL4V0+0+Ht49pZ16i8sCgYEAw+Ox -CHGtpkzjCP/z8xr+1VTSdpc/4CP2HONnYopcn48KfQnf7Nale69/1kZpypJlvQSG -eeA3jMGigNJEkb8/kaVoRLCisXcwLc0XIfCTeiK6FS0Ka30D/84Qm8UsHxRdpGkM -kYITAa2r64tgRL8as4/ukeXBKE+oOhX43LeEfyUCgYBkf7IX2Ndlhsm3GlvIarxy -NipeP9PGdR/hKlPbq0OvQf9R1q7QrcE7H7Q6/b0mYNV2mtjkOQB7S2WkFDMOP0P5 -BqDEoKLdNkV/F9TOYH+PCNKbyYNrodJOt0Ap6Y/u1+Xpw3sjcXwJDFrO+sKqX2+T -PStG4S+y84jBedsLbDoAEwKBgQCTz7/KC11o2yOFqv09N+WKvBKDgeWlD/2qFr3w -UU9K5viXGVhqshz0k5z25vL09Drowf1nAZVpFMO2SPOMtq8VC6b+Dfr1xmYIaXVH -Gu1tf77CM9Zk/VSDNc66e7GrUgbHBK2DLo+A+Ld9aRIfTcSsMbNnS+LQtCrQibvb -cG7+MQKBgQCY11oMT2dUekoZEyW4no7W5D74lR8ztMjp/fWWTDo/AZGPBY6cZoZF -IICrzYtDT/5BzB0Jh1f4O9ZQkm5+OvlFbmoZoSbMzHL3oJCBOY5K0/kdGXL46WWh -IRJSYakNU6VIS7SjDpKgm9D8befQqZeoSggSjIIULIiAtYgS80vmGA== ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/x509gen/client-public.pem b/lib/mongoc/libmongoc/tests/x509gen/client-public.pem deleted file mode 100644 index 53e4e034f9ee039b3e787616ddba1a79a417e752..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/client-public.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDgzCCAmugAwIBAgIDAxOUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIzNTU1NFoXDTM5MDUyMjIzNTU1NFowaTEP -MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx -FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD -VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDUvFBLop+/ -ytvY13yDi6SKIdYxMllasYontjp8e7iSSnKCqJIQN13lJ1TdJOl+TMGFnDedsXJ7 -Oy2LcrdOp0aUxtv3pqFeOMPbik7h7L1G4jsElZv06CkEOBVBWaKqK1x/mZibiKST -X6FvtwpBNbxAwiHnCKugTYOckrD7b0rkiRxo6ZnO/+WVA7xRNmifEGyVN1rNB14h -G+spotOPC5cxC9lSl98Opqqofu3XGRgMu6mJNuRWfZLSrwnkGru5k8lNYbD6yhYi -rTDfENmQCLV9d2rMOfyHkk6ti4CxR5W4+SqauBpi3TQrIcx+V+xMNyGDPBB5rF/H -Zg+pob+76VcCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF -BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAqRcLAGvYMaGYOV4HJTzNotT2qE0I9THNQ -wOV1fBg69x6SrUQTQLjJEptpOA288Wue6Jt3H+p5qAGV5GbXjzN/yjCoItggSKxG -Xg7279nz6/C5faoIKRjpS9R+MsJGlttP9nUzdSxrHvvqm62OuSVFjjETxD39DupE -YPFQoHOxdFTtBQlc/zIKxVdd20rs1xJeeU2/L7jtRBSPuR/Sk8zot7G2/dQHX49y -kHrq8qz12kj1T6XDXf8KZawFywXaz0/Ur+fUYKmkVk1T0JZaNtF4sKqDeNE4zcns -p3xLVDSl1Q5Gwj7bgph9o4Hxs9izPwiqjmNaSjPimGYZ399zcurY ------END CERTIFICATE----- \ No newline at end of file diff --git a/lib/mongoc/libmongoc/tests/x509gen/client.pem b/lib/mongoc/libmongoc/tests/x509gen/client.pem deleted file mode 100644 index 5b070010920d3159a2b4eb1bed834508fb799fde..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/client.pem +++ /dev/null @@ -1,48 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAsNS8UEuin7/K29jXfIOLpIoh1jEyWVqxiie2Onx7uJJKcoKo -khA3XeUnVN0k6X5MwYWcN52xcns7LYtyt06nRpTG2/emoV44w9uKTuHsvUbiOwSV -m/ToKQQ4FUFZoqorXH+ZmJuIpJNfoW+3CkE1vEDCIecIq6BNg5ySsPtvSuSJHGjp -mc7/5ZUDvFE2aJ8QbJU3Ws0HXiEb6ymi048LlzEL2VKX3w6mqqh+7dcZGAy7qYk2 -5FZ9ktKvCeQau7mTyU1hsPrKFiKtMN8Q2ZAItX13asw5/IeSTq2LgLFHlbj5Kpq4 -GmLdNCshzH5X7Ew3IYM8EHmsX8dmD6mhv7vpVwIDAQABAoIBABOdpb4qhcG+3twA -c/cGCKmaASLnljQ/UU6IFTjrsjXJVKTbRaPeVKX/05sgZQXZ0t3s2mV5AsQ2U1w8 -Cd+3w+qaemzQThW8hAOGCROzEDX29QWi/o2sX0ydgTMqaq0Wv3SlWv6I0mGfT45y -/BURIsrdTCvCmz2erLqa1dL4MWJXRFjT9UTs5twlecIOM2IHKoGGagFhymRK4kDe -wTRC9fpfoAgyfus3pCO/wi/F8yKGPDEwY+zgkhrJQ+kSeki7oKdGD1H540vB8gRt -EIqssE0Y6rEYf97WssQlxJgvoJBDSftOijS6mwvoasDUwfFqyyPiirawXWWhHXkc -DjIi/XECgYEA5xfjilw9YyM2UGQNESbNNunPcj7gDZbN347xJwmYmi9AUdPLt9xN -3XaMqqR22k1DUOxC/5hH0uiXir7mDfqmC+XS/ic/VOsa3CDWejkEnyGLiwSHY502 -wD/xWgHwUiGVAG9HY64vnDGm6L3KGXA2oqxanL4V0+0+Ht49pZ16i8sCgYEAw+Ox -CHGtpkzjCP/z8xr+1VTSdpc/4CP2HONnYopcn48KfQnf7Nale69/1kZpypJlvQSG -eeA3jMGigNJEkb8/kaVoRLCisXcwLc0XIfCTeiK6FS0Ka30D/84Qm8UsHxRdpGkM -kYITAa2r64tgRL8as4/ukeXBKE+oOhX43LeEfyUCgYBkf7IX2Ndlhsm3GlvIarxy -NipeP9PGdR/hKlPbq0OvQf9R1q7QrcE7H7Q6/b0mYNV2mtjkOQB7S2WkFDMOP0P5 -BqDEoKLdNkV/F9TOYH+PCNKbyYNrodJOt0Ap6Y/u1+Xpw3sjcXwJDFrO+sKqX2+T -PStG4S+y84jBedsLbDoAEwKBgQCTz7/KC11o2yOFqv09N+WKvBKDgeWlD/2qFr3w -UU9K5viXGVhqshz0k5z25vL09Drowf1nAZVpFMO2SPOMtq8VC6b+Dfr1xmYIaXVH -Gu1tf77CM9Zk/VSDNc66e7GrUgbHBK2DLo+A+Ld9aRIfTcSsMbNnS+LQtCrQibvb -cG7+MQKBgQCY11oMT2dUekoZEyW4no7W5D74lR8ztMjp/fWWTDo/AZGPBY6cZoZF -IICrzYtDT/5BzB0Jh1f4O9ZQkm5+OvlFbmoZoSbMzHL3oJCBOY5K0/kdGXL46WWh -IRJSYakNU6VIS7SjDpKgm9D8befQqZeoSggSjIIULIiAtYgS80vmGA== ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDgzCCAmugAwIBAgIDAxOUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIzNTU1NFoXDTM5MDUyMjIzNTU1NFowaTEP -MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx -FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD -VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDUvFBLop+/ -ytvY13yDi6SKIdYxMllasYontjp8e7iSSnKCqJIQN13lJ1TdJOl+TMGFnDedsXJ7 -Oy2LcrdOp0aUxtv3pqFeOMPbik7h7L1G4jsElZv06CkEOBVBWaKqK1x/mZibiKST -X6FvtwpBNbxAwiHnCKugTYOckrD7b0rkiRxo6ZnO/+WVA7xRNmifEGyVN1rNB14h -G+spotOPC5cxC9lSl98Opqqofu3XGRgMu6mJNuRWfZLSrwnkGru5k8lNYbD6yhYi -rTDfENmQCLV9d2rMOfyHkk6ti4CxR5W4+SqauBpi3TQrIcx+V+xMNyGDPBB5rF/H -Zg+pob+76VcCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF -BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAqRcLAGvYMaGYOV4HJTzNotT2qE0I9THNQ -wOV1fBg69x6SrUQTQLjJEptpOA288Wue6Jt3H+p5qAGV5GbXjzN/yjCoItggSKxG -Xg7279nz6/C5faoIKRjpS9R+MsJGlttP9nUzdSxrHvvqm62OuSVFjjETxD39DupE -YPFQoHOxdFTtBQlc/zIKxVdd20rs1xJeeU2/L7jtRBSPuR/Sk8zot7G2/dQHX49y -kHrq8qz12kj1T6XDXf8KZawFywXaz0/Ur+fUYKmkVk1T0JZaNtF4sKqDeNE4zcns -p3xLVDSl1Q5Gwj7bgph9o4Hxs9izPwiqjmNaSjPimGYZ399zcurY ------END CERTIFICATE----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/commonName.pem b/lib/mongoc/libmongoc/tests/x509gen/commonName.pem deleted file mode 100644 index e8ebd4953f15ef8842135afa916041cdfdff2602..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/commonName.pem +++ /dev/null @@ -1,48 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEArS94Vnpx+C+LwiCIyfZH45uwDbiEqCKr0hfWPVlJdoOQgaDO -av9nbxRvx+CnsiZ1yE6Kj1NYIX3FqOzO9YizwKtPaxCqFMjDzl1HZCJ8LTZZzMic -01K38wGfacsBwno/sNZn9jgnT+9JOasD6854IAs5T7dRCFH/nxV+RuZ4ueTWIcfH -jXzAZv9+wtu0sVmQKHV0J3S6ZdPqqDaYRdhOCyShBTO4RbUW1myIjooIqqy/xceV -TmXGWycqZjyDDronT1kj/yx6znqudOeDzj1PaEdnsqdXxQlI7MVdRf3nXdDXTpw5 -gPhqxqYc47vL6RvMxqief0BJnlc6PoZWoyTRPwIDAQABAoIBAQCYNMYwSsDrfO35 -mRpfVYHs+iGKjYaZNo+Hv8dcd6Jm9E4Gf0urIfjH2VA8fKclnUOa3dxNBtTH6n/T -bPyfMpu4U1cjI6w3RBNCxRw/V0eHfOMDZbTezS459k0ib3aGc2aShn0sGkICsKzM -cA6sKfPNRdACzXv8MgTUzdEDgv7LcGwNUKYzz/XWZxOX+XpeAGNSdXxv6ASvZNJ7 -u3Ba6LbOSAjxnKK24qdBDwCfuxRvD6ovenvI3+qIDSZSrEs/ofGhEEdKlQiyUAgS -m40kWqtoq9sC4/6cGxCLw9scuwXhwE0NNP19QRjh6Hsmr6qmu8LJAKugJi+5WyLg -1oHLs91xAoGBAO4oy6cdc57UdL7A2UbFDWJkBlySw0ChCK4I49Sfq/IISpd3mOfH -SxpZoh5IEnKTEYSqMi/kUUt8J/kQhjdAhqyA33GuNekfGPumUxyB8nKtowNNevyv -Ou6Y9FmzwEektvTLoku/4GxVbrgE262YEu/U1bMA700YK88knCtRWrtFAoGBALoo -qdUpb9s0NK0K4pGo8NYdtqVraOkXPAhKCCOY+hnl0yJERU7LLM9pYCMmR9m/TPcA -pXZTETPWcB6SDJoH3nCmje1Bt3xTxnSvt9P8lXYfvgVpKz8zBrvvnZqUDbMUjWe+ -vz9/jRKrarKgzG6KLnLgFV9sNbuSoOER4/h7MmCzAoGARP2qaUHd4Y/4Nd4V0yt4 -Qh1pvl2BlHJR2mCW51xN6jI+sXwi3lncRsjabt1AAtLZy02mdjs01aIkzkDcMJtP -qB85G2x1D5BDo3q+Ls7yFgh45ZcHXrXAY6gJeQbaV6a+nVF0NW9jKt7g0QwPO02H -htRoB4/owrOS1VHsr5vEpeUCgYAsWg/MZ2js8s0yBQvh5Dws5ztiwepmzlBRMUIr -KQE9NlJNMbLJiQKOD+8FsNMhf8BYgODrBfNtREPGJMm30PQgJq5dvnB2wIbhuhOz -/9OkJv/gziOtlPyfvgDwmSGCbv0ZoIp0GHGF5y0ujbznASj72YN+DovmupJ1zQth -YgionQKBgDGtSfvf3VpJxoabJ52tC0vJFDzkqdbOT0imuLjRHmUH4pSKuMvanvVk -kYcHXeQcfLOPjH18UUqTIgK5vXXjJraduq2bGyvdLcbd3xmj5guzfim3FP83Lh/U -OMAbRgBdq3rlylRqcZh0NqV05L0kJ0Wt1XIaV/eknpuFz5nD7O+y ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDcTCCAlmgAwIBAgIDB5VBMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIxMDUxNVoXDTM5MDUyMjIxMDUxNVowfTEf -MB0GA1UEAxMWY29tbW9uTmFtZS5tb25nb2RiLm9yZzEQMA4GA1UECxMHRHJpdmVy -czEQMA4GA1UEChMHTW9uZ29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8G -A1UECBMITmV3IFlvcmsxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEArS94Vnpx+C+LwiCIyfZH45uwDbiEqCKr0hfWPVlJdoOQgaDO -av9nbxRvx+CnsiZ1yE6Kj1NYIX3FqOzO9YizwKtPaxCqFMjDzl1HZCJ8LTZZzMic -01K38wGfacsBwno/sNZn9jgnT+9JOasD6854IAs5T7dRCFH/nxV+RuZ4ueTWIcfH -jXzAZv9+wtu0sVmQKHV0J3S6ZdPqqDaYRdhOCyShBTO4RbUW1myIjooIqqy/xceV -TmXGWycqZjyDDronT1kj/yx6znqudOeDzj1PaEdnsqdXxQlI7MVdRf3nXdDXTpw5 -gPhqxqYc47vL6RvMxqief0BJnlc6PoZWoyTRPwIDAQABMA0GCSqGSIb3DQEBCwUA -A4IBAQA34DUMfx0YaxsXnNlCmbkncwgb69VfwWTqtON2MabOlw9fQ0Z5YlwduBSD -DxkRosVURdqV+EcGxei6opnPkdoJ+1mkCDo360q+R/bJUFqjj7djB7GCwwK/Eud4 -Jjn//eLBChU+DlTjO1yL8haEQR70LyVz37sh28oIRqoTS3Nk2SZg7Gnor1qHwd6j -OljaM1WiTJfq6XCSZ9/3C5Ix0Vr7xZaP9Dn5lgQ86du6N6tmaKqVobCw3vjITmnr -eZTC7dKU4/O52d6lHZ1vv8GyvqrRCeiolTVzhW47GvO/n+snC0NMkXvoo7Rzv1S/ -FxHvlhiH5wCbaGnBx4uF5/boedV+ ------END CERTIFICATE----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/crl.pem b/lib/mongoc/libmongoc/tests/x509gen/crl.pem deleted file mode 100644 index 733a0acdc0760a1bbc5ad3dcf93620aad97ffa1e..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/crl.pem +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN X509 CRL----- -MIIB6jCB0wIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDExJEcml2ZXJzIFRl -c3RpbmcgQ0ExEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01vbmdvREIxFjAU -BgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQG -EwJVUxcNMTkwNTIyMjI0NTUzWhcNMTkwNjIxMjI0NTUzWjAVMBMCAncVFw0xOTA1 -MjIyMjQ1MzJaoA8wDTALBgNVHRQEBAICEAAwDQYJKoZIhvcNAQELBQADggEBACwQ -W9OF6ExJSzzYbpCRroznkfdLG7ghNSxIpBQUGtcnYbkP4em6TdtAj5K3yBjcKn4a -hnUoa5EJGr2Xgg0QascV/1GuWEJC9rsYYB9boVi95l1CrkS0pseaunM086iItZ4a -hRVza8qEMBc3rdsracA7hElYMKdFTRLpIGciJehXzv40yT5XFBHGy/HIT0CD50O7 -BDOHzA+rCFCvxX8UY9myDfb1r1zUW7Gzjn241VT7bcIJmhFE9oV0popzDyqr6GvP -qB2t5VmFpbnSwkuc4ie8Jizip1P8Hg73lut3oVAHACFGPpfaNIAp4GcSH61zJmff -9UBe3CJ1INwqyiuqGeA= ------END X509 CRL----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/expired.pem b/lib/mongoc/libmongoc/tests/x509gen/expired.pem deleted file mode 100644 index 2d92be01aa4c03a878a60546104ffdcbdb402d0c..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/expired.pem +++ /dev/null @@ -1,49 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAw06nN1BoINnY/WJXvi+r0taDMphWQNoyeM85A6NIYKo+vWtN -fvf6f2JTpg/Q4NJ3txiZE/F6yZaMFC78l1KMoz+zIEPLpSJoIezCaXyl2+AQih8A -WmAOFAoiWYTiNfWoVM7t0Qzy6yS+rXifuET5Dg1mtWpA6xRFHZEqQTdKX4QzbT5G -RenoFIBT9wG7xUV+FG1/9s5nx4f5gZDbwMKA7mNq/Jr+rZZQV4lReeGtoYNx1I/Z -4yd4xswI3RfuB7QDZMNHWZazFxW1N6EP5NJBDZJkYLEkMX36r4Orr/73z4EA5GBx -zqdSKH9qHLRiBwesfZf7u8xb120u1S1X1J8a5QIDAQABAoIBAQC+Y9swWerYM2WL -RKYCWZhndQP6e3SBzfMrv951hGQXD38Pyh2Gq5h/O0wN8xcNQz6+t3TqcxnekCrH -tjI4FZnRvlQRHOXVeeAHSjUO/hr1Z8zXyHbgowi2Ula/64FVVr+cxQgiJTxdK7nR -g2g4Csy6/SdlrEnSoDTsKMoHPy36Q0GaLDBnthpKIc1Prhntf6vBCgQAHXVfLk6E -NwddYloL+mfEZESa3Qf2ZYeX/Ovq9agbuQ3cRE7M5FunSo9E7eXt+D+Ntk0usTKV -BaUEHLRYXV827fMDGc1vBN6WFVfthhYviIEgDdkALwOw4lfIiA2WM3fhCF6Ow9hJ -as3dpEHBAoGBAO+l4PdUXypWBYQNZKggH79kAFuAOWtLsMqEBO0ZaXXdvFdwdzhR -jbL7mhRrghgGYpXWIUaNkcbX0XPlkWl2dRzYQqRNjUSEGFabVAxdGZPfiYoupXVl -Lz/FIG3P6BnEYmczh9MxRpJyk4wlUCKppYPiBrR0Ei/qcbGvciOwLq5VAoGBANCi -PWG2izO2HuBFgZTuVIvnl7ixQXgG/tvbiEmYvDNYy1E+w1MWY10Ve/JtIncBIVHk -fEgJPL3hvipAez5ir9Qa1D4PlWxsIrbjuNcLaj+IsRhWBDjMKwRWgmTvvsimcyF5 -39Vs4FujR8cgXy8UnZhYDVRC13PyxmYfJrp4QCpRAoGAKV8nsUsdir+DAEMXp3a0 -RGRNM361avKMOMoF17DVZgW7qBTAYDakEcwh03ij4uXnSxrGb9ms2vkTLcDqE5zh -pvMmvhqtUrDDSuBR6DiCW+bxZaub4OJw/79WU97aoOgoXMymnC0bk9i35C/k37cN -3fC9W5XWNfNxYU16lPKrfGkCgYA14hD0UY72Fg03YvwqmLshPvkCbFU6SKQ96B70 -0wuYP1CTdSBBL0EOY2QVonYKQjJ20gn/GNOlPs48X1b1L8u1fhBezuuKiwsULRAq -Cfqw2f7TCDQi7ygVALrAkuK1M7f8Z1uV5X60bCE3nna21B43oFYg8vpuKb9v1I/O -DQyVYQKBgQCH/Kxq+7Or/5ciq15Vy6z+PJdsGV9FV9S7zkQOZqJ4PXJn0wG9PXnp -ugjvmU1iLx0bXs5llByRx792Q/QmdWnwMCohs6bkWaBCf36JJfTkDTzzbez43cCK -HcYi6gtbiBznWiLWekudRkWdhIFEGU6cSjimy1i4yvwIw85PlEQt/Q== ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIDAYZJMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMDIyMzYzNVoXDTE5MDUyMTIyMzYzNVowcDES -MBAGA1UEAxMJbG9jYWxob3N0MRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdN -b25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9y -azELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDD -Tqc3UGgg2dj9Yle+L6vS1oMymFZA2jJ4zzkDo0hgqj69a01+9/p/YlOmD9Dg0ne3 -GJkT8XrJlowULvyXUoyjP7MgQ8ulImgh7MJpfKXb4BCKHwBaYA4UCiJZhOI19ahU -zu3RDPLrJL6teJ+4RPkODWa1akDrFEUdkSpBN0pfhDNtPkZF6egUgFP3AbvFRX4U -bX/2zmfHh/mBkNvAwoDuY2r8mv6tllBXiVF54a2hg3HUj9njJ3jGzAjdF+4HtANk -w0dZlrMXFbU3oQ/k0kENkmRgsSQxffqvg6uv/vfPgQDkYHHOp1Iof2octGIHB6x9 -l/u7zFvXbS7VLVfUnxrlAgMBAAGjMDAuMCwGA1UdEQQlMCOCCWxvY2FsaG9zdIcE -fwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAgPh9C6Yi -6ykJYfaOETPEkggI9LlLQyQ0VhSJGrcw8DXGuPEkyd2xtczYoh0ijtYD3nlTQnh1 -u+5mEEP05nuMMURzG+v7WzZG8Qfz/SDBY1Lfvb/waI3w3RT/dcZ6jwz39jQhV+rU -o2F1vr37Hnh1Ehoa2igjKL1w1LmWdoFgHb0p09qQDAGtkP0gxl0t7iujDDRStLQn -OpWwfOpCaYhtzWwONJn/JIG+JCE/szcRbmc4XKw8t06ffS0mKR/yZBCoekZinnPD -XRVWAH/UF5XPs0mUlrvhFcT/vjgXSZvpi+UuVv3XL56xwPmXAgKsYUpqLlgbrVxv -jY93LTJ1azg+Sw== ------END CERTIFICATE----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/legacy-ca.crt b/lib/mongoc/libmongoc/tests/x509gen/legacy-ca.crt deleted file mode 100644 index f739ef0627b773f7a4344b76dfc8803a546fdd53..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/legacy-ca.crt +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICnTCCAgYCCQD4+RCKzwZr/zANBgkqhkiG9w0BAQUFADCBkjELMAkGA1UEBhMC -VVMxETAPBgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MQ4w -DAYDVQQKDAUxMEdlbjEPMA0GA1UECwwGS2VybmVsMRowGAYDVQQDDBFNeSBDZXJ0 -IEF1dGhvcml0eTEbMBkGCSqGSIb3DQEJARYMcm9vdEBsYXphcnVzMB4XDTEzMTEz -MDAyMzU0OVoXDTIzMTEyODAyMzU0OVowgZIxCzAJBgNVBAYTAlVTMREwDwYDVQQI -DAhOZXcgWW9yazEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTEOMAwGA1UECgwFMTBH -ZW4xDzANBgNVBAsMBktlcm5lbDEaMBgGA1UEAwwRTXkgQ2VydCBBdXRob3JpdHkx -GzAZBgkqhkiG9w0BCQEWDHJvb3RAbGF6YXJ1czCBnzANBgkqhkiG9w0BAQEFAAOB -jQAwgYkCgYEA1xymeY+U/evUuQvxpun9moe4GopN80c1ptmaAHM/1Onwaq54Wt27 -nl1wUVme3dh4DdWviYY7mJ333HVEnp/QhVcT4kQhICZqdgPKPdCseQW3H+8x6Gwz -hrNRBdz0NkSoFxDlIymfy2Q2xoQpbCGAg+EnRYUTKlHMXNpUDLFhGjcCAwEAATAN -BgkqhkiG9w0BAQUFAAOBgQDRQB3c/9osTexEzMPHyMGTzG5nGwy8Wv77GgW3BETM -hECoGqueXLa5ZgvealJrnMHNKdj6vrCGgBDzE0K0VdXc4dLtLmx3DRntDOAWKJdB -2XPMvdC7Ec//Fwep/9emz0gDiJrTiEpL4p74+h+sp4Xy8cBokQ3Ss5S9NmnPXT7E -qQ== ------END CERTIFICATE----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/legacy-x509.pem b/lib/mongoc/libmongoc/tests/x509gen/legacy-x509.pem deleted file mode 100644 index 85ace4fd40b500c2b427eecd9894d7f64ae548bd..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/legacy-x509.pem +++ /dev/null @@ -1,101 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 7 (0x7) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, ST=New York, L=New York City, O=10Gen, OU=Kernel, CN=My Cert Authority/emailAddress=root@lazarus - Validity - Not Before: Aug 23 14:55:32 2013 GMT - Not After : Jan 7 14:55:32 2041 GMT - Subject: C=US, ST=New York, L=New York City, O=10Gen, OU=kerneluser, CN=client - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:ba:16:42:d4:8b:3d:5e:8a:67:9e:a7:c0:cd:4a: - 9c:9c:fd:95:b9:83:bf:f4:cf:03:8c:2e:db:a9:c1: - 35:58:80:f6:e2:e9:87:28:84:e3:d0:9b:68:60:51: - 0e:42:84:d8:6f:e8:34:cc:18:97:79:d3:8d:d8:2f: - 23:11:25:6f:69:7a:38:bb:8c:b2:29:e9:91:be:79: - 8c:cc:1b:56:98:98:d3:83:2a:c5:f9:9c:86:0c:2c: - 24:0e:5c:46:3b:a9:95:44:6c:c5:e0:7c:9d:03:ae: - 0d:23:99:49:a4:48:dd:0e:35:a2:e5:b4:8b:86:bd: - c0:c8:ce:d5:ac:c4:36:f3:9e:5f:17:00:23:8d:53: - a1:43:1b:a3:61:96:36:80:4d:35:50:b5:8b:69:31: - 39:b4:63:8b:96:59:5c:d1:ea:92:eb:eb:fa:1b:35: - 64:44:b3:f6:f3:a6:9d:49:3a:59:e5:e1:c2:cb:98: - be:29:b3:22:dd:33:97:d7:50:4f:db:c2:58:64:18: - b5:8c:3c:6b:2d:21:f6:bd:8d:e5:d2:da:8d:79:fe: - a7:80:75:a8:15:b9:ee:79:7f:01:31:1d:e5:e7:15: - 76:53:65:f6:fe:f0:93:7d:20:3d:cc:ff:9b:ca:b2: - 50:2c:1b:3a:69:d5:e6:70:cf:ac:be:7e:5c:33:c4: - 6e:a7 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - Netscape Comment: - OpenSSL Generated Certificate - X509v3 Subject Key Identifier: - 4A:8B:EE:22:42:E6:F8:62:4C:86:38:8D:C5:78:95:98:C1:10:05:7C - X509v3 Authority Key Identifier: - keyid:07:41:19:3A:9F:7E:C5:B7:22:4E:B7:BC:D5:DF:E4:FC:09:B8:64:16 - - Signature Algorithm: sha1WithRSAEncryption - 13:13:a8:f0:de:78:c6:b1:e0:85:cc:27:e6:04:28:44:93:1d: - f1:ff:5e:81:69:33:1f:f3:76:e0:49:ca:d9:ad:aa:db:f5:a5: - f8:a6:50:bb:a1:a7:40:14:e4:2f:8d:b8:21:7f:35:04:60:db: - af:f0:9e:dd:a1:ca:0b:7f:03:2e:2f:19:1e:32:6e:1e:2d:87: - 68:e3:37:47:a8:5b:93:d1:88:41:73:da:88:21:59:27:d4:35: - 1c:6a:27:b5:c0:c6:17:ba:f3:87:c8:e1:f4:8f:43:12:bc:fa: - 8d:90:d5:86:83:df:51:a5:c9:e0:92:f0:66:d0:37:61:6f:85: - 24:18 ------BEGIN CERTIFICATE----- -MIIDdjCCAt+gAwIBAgIBBzANBgkqhkiG9w0BAQUFADCBkjELMAkGA1UEBhMCVVMx -ETAPBgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MQ4wDAYD -VQQKDAUxMEdlbjEPMA0GA1UECwwGS2VybmVsMRowGAYDVQQDDBFNeSBDZXJ0IEF1 -dGhvcml0eTEbMBkGCSqGSIb3DQEJARYMcm9vdEBsYXphcnVzMB4XDTEzMDgyMzE0 -NTUzMloXDTQxMDEwNzE0NTUzMlowbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5l -dyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MQ4wDAYDVQQKDAUxMEdlbjET -MBEGA1UECwwKa2VybmVsdXNlcjEPMA0GA1UEAwwGY2xpZW50MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuhZC1Is9XopnnqfAzUqcnP2VuYO/9M8DjC7b -qcE1WID24umHKITj0JtoYFEOQoTYb+g0zBiXedON2C8jESVvaXo4u4yyKemRvnmM -zBtWmJjTgyrF+ZyGDCwkDlxGO6mVRGzF4HydA64NI5lJpEjdDjWi5bSLhr3AyM7V -rMQ2855fFwAjjVOhQxujYZY2gE01ULWLaTE5tGOLlllc0eqS6+v6GzVkRLP286ad -STpZ5eHCy5i+KbMi3TOX11BP28JYZBi1jDxrLSH2vY3l0tqNef6ngHWoFbnueX8B -MR3l5xV2U2X2/vCTfSA9zP+byrJQLBs6adXmcM+svn5cM8RupwIDAQABo3sweTAJ -BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0 -aWZpY2F0ZTAdBgNVHQ4EFgQUSovuIkLm+GJMhjiNxXiVmMEQBXwwHwYDVR0jBBgw -FoAUB0EZOp9+xbciTre81d/k/Am4ZBYwDQYJKoZIhvcNAQEFBQADgYEAExOo8N54 -xrHghcwn5gQoRJMd8f9egWkzH/N24EnK2a2q2/Wl+KZQu6GnQBTkL424IX81BGDb -r/Ce3aHKC38DLi8ZHjJuHi2HaOM3R6hbk9GIQXPaiCFZJ9Q1HGontcDGF7rzh8jh -9I9DErz6jZDVhoPfUaXJ4JLwZtA3YW+FJBg= ------END CERTIFICATE----- ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6FkLUiz1eimee -p8DNSpyc/ZW5g7/0zwOMLtupwTVYgPbi6YcohOPQm2hgUQ5ChNhv6DTMGJd5043Y -LyMRJW9peji7jLIp6ZG+eYzMG1aYmNODKsX5nIYMLCQOXEY7qZVEbMXgfJ0Drg0j -mUmkSN0ONaLltIuGvcDIztWsxDbznl8XACONU6FDG6NhljaATTVQtYtpMTm0Y4uW -WVzR6pLr6/obNWREs/bzpp1JOlnl4cLLmL4psyLdM5fXUE/bwlhkGLWMPGstIfa9 -jeXS2o15/qeAdagVue55fwExHeXnFXZTZfb+8JN9ID3M/5vKslAsGzpp1eZwz6y+ -flwzxG6nAgMBAAECggEBALYw92urjAFVFxCiA8W7aEzYhtAkaztft4R3mD/C19z4 -H0CZDeig+3+RuIactY5xDIu8WHz/EseHVlg0BmxSL5ugu4z8uq8IbNaFoVFw7r7m -2ieRKFY0ZpXiXcbllynw5iEhMjeRKhWhQmH5Qb2kTTINV5j4xKa+f9Lblx7Y2Uh4 -tsaOtlMwb98D2/KYJdTv5Nj1nyuSqRVhECsd00Cb6JUBGQBx8Ja0wFy9gEygq6kU -w3s1XNOSnYNEo4FaVZwp5KZyCyBENcKpNUq4nXt/7ncEfVYdJck0Li3wN4Jr2J9S -eHqRzh8QkHxc1Ro8ktcXaUSs9kFuwvVvb4rcGUpOMWkCgYEA9xxp8yDtFVgzMtc/ -vS8xgM1Wj4SrgKKYhE2wS05BJh/41oFMzfH1FpZ1GCM983r4QgYWoT71XsBgiOMC -yN2p2IbV4V44bMGKJqaVMkB91CVCUWI6piaCQb/1CJTwaXE7zPim6dlUSxxBBnRn -LP50NTscRLFcCZELD3Yl7jR8XFUCgYEAwMfkNFmGtBKAwlHZ3Y3XOwPWg+jCll7s -9nhv8TU2IB9pcCRGqyOT7k1YymvYkDT2Je4JUPWEBs4cW7yD61LrQ8w8+DrE9dGo -czzGPyjOAANSX0asG74UjkNIQThmyEOltVHIxYMaSqowjHRSPdA+R4Od9EdcDdfS -q5SfSVFxmwsCgYBtl1thqUOcCL7EGHQ7KdfxgJ+YDMWmyfWMD4xVCYKZLurD7xop -59nDR7zslIygE/RQC7Uzk+FsQTNO4ibVAIGX9syaI5gwm3DyjURzwehMEq4ju8W4 -9DEmicRZJvysNrzHvasA4RKiMQihnTQ43yyYgvuZd3MTBxF5rPNLfll89QKBgQC9 -SsmiOZIR+OUjaTmS2bbQBNm7Fm8TNcxZyzKn1wb5jb57VbNqUfnskVgxEqpIFyjn -X48YRqtH/1RLI5UpGXdXUBFB8Hr7oM1VsgQ7ejakPp7AXOWcLA2FDz3AhMAvvnTU -0KRihHPpgqk/EOy8M2Ej2XHcrcEO+q+quLmbRXRWtwKBgHacQiwci/2J+v0e9i52 -re/2AJHKP5MwNHFe1e01iNc5EEN0G+/Ut8XW19DWf6bsxqie0ChC+xN8TUst8alT -F+tXTsHHmt/lRcjTROjT5XVuoqjtU2Q0QeVeGLgvObso+fZy3ZNeQuSJjWukdMZ3 -57rGT6p0OuM8qbrTzpv3JMrm ------END PRIVATE KEY----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/password_protected.pem b/lib/mongoc/libmongoc/tests/x509gen/password_protected.pem deleted file mode 100644 index cc9e124703503deccbc163d60b349eac560b7aa5..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/password_protected.pem +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIC8as6PDVhwECAggA -MB0GCWCGSAFlAwQBAgQQTYOgCJcRqUI7dsgqNojv/ASCBNCG9fiu642V4AuFK34c -Q42lvy/cR0CIXLq/rDXN1L685kdeKex7AfDuRtnjY2+7CLJiJimgQNJXDJPHab/k -MBHbwbBs38fg6eSYX8V08/IyyTege5EJMhYxmieHDC3DXKt0gyHk6hA/r5+Mr49h -HeVGwqBLJEQ3gVIeHaOleZYspsXXWqOPHnFiqnk/biaJS0+LkDDEiQgTLEYSnOjP -lexxUc4BV/TN0Z920tZCMfwx7IXD/C+0AkV/Iqq4LALmT702EccB3indaIJ8biGR -radqDLR32Q+vT9uZHgT8EFiUsISMqhob2mnyTfFV/s9ghWwogjSz0HrRcq6fxdg7 -oeyT9K0ET53AGTGmV0206byPu6qCj1eNvtn+t1Ob+d5hecaTugRMVheWPlc5frsz -AcewDNa0pv4pZItjAGMqOPJHfzEDnzTJXpLqGYhg044H1+OCY8+1YK7U0u8dO+/3 -f5AoDMq18ipDVTFTooJURej4/Wjbrfad3ZFjp86nxfHPeWM1YjC9+IlLtK1wr0/U -V8TjGqCkw8yHayz01A86iA8X53YQBg+tyMGjxmivo6LgFGKa9mXGvDkN+B+0+OcA -PqldAuH/TJhnkqzja767e4n9kcr+TmV19Hn1hcJPTDrRU8+sSqQFsWN4pvHazAYB -UdWie+EXI0eU2Av9JFgrVcpRipXjB48BaPwuBw8hm+VStCH7ynF4lJy6/3esjYwk -Mx+NUf8+pp1DRzpzuJa2vAutzqia5r58+zloQMxkgTZtJkQU6OCRoUhHGVk7WNb1 -nxsibOSzyVSP9ZNbHIHAn43vICFGrPubRs200Kc4CdXsOSEWoP0XYebhiNJgGtQs -KoISsV4dFRLwhaJhIlayTBQz6w6Ph87WbtuiAqoLiuqdXhUGz/79j/6JZqCH8t/H -eZs4Dhu+HdD/wZKJDYAS+JBsiwYWnI3y/EowZYgLdOMI4u6xYDejhxwEw20LW445 -qjJ7pV/iX2uavazHgC91Bfd4zodfXIQ1IDyTmb51UFwx0ARzG6enntduO6xtcYU9 -MXwfrEpuZ/MkWTLkR0PHPbIPcR1MiVwPKdvrLk42Bzj/urtXYrAFUckMFMzEh+uv -0lix2hbq/Xwj4dXcY4w9hnC6QQDCJTf9S6MU6OisrZHKk0qZ2Vb4aU/eBcBsHBwo -X/QGcDHneHxlrrs2eLX26Vh8Odc5h8haeIxnfaa1t+Yv56OKHuAztPMnJOUL7KtQ -A556LxT0b5IGx0RcfUcbG8XbxEHseACptoDOoguh9923IBI0uXmpi8q0P815LPUu -0AsE47ATDMGPnXbopejRDicfgMGjykJn8vKO8r/Ia3Fpnomx4iJNCXGqomL+GMpZ -IhQbKNrRG6XZMlx5kVCT0Qr1nOWMiOTSDCQ5vrG3c1Viu+0bctvidEvs+LCm98tb -7ty8F0uOno0rYGNQz18OEE1Tj+E19Vauz1U35Z5SsgJJ/GfzhSJ79Srmdg2PsAzk -AUNTKXux1GLf1cMjTiiU5g+tCEtUL9Me7lsv3L6aFdrCyRbhXUQfJh4NAG8+3Pvh -EaprThBzKsVvbOfU81mOaH9YMmUgmxG86vxDiNtaWd4v6c1k+HGspJr/q49pcXZP -ltBMuS9AihstZ1sHJsyQCmNXkA== ------END ENCRYPTED PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDgzCCAmugAwIBAgIDBXUHMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMzAwMDEyOVoXDTM5MDUyMzAwMDEyOVowaTEP -MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx -FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD -VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOqCb0Lo4XsV -W327Wlnqc5rwWa5Elw0rFuehSfViRIcYfuFWAPXoOj3fIDsYz6d41G8hp6tkF88p -swlbzDF8Fc7mXDhauwwl2F/NrWYUXwCT8fKju4DtGd2JlDMi1TRDeofkYCGVPp70 -vNqd0H8iDWWs8OmiNrdBLJwNiGaf9y15ena4ImQGitXLFn+qNSXYJ1Rs8p7Y2PTr -L+dff5gJCVbANwGII1rjMAsrMACPVmr8c1Lxoq4fSdJiLweosrv2Lk0WWGsO0Seg -ZY71dNHEyNjItE+VtFEtslJ5L261i3BfF/FqNnH2UmKXzShwfwxyHT8o84gSAltQ -5/lVJ4QQKosCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF -BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBOAlKxIMFcTZ+4k8NJv97RSf+zOb5Wu2ct -uxSZxzgKTxLFUuEM8XQiEz1iHQ3XG+uV1fzA74YLQiKjjLrU0mx54eM1vaRtOXvF -sJlzZU8Z2+523FVPx4HBPyObQrfXmIoAiHoQ4VUeepkPRpXxpifgWd/OCWhLDr2/ -0Kgcb0ybaGVDpA0UD9uVIwgFjRu6id7wG+lVcdRxJYskTOOaN2o1hMdAKkrpFQbd -zNRfEoBPUYR3QAmAKP2HBjpgp4ktOHoOKMlfeAuuMCUocSnmPKc3xJaH/6O7rHcf -/Rm0X411RH8JfoXYsSiPsd601kZefhuWvJH0sJLibRDvT7zs8C1v ------END CERTIFICATE----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/server.pem b/lib/mongoc/libmongoc/tests/x509gen/server.pem deleted file mode 100644 index 7480f9644763eff444e0490bf78bdc342213c7b8..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/server.pem +++ /dev/null @@ -1,49 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAhNrB0E6GY/kFSd8/vNpu/t952tbnOsD5drV0XPvmuy7SgKDY -a/S+xb/jPnlZKKehdBnH7qP/gYbv34ZykzcDFZscjPLiGc2cRGP+NQCSFK0d2/7d -y15zSD3zhj14G8+MkpAejTU+0/qFNZMc5neDvGanTe0+8aWa0DXssM0MuTxIv7j6 -CtsMWeqLLofN7a1Kw2UvmieCHfHMuA/08pJwRnV/+5T9WONBPJja2ZQRrG1BjpI4 -81zSPUZesIqi8yDlExdvgNaRZIEHi/njREqwVgJOZomUY57zmKypiMzbz48dDTsV -gUStxrEqbaP+BEjQYPX5+QQk4GdMjkLf52LR6QIDAQABAoIBAHSs+hHLJNOf2zkp -S3y8CUblVMsQeTpsR6otaehPgi9Zy50TpX4KD5D0GMrBH8BIl86y5Zd7h+VlcDzK -gs0vPxI2izhuBovKuzaE6rf5rFFkSBjxGDCG3o/PeJOoYFdsS3RcBbjVzju0hFCs -xnDQ/Wz0anJRrTnjyraY5SnQqx/xuhLXkj/lwWoWjP2bUqDprnuLOj16soNu60Um -JziWbmWx9ty0wohkI/8DPBl9FjSniEEUi9pnZXPElFN6kwPkgdfT5rY/TkMH4lsu -ozOUc5xgwlkT6kVjXHcs3fleuT/mOfVXLPgNms85JKLucfd6KiV7jYZkT/bXIjQ+ -7CZEn0ECgYEA5QiKZgsfJjWvZpt21V/i7dPje2xdwHtZ8F9NjX7ZUFA7mUPxUlwe -GiXxmy6RGzNdnLOto4SF0/7ebuF3koO77oLup5a2etL+y/AnNAufbu4S5D72sbiz -wdLzr3d5JQ12xeaEH6kQNk2SD5/ShctdS6GmTgQPiJIgH0MIdi9F3v0CgYEAlH84 -hMWcC+5b4hHUEexeNkT8kCXwHVcUjGRaYFdSHgovvWllApZDHSWZ+vRcMBdlhNPu -09Btxo99cjOZwGYJyt20QQLGc/ZyiOF4ximQzabTeFgLkTH3Ox6Mh2Rx9yIruYoX -nE3UfMDkYELanEJUv0zenKpZHw7tTt5yXXSlEF0CgYBSsEOvVcKYO/eoluZPYQAA -F2jgzZ4HeUFebDoGpM52lZD+463Dq2hezmYtPaG77U6V3bUJ/TWH9VN/Or290vvN -v83ECcC2FWlSXdD5lFyqYx/E8gqE3YdgqfW62uqM+xBvoKsA9zvYLydVpsEN9v8m -6CSvs/2btA4O21e5u5WBTQKBgGtAb6vFpe0gHRDs24SOeYUs0lWycPhf+qFjobrP -lqnHpa9iPeheat7UV6BfeW3qmBIVl/s4IPE2ld4z0qqZiB0Tf6ssu/TpXNPsNXS6 -dLFz+myC+ufFdNEoQUtQitd5wKbjTCZCOGRaVRgJcSdG6Tq55Fa22mOKPm+mTmed -ZdKpAoGAFsTYBAHPxs8nzkCJCl7KLa4/zgbgywO6EcQgA7tfelB8bc8vcAMG5o+8 -YqAfwxrzhVSVbJx0fibTARXROmbh2pn010l2wj3+qUajM8NiskCPFbSjGy7HSUze -P8Kt1uMDJdj55gATzn44au31QBioZY2zXleorxF21cr+BZCJgfA= ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDlTCCAn2gAwIBAgICdxUwDQYJKoZIhvcNAQELBQAweTEbMBkGA1UEAxMSRHJp -dmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdNb25n -b0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazEL -MAkGA1UEBhMCVVMwHhcNMTkwNTIyMjIzMjU2WhcNMzkwNTIyMjIzMjU2WjBwMRIw -EAYDVQQDEwlsb2NhbGhvc3QxEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01v -bmdvREIxFjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3Jr -MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAITa -wdBOhmP5BUnfP7zabv7fedrW5zrA+Xa1dFz75rsu0oCg2Gv0vsW/4z55WSinoXQZ -x+6j/4GG79+GcpM3AxWbHIzy4hnNnERj/jUAkhStHdv+3ctec0g984Y9eBvPjJKQ -Ho01PtP6hTWTHOZ3g7xmp03tPvGlmtA17LDNDLk8SL+4+grbDFnqiy6Hze2tSsNl -L5ongh3xzLgP9PKScEZ1f/uU/VjjQTyY2tmUEaxtQY6SOPNc0j1GXrCKovMg5RMX -b4DWkWSBB4v540RKsFYCTmaJlGOe85isqYjM28+PHQ07FYFErcaxKm2j/gRI0GD1 -+fkEJOBnTI5C3+di0ekCAwEAAaMwMC4wLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/ -AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4IBAQBol8+YH7MA -HwnIh7KcJ8h87GkCWsjOJCDJWiYBJArQ0MmgDO0qdx+QEtvLMn3XNtP05ZfK0WyX -or4cWllAkMFYaFbyB2hYazlD1UAAG+22Rku0UP6pJMLbWe6pnqzx+RL68FYdbZhN -fCW2xiiKsdPoo2VEY7eeZKrNr/0RFE5EKXgzmobpTBQT1Dl3Ve4aWLoTy9INlQ/g -z40qS7oq1PjjPLgxINhf4ncJqfmRXugYTOnyFiVXLZTys5Pb9SMKdToGl3NTYWLL -2AZdjr6bKtT+WtXyHqO0cQ8CkAW0M6VOlMluACllcJxfrtdlQS2S4lUIj76QKBdZ -khBHXq/b8MFX ------END CERTIFICATE----- diff --git a/lib/mongoc/libmongoc/tests/x509gen/wild.pem b/lib/mongoc/libmongoc/tests/x509gen/wild.pem deleted file mode 100644 index d418007486b4bac4f3b22d0e1a39bdffbfbd0015..0000000000000000000000000000000000000000 --- a/lib/mongoc/libmongoc/tests/x509gen/wild.pem +++ /dev/null @@ -1,49 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAlenyliMpkLM9aR51iOO7hdLS66pwgafsJlIbtsKAy6WxlcKA -yecs0yCQfw5z5j3BFgv88dzAFEF+jFG6o/EmAzqmK5uRCQX1EJbl2p8detbzToj9 -Ys1Z1peWE8FkJtZMKUdLdlRQQ57v2VUr0kwtFEUGlSNyVwf4pJ5coyqpukmoUdko -zrKeclshjydDVo44Ln6WYvN6odz/CZT808fHZ0CXcIEKyDV8zXIcHGX2OUL/ajtZ -+C2pIbAx64nin1BLtHGvDT0Pan1xKDiMCkOdc7va0gLh0qtPjGLsI4vc8iByviGJ -Kw7hVaj7ym0r2DFzeqghfvNNNHisGXSf+6EcPQIDAQABAoIBAGq/PVefDhfVKaNS -ZwrkbkDqT/ozUQ1hzwuyZ72JXkCkaYFkEGS0Ufy8MWfnmKuXyYezXZezQqqpwDyW -bboTGqgt+OkQSwQL0+bOLDmyF0HDEVkYvqS96HyfT+QdTv1AltbFx3woqUadQ9iT -hzKlv2uxgvBrXx2NtYUypnAhDt5wQQ4n1w46Kl1USb983qWDWyFtHfIQo6vF1JK/ -s6I6oA2tmORPTD3A7E2xT98UMM8B1c/v1F+owAiD+KNmgAN4oWSWBfRGEKg59fZA -aGWjQrwoWmQQJnMnTsHZc+2hT7waKnyOwOFq1NPXyfCw+4cSeI3B3rPxPyShBM4O -ZKfajIECgYEAz555nPHhk5GmMpXprryCODy66ChHWulA3fM9r0k/ObBgKqTirAOA -y0PmA8OxR8acV0V2lZImdwF5Lvnj+c8+fTFSnPKSQHpcZ/lbxo+m2rYwv7+BxUP9 -GJAWzA6xqBde6hNPULml8cNOqT7jwRnLt/DkwY+94Oeh3H5CRYb90Y0CgYEAuNkR -EieGwCn+TjgatkhMLhYqr234544p3ofL82CFlCcsOXtWqCma6POOi038eBlZiHV9 -EPBq4qQHCZMAPeApTZbiZ+Z8ezC3IxjGSX0jP5QK+gBrkk7nbp24nRMlHOrwizsL -/Sxu4Y6puZk5aTUZVufPLXokY6Iez0Kd07vyUXECgYBqWHFQi7EQ5nzr0lAVOee1 -qJ3QRrlt/qZESdCh1XH2Obq4fSbCFzVEaK4L5ZQMANaZ+TGpoWfkczPAdS1qCtam -R7paPAHf1w04EMkKpxA/XS0ROqXdBltA1qVmtmwXfokWeveYkM9IS9Mh6927TlxE -BrcV0mvfJKaLC30koeWnDQKBgEn1oBzxb7sHklbdn+J7Pu/Zsq6Kg+KyQRJmpzXz -0r6ahdlh/iQ+sVqvyML4KyIqkmZFDAtxBnM0ShSMmrYnMJ941ZHY6Mmpjj0etofE -6AuSQmoRLPlXVMYvmSRP+rN9VU2ADKX510usd0BpjE0KD99z1LNPgavTvBwVfWyw -cJ4hAoGBALgyVPMBPv1d8irbM1WHFe/I3vxjb4DWOY9xclbRWjkW69oZmkouGP07 -52ehzfBtBC87VPLwTEr/ERZqfICBqZvXYFypd2ydGhbDKjDswiUd6nACNKAx5ZPo -OVwQjVfjGqkKNThoHhvE1YU//+WtCe0YVUGqMA9dyZe1QO3HcqI8 ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIDCRU4MA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIyMzgxOVoXDTM5MDUyMjIyMzgxOVowcDES -MBAGA1UEAxMJbG9jYWxob3N0MRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdN -b25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9y -azELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV -6fKWIymQsz1pHnWI47uF0tLrqnCBp+wmUhu2woDLpbGVwoDJ5yzTIJB/DnPmPcEW -C/zx3MAUQX6MUbqj8SYDOqYrm5EJBfUQluXanx161vNOiP1izVnWl5YTwWQm1kwp -R0t2VFBDnu/ZVSvSTC0URQaVI3JXB/iknlyjKqm6SahR2SjOsp5yWyGPJ0NWjjgu -fpZi83qh3P8JlPzTx8dnQJdwgQrINXzNchwcZfY5Qv9qO1n4LakhsDHrieKfUEu0 -ca8NPQ9qfXEoOIwKQ51zu9rSAuHSq0+MYuwji9zyIHK+IYkrDuFVqPvKbSvYMXN6 -qCF+8000eKwZdJ/7oRw9AgMBAAGjLTArMCkGA1UdEQQiMCCCCWxvY2FsaG9zdIcE -fwAAAYINKi5tb25nb2RiLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAMCENVK+w+wP7 -T1XBytsScn7+Bh33sn+A+c7H/6BNOEdTxCQ67L3zBc0XrBFYtiHcAppNBKvvM8cV -ERWjXlU2nZ+A0WKOZE2nXYQL5lBnnXoIMwcdtJuTJuWw8r3MlVXDcP6bK8tNSQMG -WYK7PHQ3RNiWNABZejJV9GVP25nO6Wr2gt2xnEwYvUXTnCJtT+NsTE/fU4MlGuUL -a93Cec86Ij0XTMTcnj4nfZhct30nuqiU4wWBPHCN7BXxRQzIHu68aVHBpwDEAf6j -PAOKhucGY6DW+dyrW/1BjW6+ZOmJWxJ7GB+x0gjprQbGH67gIvRvTa9wW7NqWyS3 -Go/qT7H6FQ== ------END CERTIFICATE----- diff --git a/libdap-chain-net b/libdap-chain-net index b92ccafc47577e91f55073edf8b2eae1e94fc83c..091c44fdf2926f7d92f96f080db80be9a2b0eb5a 160000 --- a/libdap-chain-net +++ b/libdap-chain-net @@ -1 +1 @@ -Subproject commit b92ccafc47577e91f55073edf8b2eae1e94fc83c +Subproject commit 091c44fdf2926f7d92f96f080db80be9a2b0eb5a