Get desktop application:
View/edit binary Protocol Buffers messages
Used in: ,
This will be propagated to other concurrent transactions, e.g. it can be used for gating and communicating between concurrent transactions
Used in: ,
Countdown a latch
Defined https://hackmd.io/foGjnSSIQmqfks2lXwNp8w#Protocol-Extensions
Used in: ,
This is mandatory if PROTOCOL_VERSION_2_0 or higher is sent.
At least one of EXT_MEMORY_OPT_UNSTAGING and EXT_TIME_OPT_UNSTAGING must be supported
Support for Caps.CONTENT_AS_PERFORMER_VALIDATION is a pre-requisite for all following extensions.
The set of collections currently being cleaned up.
Used in:
Used as request type in: PerformerService.cleanupSetFetch
Used as response type in: PerformerService.cleanupSetFetch
Used as request type in: PerformerService.clientRecordProcess
The collection where the client record should exist (this message was created before Collection existed)
Any hooks can only use HookPoints in the CLIENT_RECORD_* range
This is only needed for KV operations, so the driver will usually send the default cluster connection.
Used as response type in: PerformerService.clientRecordProcess
Used as request type in: PerformerService.clientRecordRemove
Any hooks can only use HookPoints in the CLIENT_RECORD_* range
This is only needed for KV operations, so the driver will usually send the default cluster connection.
Used as response type in: PerformerService.clientRecordRemove
Used as request type in: PerformerService.closeTransactions
(message has no fields)
Used as response type in: PerformerService.closeTransactions
(message has no fields)
A batch of commands, often to be performed in parallel. But not always, sometimes it's used so multiple threads can each run a series of commands in serial. (E.g. nested CommandBatches). So it's crucial that the performer respect the `parallelism` setting. Created long before HorizontalScaling. Note the semantics of this command aren't as defined as they could be - see some discussion on https://couchbase.slack.com/archives/C014WB8U2MQ/p1665062945395139 The requirements are: 1. The operations should be started in parallel (assuming `parallelism` > 1 of course) 2. The ~first error should be propagated out of the lambda. ("~first" as it's fine for this to be best-effort, e.g. it doesn't have to require atomic variables or locking. Because the first concurrent failure is anyway non-deterministic). What is not defined is what happens to the other operations if one of them fails. Are they left to run to completion, are they cancelled, is that cancellation waited on? These semantics probably need to be selectable. Currently it is acceptable to do whatever is easiest - e.g. Java reactor will automatically cancel the other operations, while in Go it's easiest to wait for them all to complete.
Used in:
A limited subset of commands are supported here: CommandInsert, CommandReplace, CommandRemove and CommandGet. And replace/remove cannot use useStashedResult, as that is not a well-defined concept in parallel operations.
If the commands are being performed in parallel, how many to do concurrently. The performer is required to have this many operations in flight at once. E.g. say this value is 3, and 10 operations are specified in `commands`. The performer should start the first 3 operations in `commands` in parallel. Once an operation finishes successfully the performer should immediately start the next operation in `commands`, in parallel with the still-running other 2. It should not 'batch' the operations and wait for them all to succeed before progressing with the next batch.
ExtSDKIntegration performers should ignore. Otherwise, perform an explicit ctx.commit()
Used in:
What result(s) the command is allowed to return. Anything outside this will fail the test.
Used in: ,
What result(s) the command is allowed to return. Anything outside this will fail the test. Tests can generally just set one expected result. Multiple results are allowed to support tricky situations, such as an op generally failing with FAIL_TRANSIENT until it fails with FAIL_EXPIRY
If not-null, the performer will check the fetched data equals this. Useful for read-your-own-write tests. This is superceded by content_as_validation, but that is only available with CONTENT_AS_PERFORMER_VALIDATION, so tests will continue to use this until that extension is fully rolled out.
Added with cap CONTENT_AS_PERFORMER_VALIDATION and will only be sent if performer declares support for that.
If not DO_NOT_CHECK, the performer will check the fetched document status equals this. Fully deprecated as of ExtSDKIntegration. The driver will only specify DO_NOT_CHECK now.
Since day one the performer must have supported stashing a single document. Whenever a CommandGet or CommandGetOptional is executed (but not a transactions.Get), the result is automatically stashed. ExtMobileInterop adds the concept of stashing multiple documents. This allows some more sophisticated tests particularly around CAS mismatches. If this `stashInSlot` is set, the performer needs to update or create a map of StashSlot (Int) -> TransactionGetResult. This is stored per-transaction and should be deleted at the end of the transaction. Subsequent CommandReplace and CommandReplace operations may may reference to one of these stashed results.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
The SDK needs to implement TransactionGetMultiReplicasFromPreferredServerGroupOptions and TransactionGetMultiReplicaFromPreferredServerGroupSpec. But to save testing effort, and because the APIs are currently identical except for naming, FIT will use the same CommandGetMulti for both. If they diverge in future we will copy the messages then.
Used in:
What result(s) this individual spec is allowed to return. Anything outside this will fail the test. The performer must perform this validation. If this is empty, the performer skips validation.
Iff true, performer should use ctx.getMultiReplicasFromPreferredServerGroup() instead of ctx.getMulti()
Used in:
The performer always needs to check if the doc is returned as Optional.None or present, against this.
Determines if and how the performer should execute transactionGetResult.contentAs() on this individual spec result.
Each spec will result in a result in the output array. This contains the required position of the result in that array, which the SDK must validate.
There are two ways the implementation can implement getOptional: 1. An explicit ctx.getOptional() API. 2. ctx.get() throwing a catchable DocumentNotFoundException. Either is allowed.
Used in:
Use this instead of passing EXPECT_FAIL_DOC_NOT_FOUND or EXPECT_FAIL_DOC_ALREADY_EXISTS
Added with cap CONTENT_AS_PERFORMER_VALIDATION and will only be sent if performer declares support for that.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
Used in:
What result(s) the command is allowed to return. Anything outside this will fail the test.
Added with cap CONTENT_AS_PERFORMER_VALIDATION and will only be sent if performer declares support for that.
Refer to `stashInSlot` in CommandGet for details. `useStashedResult` and `useStashedSlot` will not be sent together.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
Used in:
This is superceded by `content`, but that is only available with EXT_BINARY_SUPPORT, so tests will continue to use this until that extension is fully rolled out.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
What result(s) the command is allowed to return. Anything outside this will fail the test.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
Insert a document using a regular KV operation. The command is expected to succeed. Created long before SdkCommandInsert.
Used in:
Run a query command.
Used in: ,
What result(s) the command is allowed to return. Anything outside this will fail the test.
Whether to check the returned rows against expectedRows
What rows the query should return, as JSON
Whether to check the number of returned rows against expectedRowCount
How many rows the query should return
Whether to check the returned mutations
How many mutations the query should create
Deprecated as of ExtSDKIntegration, replaced by queryOptions, which allows optional. FIT will send both for now, performers should remove support for queryParameters.
Parameters for the Query Statement
Used in:
Extra deprecated as it was never possible to set timeout on TransactionQueryOptions
Used in:
What result(s) the command is allowed to return. Anything outside this will fail the test.
Whether to use the result of the last get operation This will not be set inside a CommandBatch, due to the 'last' operation not being a valid concept during parallel ops.
Refer to `stashInSlot` in CommandGet for details. `useStashedResult` and `useStashedSlot` will not be sent together.
Remove a document using a regular KV operation. The command is expected to succeed. Created long before SdkCommandRemove.
Used in:
Used in:
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
What result(s) the command is allowed to return. Anything outside this will fail the test.
Whether to use the result of the last get operation. This will not be set inside a CommandBatch, due to the 'last' operation not being a valid concept during parallel ops.
Refer to `stashInSlot` in CommandGet for details. `useStashedResult` and `useStashedSlot` will not be sent together.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
Replace a document using a regular KV operation. The command is expected to succeed. Created long before SdkCommandReplace.
Used in:
ExtSDKIntegration performers: throw an exception (or raise an error) to cause an auto-rollback. Otherwise, perform an explicit ctx.rollback()
Used in:
What result(s) the command is allowed to return. Anything outside this will fail the test.
Used in: ,
If the performer executes this command, it should report a failure. This is usually used to check an earlier operation definitely failed the transaction.
Used in:
(message has no fields)
Simulates the application throwing an exception inside the lambda. Could be used to simulate an application bug, or the application choosing to rollback this way (as opposed to ctx.rollback(), e.g. app-rollback). Application exceptions will be classified as FAIL_OTHER.
Used in:
(message has no fields)
Used in:
Requests the performer creates a connection to a Couchbase cluster, and return performer caps. In the transactions package as it was part of the original transactions-only implementation, and has been replaced now.
Used as request type in: PerformerService.createConnection
As of ExtSDKIntegration this field will no longer be sent and should be ignored. It is unclear why it was ever required.
As of ExtSDKIntegration this field will no longer be sent and should be ignored. The driver will now always explicitly send a clusterConnectionId.
The performer should use a custom JsonSerializer when creating the Cluster. This custom JsonSerializer is required to have specific serialization and deserialization logic, which the driver will validate. See the Java performer for implementation details.
Used for TLS enabled clusters such as Capella clusters
Returns the capabilities of the performer (or more specifically, the transactions-implementation-under-test by that performer), along with a reference to the created cluster connection. As of ExtSDKIntegration, this is now legacy. Performers should implement getPerformerCaps and createClusterConnection instead. This
Used as response type in: PerformerService.createConnection
Human-readable string identifying the performer. For example, "java".
Identifies the version of the library under test. For example, "1.1.2".
Defined https://hackmd.io/foGjnSSIQmqfks2lXwNp8w#Protocol-Versions Must be "1.0", "2.0" or "2.1" any other values will cause the driver to abort.
The APIs this implementation supports. This is primarily used to run tests on multiple APIs, so if an implementation only supports one, it should just return one - see comments for `API` for details. If the performer does not return anything, it will be assumed to support just API.DEFAULT.
Exists for legacy reasons. Newer messages should use DocLocation.
Used in: , , , , , , , , , , ,
This was only exposed in the Java API and is deprecated as of 1.1.3 Other implementations are not required to check this.
Used in:
Used in:
Any ErrorClass is permitted - including the TransactionOperationFailed not having one Note that ErrorClass validation is now deprecated and performers should remove their validation logic.
This maps to the TransactionOperationFailed defined in the design doc
Used in:
This is now deprecated and the performer can feel free to disable validation of this. Once all performers have removed validation, it will be removed.
Used in:
Used in:
Used in:
Tests should specify the expected cause wherever possible
Used in: , , , , , , , , , , , ,
If the command should succeed
If the command is permitted to do anything, e.g. succeed or throw errors. Required for some complex tests where it's tricky to calculate what a given op will do.
The operation throws an ErrorWrapper/TransactionOperationFailed, the only exception an operation may throw. Update: as of EXT_QUERY, EXT_SDK_INTEGRATION and EXT_INSERTS_EXISTING, that is no longer the case, some operations can throw some other exceptions.
Require a non-TransactionOperationFailed exception.
The root cause of the TransactionException. Will only be checked if TransactionException != NO_EXCEPTION_THROWN
Used in: , , ,
Added with EXT_REPLICA_FROM_PREFERRED_GROUP
Used in:
What result(s) the command is allowed to return. Anything outside this will fail the test. The performer must perform this validation. If this is empty, the performer skips validation.
If this `stashInSlot` is set, the performer needs to update or create a map of StashSlot (Int) -> TransactionGetResult. This is stored per-transaction and should be deleted at the end of the transaction. Subsequent operations may may reference to one of these stashed results. transactions.CommandGet and transactions.Get share the same map.
Determines if and how the performer should execute transactionGetResult.contentAs(). Added with CONTENT_AS_PERFORMER_VALIDATION and will only be sent if performer declares support for that.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
Used in:
What result(s) the command is allowed to return. Anything outside this will fail the test. The performer must perform this validation. If this is empty, the performer skips validation.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
Used in:
What result(s) the command is allowed to return. Anything outside this will fail the test. The performer must perform this validation. If this is empty, the performer skips validation.
Refer to `stashInSlot` in CommandGet for details.
Used in:
What result(s) the command is allowed to return. Anything outside this will fail the test. The performer must perform this validation. If this is empty, the performer skips validation.
Refer to `stashInSlot` in CommandGet for details.
Added with EXT_BINARY_SUPPORT and will only be sent if performer declares support for that.
Used in:
Can be empty iff state=NOTHING_WRITTEN
Used in:
Used as request type in: PerformerService.transactionCleanupATR
For backwards-compatibility with performers that don't support `atr` yet - will be removed eventually
Field `atr` should be used instead.
Any hooks can only use HookPoints in the CLEANUP_* range
Used as response type in: PerformerService.transactionCleanupATR
Total number of entries found in the ATR
Total number of expired entries found in the ATR
The result of attempting to cleanup a single attempt entry in an ATR
Used as response type in: PerformerService.transactionCleanup
Used as field type in: ,
Whether the attempt succeeded
All logs related to the attempt
The state of the ATR entry, before cleanup. This field is optional. It will allow additional verification in some tests if it is provided.
The ATR's location
The key of the ATR document For backwards-compatibility with performers that don't support `atr` yet - aiming to remove eventually.
Field `atr` should be used instead.
The name of the bucket the ATR is on
Field `atr` should be used instead.
The ID of the transaction attempt that was being cleaned up
Used as response type in: PerformerService.transactionProcessCleanupQueue
Used as request type in: PerformerService.transactionCleanup
For backwards-compatibility with performers that don't support `atr` yet - will be removed eventually
Field `atr` should be used instead.
Any hooks can only use HookPoints in the CLEANUP_* range
This is only needed for KV operations, so the driver will usually send the default cluster connection.
Used in: ,
All operations in the batch will be performed in parallel
Why do we have transactions.CommandInsert and transactions.Insert? The former stems from the original days of FIT that just did integration testing of transactions. The latter is for modern FIT and supports the abstractions we need now, including for performance testing. These will only be sent if the performer declares support for TRANSACTIONS_WORKLOAD_1.
Added for TXNJ-249: make the application (erroneously) catch and not propagate the error.
If given, the performer will pause (blocking) for `wait_msecs` before executing the TransactionCommand
Initiates a single transaction.
Used as request type in: PerformerService.transactionCreate
Used as field type in: ,
Non-ExtSDKIntegration: A reference to a previously constructed Transactions object (e.g. factory). ExtSDKIntegration: ignore this (it will not be sent), and just use `clusterConnectionId` to get `cluster.transactions()`.
A transaction can consist of multiple attempts. Usually we want each attempt to do the same thing, but there are a handful of tests where we need more complex logic and need to do different things on different attempts. If the transaction does more attempts than are in this field, the commands in the last attempt are what will be repeated.
Any latches that the transaction should create.
Just for debugging, name the test
Instead of the performer returning any raised events, the driver specifies which are expected, or explicitly not expected. Event buses can be asynchronous so this prevents the performer having to wait for an unknown amount of time on each test. Also, each implementation handles events differently - some use an event bus, some simply log. So this allows the performer to also check as appropriate. For expectedAbsenceOfEvents, the performer should pick an appropriate amount of time to wait for events before deciding an event will definitely not arrive.
Used for ExtSDKIntegration to create the transaction, and both in that and in non-ExtSDKIntegration to access collections for KV operations.
The API to use for this transaction. See the comments for `API`.
Used in:
(message has no fields)
The exception received by the application, if any
Used in: , ,
Used as response type in: PerformerService.transactionsFactoryClose
(message has no fields)
Used in:
Used in:
Used in: , , ,
Used in: ,
Added with EXT_TTL and will only be sent if performer declares support for that
Options that can be overridden at the individual transaction level. Note that pre-ExtSDKIntegration, this struct was empty. Not in the implementation, where PerTransactionConfig existed, but here at the FIT level. So, it will only be populated for ExtSDKIntegration performers.
Used in:
Durability to use for all mutating KV operations in this transaction.
Timeout (nee expirationTime) for this transaction.
Any hooks can only use HookPoints before the CLEANUP_* range.
Will only be sent to ExtSDKIntegration-enabled performers.
Identifies a tracing span to use as the parent for this transaction. Only sent to performers that declare support for Caps.OBSERVABILITY_1.
Used as request type in: PerformerService.transactionProcessCleanupQueue
Used in:
"off", "phases", or "timings"
Used in: ,
Added with EXT_TTL and will only be sent if performer declares support for that
The result of closing a transaction: whether the transaction succeeded, its logs, any exception thrown...
Used as response type in: PerformerService.transactionCreate
Used as field type in: , ,
With CBD-3802 this is now only checked for the Java performer, other implementations should not provide this. It will eventually be removed.
Next three fields are all now deprecated. They are no longer used by FIT and performers do not need to return them. They will eventually be removed.
Any TransactionFailed error raised by the operation.
The cause field from any TransactionFailed error.
The implementation's in-memory log. It's optional but helps greatly with debugging.
How many attempts need to be cleaned up, as a direct result of this transaction. This field is only valid if cleanupClientAttempts was set (transactions will not queue a cleanup attempt if there is nothing to handle it)
Whether the cleanupRequestsPending field is valid, e.g. whether it can be checked
Allows the performer to flag implementation/platform-specific validation failures that cannot be handled generically. E.g. if an erroneous event is detected it can be returned here. If present, the driver will fail the test, logging this message.
As of ExtSDKIntegration, this is deprecated, and the performer no longer needs to return it - it will be ignored. It's somewhat unclear why it was here in the first place. Appears to be used for creating a TransactionCleanupRequest, but that can use any clusterConnectionId, including the default.
Runs a single query transaction (tximplicit). ExtSDKIntegration: cluster.query() Non-ExtSDKIntegration: transactions.query()
Used as request type in: PerformerService.transactionSingleQuery
A reference to a previously constructed Transactions object (e.g. factory). Not sent to ExtSDKIntegration performers.
A reference to a previously constructed cluster connection. Will always be sent, but is only used by ExtSDKIntegration performers.
The query to run
Config needs handling differently in the performer based on ExtSDKIntegration or not. The structure of these messages is based around how things work in ExtSDKIntegration, and need some finangling for non-ExtSDKIntegration performers. ExtSDKIntegration: - The user calls `(cluster|scope).query(String, queryOptions().asTransaction([SingleQueryTransactionOptions]))`. - Everything in GRPC QueryOptions should be passed to an SDK QueryOptions. - The nested GRPC SingleQueryTransactionOptions should be passed as the SDK SingleQueryTransactionOptions block on QueryOptions.asTransaction(), if it is present. Otherwise call QueryOptions.asTransaction() with no args. Non-ExtSDKIntegration: - The user calls `transactions().query([Scope], String, [SingleQueryTransactionConfig])` - SDK SingleQueryTransactionConfig contains an SDK TransactionQueryOptions. This should be populated from GRPC QueryOptions. -- If no GRPC QueryOptions settings are specified, no SDK TransactionQueryOptions should be created. -- The GRPC QueryOptions.timeout() field must be applied at the SDK SingleQueryTransactionConfig level instead. - SDK SingleQueryTransactionConfig is populated from GRPC QueryOptions.SingleQueryTransactionOptions. - GRPC SingleQueryTransactionOptions.metadataCollection can be ignored. That was added in ExtSDKIntegration.
The API to use for this transaction. See the comments for `API`.
Used as response type in: PerformerService.transactionSingleQuery
Deprecated as this was from the initial version of ExtSingleQuery, pre SDK-integration. The replacement fields below are compatible with the SDK integration, when only a QueryResult (or TransactionFailed-derived error) is going to be returned to the user. If `result` is returned then FIT will validate that, else it will use the replacement fields.
Any TransactionFailed error raised by the operation, at the point of performing the cluster.query()/transactions.query() If it threw a non-TransactionFailed exception, return EXCEPTION_UNKNOWN
If `exception` is EXCEPTION_UNKNOWN, then this is the exception raised at the point of performing the cluster.query()/transactions.query(). e.g. this is how non-TransactionFailed errors are indicated. Otherwise, it's the cause field of the TransactionFailed.
Any TransactionFailed error raised by the operation, at the point of streaming the rows.
If `exceptionDuringStreaming` is NO_EXCEPTION_THROWN, then this is the exception raised while streaming the rows. e.g. this is how non-TransactionFailed errors are indicated. Otherwise, it's the cause field of the TransactionFailed.
The implementation's in-memory log. It's optional (and not possible to return when the SDK integrated cluster.query() succeeds), but helps greatly with debugging on failures.
Allows the performer to flag implementation/platform-specific validation failures that cannot be handled generically. E.g. if an erroneous event is detected it can be returned here. If present, the driver will fail the test, logging this message.
Used in:
(message has no fields)
Used as request type in: PerformerService.transactionStream
This will setup a TwoWayTransaction but not start it. Must only be one of these per stream..
Starts a previously setup TwoWayTransaction Only one of these will be sent per stream, and it will be after the TransactionCreateRequest.
A request broadcast from another TwoWayTransaction, that is being broadcast to the rest via the driver.
Used as response type in: PerformerService.transactionStream
The transaction is completed, and the stream is done
The transaction has been created e.g. as result of a TransactionCreateRequest, and is now ready to start e.g. a TransactionStartRequest
Shuts down a previously created Transactions (factory)
Used as request type in: PerformerService.transactionsFactoryClose
Creates a Transactions object, e.g. a transactions factory
Used as request type in: PerformerService.transactionsFactoryCreate
The following fields are deprecated and replaced by the `config` field (which allows optional fields) They will still be sent by FIT, but performers should remove them while implementing the breaking change for ExtSDKIntegration
Any hooks can only use HookPoints before the CLEANUP_* range
The Cluster to use for `Transactions.create()`
Used as response type in: PerformerService.transactionsFactoryCreate
Used in:
Used in:
The commands to run. Each command should send back one TransactionResult. The commands should be executed in a loop following `bounds`. E.g. the performer may go through all the commands multiple times. If the command fails, the performer should not propagate the failure (but should still send back an TransactionResult). E.g. it should continue until bounds is exhausted (or it has run all commands, if bounds is not specified).
Controls how the commands should be run. If it's not present, just run the commands through once.
Performance mode indicates that this is a performance test, where the performer should disable various functionality. This includes: 1. Minimise the returned result A TransactionResult is heavy-weight, including things like a full log of the transaction. This requests that a minimal TransactionResult be returned, to reduce the performance impact. Specifically, on success the performer should only set exception=NO_EXCEPTION_THROWN, and populate no other fields. On failure, the performer should populate a full TransactionResult as normal - as it's expected that normal performance tests should not include failed transactions). 2. Reduce all performer logging to minimise impact. The transactions/SDK logging though should not be affected - this should be configured through the standard configuration paths. Because we will want to measure the impact of having it enabled.