...

Text file src/go.mongodb.org/mongo-driver/testdata/sessions/README.rst

Documentation: go.mongodb.org/mongo-driver/testdata/sessions

     1====================
     2Driver Session Tests
     3====================
     4
     5.. contents::
     6
     7----
     8
     9Introduction
    10============
    11
    12The YAML and JSON files in this directory are platform-independent tests
    13meant to exercise a driver's implementation of sessions. These tests utilize the
    14`Unified Test Format <../../unified-test-format/unified-test-format.rst>`__.
    15
    16Several prose tests, which are not easily expressed in YAML, are also presented
    17in the Driver Sessions Spec. Those tests will need to be manually implemented
    18by each driver.
    19
    20Snapshot session tests
    21======================
    22Snapshot sessions tests require server of version 5.0 or higher and
    23replica set or a sharded cluster deployment.
    24Default snapshot history window on the server is 5 minutes. Running the test in debug mode, or in any other slow configuration
    25may lead to `SnapshotTooOld` errors. Drivers can work around this issue by increasing the server's `minSnapshotHistoryWindowInSeconds` parameter, for example:
    26
    27.. code:: python
    28
    29    client.admin.command('setParameter', 1, minSnapshotHistoryWindowInSeconds=60)
    30
    31Prose tests
    32```````````
    33
    341. Setting both ``snapshot`` and ``causalConsistency`` to true is not allowed
    35~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    36
    37* ``client.startSession(snapshot = true, causalConsistency = true)``
    38* Assert that an error was raised by driver
    39
    402. Pool is LIFO
    41~~~~~~~~~~~~~~~
    42
    43This test applies to drivers with session pools.
    44
    45* Call ``MongoClient.startSession`` twice to create two sessions, let us call them ``A`` and ``B``.
    46* Call ``A.endSession``, then ``B.endSession``.
    47* Call ``MongoClient.startSession``: the resulting session must have the same session ID as ``B``.
    48* Call ``MongoClient.startSession`` again: the resulting session must have the same session ID  as ``A``.
    49
    503. ``$clusterTime`` in commands
    51~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    52
    53* Turn ``heartbeatFrequencyMS`` up to a very large number.
    54* Register a command-started and a command-succeeded APM listener. If the driver has no APM support, inspect commands/replies in another idiomatic way, such as monkey-patching or a mock server.
    55* Send a ``ping`` command to the server with the generic ``runCommand`` method.
    56* Assert that the command passed to the command-started listener includes ``$clusterTime`` if and only if ``maxWireVersion`` >= 6.
    57* Record the ``$clusterTime``, if any, in the reply passed to the command-succeeded APM listener.
    58* Send another ``ping`` command.
    59* Assert that ``$clusterTime`` in the command passed to the command-started listener, if any, equals the ``$clusterTime`` in the previous server reply. (Turning ``heartbeatFrequencyMS`` up prevents an intervening heartbeat from advancing the ``$clusterTime`` between these final two steps.)
    60
    61Repeat the above for:
    62
    63* An aggregate command from the ``aggregate`` helper method
    64* A find command from the ``find`` helper method
    65* An insert command from the ``insert_one`` helper method
    66
    674. Explicit and implicit session arguments
    68~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    69
    70* Register a command-started APM listener. If the driver has no APM support, inspect commands in another idiomatic way, such as monkey-patching or a mock server.
    71* Create ``client1``
    72* Get ``database`` from ``client1``
    73* Get ``collection`` from ``database``
    74* Start ``session`` from ``client1``
    75* Call ``collection.insertOne(session,...)``
    76* Assert that the command passed to the command-started listener contained the session ``lsid`` from ``session``.
    77* Call ``collection.insertOne(,...)`` (*without* a session argument)
    78* Assert that the command passed to the command-started listener contained a session ``lsid``.
    79
    80Repeat the above for all methods that take a session parameter.
    81
    825. Session argument is for the right client
    83~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    84
    85* Create ``client1`` and ``client2``
    86* Get ``database`` from ``client1``
    87* Get ``collection`` from ``database``
    88* Start ``session`` from ``client2``
    89* Call ``collection.insertOne(session,...)``
    90* Assert that an error was reported because ``session`` was not started from ``client1``
    91
    92Repeat the above for all methods that take a session parameter.
    93
    946. No further operations can be performed using a session after ``endSession`` has been called
    95~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    96
    97* Start a ``session``
    98* End the ``session``
    99* Call ``collection.InsertOne(session, ...)``
   100* Assert that the proper error was reported
   101
   102Repeat the above for all methods that take a session parameter.
   103
   104If your driver implements a platform dependent idiomatic disposal pattern, test
   105that also (if the idiomatic disposal pattern calls ``endSession`` it would be
   106sufficient to only test the disposal pattern since that ends up calling
   107``endSession``).
   108
   1097. Authenticating as multiple users suppresses implicit sessions
   110~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   111
   112Skip this test if your driver does not allow simultaneous authentication with multiple users.
   113
   114* Authenticate as two users
   115* Call ``findOne`` with no explicit session
   116* Capture the command sent to the server
   117* Assert that the command sent to the server does not have an ``lsid`` field
   118
   1198. Client-side cursor that exhausts the results on the initial query immediately returns the implicit session to the pool
   120~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   121
   122* Insert two documents into a collection
   123* Execute a find operation on the collection and iterate past the first document
   124* Assert that the implicit session is returned to the pool. This can be done in several ways:
   125
   126  * Track in-use count in the server session pool and assert that the count has dropped to zero
   127  * Track the lsid used for the find operation (e.g. with APM) and then do another operation and
   128    assert that the same lsid is used as for the find operation.
   129
   1309. Client-side cursor that exhausts the results after a ``getMore`` immediately returns the implicit session to the pool
   131~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   132
   133* Insert five documents into a collection
   134* Execute a find operation on the collection with batch size of 3
   135* Iterate past the first four documents, forcing the final ``getMore`` operation
   136* Assert that the implicit session is returned to the pool prior to iterating past the last document
   137
   13810. No remaining sessions are checked out after each functional test
   139~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   140
   141At the end of every individual functional test of the driver, there SHOULD be an
   142assertion that there are no remaining sessions checked out from the pool. This
   143may require changes to existing tests to ensure that they close any explicit
   144client sessions and any unexhausted cursors.
   145
   14611. For every combination of topology and readPreference, ensure that ``find`` and ``getMore`` both send the same session id
   147~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   148
   149* Insert three documents into a collection
   150* Execute a ``find`` operation on the collection with a batch size of 2
   151* Assert that the server receives a non-zero lsid
   152* Iterate through enough documents (3) to force a ``getMore``
   153* Assert that the server receives a non-zero lsid equal to the lsid that ``find`` sent.
   154
   15512. Session pool can be cleared after forking without calling ``endSession``
   156~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   157
   158Skip this test if your driver does not allow forking.
   159
   160* Create ClientSession
   161* Record its lsid
   162* Delete it (so the lsid is pushed into the pool)
   163* Fork
   164* In the parent, create a ClientSession and assert its lsid is the same.
   165* In the child, create a ClientSession and assert its lsid is different.
   166
   16713. Existing sessions are not checked into a cleared pool after forking
   168~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   169
   170Skip this test if your driver does not allow forking.
   171
   172* Create ClientSession
   173* Record its lsid
   174* Fork
   175* In the parent, return the ClientSession to the pool, create a new ClientSession, and assert its lsid is the same.
   176* In the child, return the ClientSession to the pool, create a new ClientSession, and assert its lsid is different.
   177
   17814. Implicit sessions only allocate their server session after a successful connection checkout
   179~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   180
   181* Create a MongoClient with the following options: ``maxPoolSize=1`` and ``retryWrites=true``. If testing against a sharded deployment, the test runner MUST ensure that the MongoClient connects to only a single mongos host.
   182* Attach a command started listener that collects each command's lsid
   183* Initiate the following concurrent operations
   184
   185  * ``insertOne({ }),``
   186  * ``deleteOne({ }),``
   187  * ``updateOne({ }, { $set: { a: 1 } }),``
   188  * ``bulkWrite([{ updateOne: { filter: { }, update: { $set: { a: 1 } } } }]),``
   189  * ``findOneAndDelete({ }),``
   190  * ``findOneAndUpdate({ }, { $set: { a: 1 } }),``
   191  * ``findOneAndReplace({ }, { a: 1 }),``
   192  * ``find().toArray()``
   193
   194* Wait for all operations to complete successfully
   195* Assert the following across at least 5 retries of the above test:
   196
   197  * Drivers MUST assert that exactly one session is used for all operations at
   198    least once across the retries of this test.
   199  * Note that it's possible, although rare, for >1 server session to be used
   200    because the session is not released until after the connection is checked in.
   201  * Drivers MUST assert that the number of allocated sessions is strictly less
   202    than the number of concurrent operations in every retry of this test. In
   203    this instance it would be less than (but NOT equal to) 8.
   204
   20515. ``lsid`` is added inside ``$query`` when using OP_QUERY
   206~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   207
   208This test only applies to drivers that have not implemented OP_MSG and still use OP_QUERY.
   209
   210* For a command to a mongos that includes a readPreference, verify that the
   211  ``lsid`` on query commands is added inside the ``$query`` field, and NOT as a
   212  top-level field.
   213
   21416. Authenticating as a second user after starting a session results in a server error
   215~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   216
   217This test only applies to drivers that allow authentication to be changed on the fly.
   218
   219* Authenticate as the first user
   220* Start a session by calling ``startSession``
   221* Authenticate as a second user
   222* Call ``findOne`` using the session as an explicit session
   223* Assert that the driver returned an error because multiple users are authenticated
   224
   22517. Driver verifies that the session is owned by the current user
   226~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   227
   228This test only applies to drivers that allow authentication to be changed on the fly.
   229
   230* Authenticate as user A
   231* Start a session by calling ``startSession``
   232* Logout user A
   233* Authenticate as user B
   234* Call ``findOne`` using the session as an explicit session
   235* Assert that the driver returned an error because the session is owned by a different user
   236
   237Changelog
   238=========
   239
   240:2019-05-15: Initial version.
   241:2021-06-15: Added snapshot-session tests. Introduced legacy and unified folders.
   242:2021-07-30: Use numbering for prose test
   243:2022-02-11: Convert legacy tests to unified format
   244:2022-06-13: Relocate prose test from spec document and apply new ordering

View as plain text