PYTHON-2769 Test redaction of replies to security-sensitive commands (#676)
Resync command monitoring and unified test format tests. Redact entire hello response when the command started contained speculativeAuthenticate. Make OP_REPLY cursor.cursor_id always be an Int64.
This commit is contained in:
parent
9a4c64f325
commit
01e34cebdb
@ -33,6 +33,7 @@ from bson import (CodecOptions,
|
||||
_dict_to_bson,
|
||||
_make_c_string)
|
||||
from bson.codec_options import DEFAULT_CODEC_OPTIONS
|
||||
from bson.int64 import Int64
|
||||
from bson.raw_bson import (_inflate_bson, DEFAULT_RAW_BSON_OPTIONS,
|
||||
RawBSONDocument)
|
||||
from bson.son import SON
|
||||
@ -1503,7 +1504,7 @@ class _OpReply(object):
|
||||
|
||||
def __init__(self, flags, cursor_id, number_returned, documents):
|
||||
self.flags = flags
|
||||
self.cursor_id = cursor_id
|
||||
self.cursor_id = Int64(cursor_id)
|
||||
self.number_returned = number_returned
|
||||
self.documents = documents
|
||||
|
||||
|
||||
@ -1350,7 +1350,8 @@ class _EventListeners(object):
|
||||
|
||||
def publish_command_success(self, duration, reply, command_name,
|
||||
request_id, connection_id, op_id=None,
|
||||
service_id=None):
|
||||
service_id=None,
|
||||
speculative_hello=False):
|
||||
"""Publish a CommandSucceededEvent to all command listeners.
|
||||
|
||||
:Parameters:
|
||||
@ -1362,9 +1363,14 @@ class _EventListeners(object):
|
||||
command was sent to.
|
||||
- `op_id`: The (optional) operation id for this operation.
|
||||
- `service_id`: The service_id this command was sent to, or ``None``.
|
||||
- `speculative_hello`: Was the command sent with speculative auth?
|
||||
"""
|
||||
if op_id is None:
|
||||
op_id = request_id
|
||||
if speculative_hello:
|
||||
# Redact entire response when the command started contained
|
||||
# speculativeAuthenticate.
|
||||
reply = {}
|
||||
event = CommandSucceededEvent(
|
||||
duration, reply, command_name, request_id, connection_id, op_id,
|
||||
service_id)
|
||||
|
||||
@ -31,6 +31,7 @@ from pymongo.errors import (NotPrimaryError,
|
||||
ProtocolError,
|
||||
_OperationCancelled)
|
||||
from pymongo.message import _UNPACK_REPLY, _OpMsg
|
||||
from pymongo.monitoring import _is_speculative_authenticate
|
||||
from pymongo.socket_checker import _errno_from_exception
|
||||
|
||||
|
||||
@ -82,6 +83,7 @@ def command(sock_info, dbname, spec, slave_ok, is_mongos,
|
||||
name = next(iter(spec))
|
||||
ns = dbname + '.$cmd'
|
||||
flags = 4 if slave_ok else 0
|
||||
speculative_hello = False
|
||||
|
||||
# Publish the original command document, perhaps with lsid and $clusterTime.
|
||||
orig = spec
|
||||
@ -98,6 +100,7 @@ def command(sock_info, dbname, spec, slave_ok, is_mongos,
|
||||
publish = listeners is not None and listeners.enabled_for_commands
|
||||
if publish:
|
||||
start = datetime.datetime.now()
|
||||
speculative_hello = _is_speculative_authenticate(name, spec)
|
||||
|
||||
if compression_ctx and name.lower() in _NO_COMPRESSION:
|
||||
compression_ctx = None
|
||||
@ -170,7 +173,8 @@ def command(sock_info, dbname, spec, slave_ok, is_mongos,
|
||||
duration = (datetime.datetime.now() - start) + encoding_duration
|
||||
listeners.publish_command_success(
|
||||
duration, response_doc, name, request_id, address,
|
||||
service_id=sock_info.service_id)
|
||||
service_id=sock_info.service_id,
|
||||
speculative_hello=speculative_hello)
|
||||
|
||||
if client and client._encrypter and reply:
|
||||
decrypted = client._encrypter.decrypt(reply.raw_command_response())
|
||||
|
||||
@ -86,9 +86,7 @@
|
||||
"$set": {
|
||||
"x": 333
|
||||
}
|
||||
},
|
||||
"upsert": false,
|
||||
"multi": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"ordered": true
|
||||
|
||||
@ -32,9 +32,7 @@
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": true
|
||||
}
|
||||
"ordered": true
|
||||
},
|
||||
"command_name": "insert",
|
||||
"database_name": "command-monitoring-tests"
|
||||
@ -75,9 +73,7 @@
|
||||
"x": 11
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": true
|
||||
}
|
||||
"ordered": true
|
||||
},
|
||||
"command_name": "insert",
|
||||
"database_name": "command-monitoring-tests"
|
||||
@ -128,9 +124,7 @@
|
||||
"x": 22
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"ordered": false
|
||||
}
|
||||
"ordered": false
|
||||
},
|
||||
"command_name": "insert",
|
||||
"database_name": "command-monitoring-tests"
|
||||
|
||||
@ -51,8 +51,7 @@
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": true,
|
||||
"upsert": false
|
||||
"multi": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -106,8 +105,7 @@
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": true,
|
||||
"upsert": false
|
||||
"multi": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -50,9 +50,7 @@
|
||||
"$inc": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -103,7 +101,6 @@
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": true
|
||||
}
|
||||
]
|
||||
@ -163,9 +160,7 @@
|
||||
"$nothing": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"multi": false,
|
||||
"upsert": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -12,7 +12,8 @@
|
||||
"client": {
|
||||
"id": "client",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
"commandStartedEvent",
|
||||
"commandSucceededEvent"
|
||||
],
|
||||
"observeSensitiveCommands": true
|
||||
}
|
||||
@ -35,7 +36,10 @@
|
||||
"arguments": {
|
||||
"commandName": "authenticate",
|
||||
"command": {
|
||||
"authenticate": "private"
|
||||
"authenticate": 1,
|
||||
"mechanism": "MONGODB-X509",
|
||||
"user": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry",
|
||||
"db": "$external"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
@ -53,6 +57,15 @@
|
||||
"command": {
|
||||
"authenticate": {
|
||||
"$$exists": false
|
||||
},
|
||||
"mechanism": {
|
||||
"$$exists": false
|
||||
},
|
||||
"user": {
|
||||
"$$exists": false
|
||||
},
|
||||
"db": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,7 +83,9 @@
|
||||
"arguments": {
|
||||
"commandName": "saslStart",
|
||||
"command": {
|
||||
"saslStart": "private"
|
||||
"saslStart": 1,
|
||||
"payload": "definitely-invalid-payload",
|
||||
"db": "admin"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
@ -88,6 +103,12 @@
|
||||
"command": {
|
||||
"saslStart": {
|
||||
"$$exists": false
|
||||
},
|
||||
"payload": {
|
||||
"$$exists": false
|
||||
},
|
||||
"db": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,7 +126,9 @@
|
||||
"arguments": {
|
||||
"commandName": "saslContinue",
|
||||
"command": {
|
||||
"saslContinue": "private"
|
||||
"saslContinue": 1,
|
||||
"conversationId": 0,
|
||||
"payload": "definitely-invalid-payload"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
@ -123,6 +146,12 @@
|
||||
"command": {
|
||||
"saslContinue": {
|
||||
"$$exists": false
|
||||
},
|
||||
"conversationId": {
|
||||
"$$exists": false
|
||||
},
|
||||
"payload": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,7 +169,7 @@
|
||||
"arguments": {
|
||||
"commandName": "getnonce",
|
||||
"command": {
|
||||
"getnonce": "private"
|
||||
"getnonce": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,6 +187,19 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"commandName": "getnonce",
|
||||
"reply": {
|
||||
"ok": {
|
||||
"$$exists": false
|
||||
},
|
||||
"nonce": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -172,7 +214,9 @@
|
||||
"arguments": {
|
||||
"commandName": "createUser",
|
||||
"command": {
|
||||
"createUser": "private"
|
||||
"createUser": "private",
|
||||
"pwd": {},
|
||||
"roles": []
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
@ -190,6 +234,12 @@
|
||||
"command": {
|
||||
"createUser": {
|
||||
"$$exists": false
|
||||
},
|
||||
"pwd": {
|
||||
"$$exists": false
|
||||
},
|
||||
"roles": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -207,7 +257,9 @@
|
||||
"arguments": {
|
||||
"commandName": "updateUser",
|
||||
"command": {
|
||||
"updateUser": "private"
|
||||
"updateUser": "private",
|
||||
"pwd": {},
|
||||
"roles": []
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
@ -225,6 +277,12 @@
|
||||
"command": {
|
||||
"updateUser": {
|
||||
"$$exists": false
|
||||
},
|
||||
"pwd": {
|
||||
"$$exists": false
|
||||
},
|
||||
"roles": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -340,6 +398,11 @@
|
||||
},
|
||||
{
|
||||
"description": "hello with speculative authenticate",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "4.9"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "runCommand",
|
||||
@ -347,40 +410,11 @@
|
||||
"arguments": {
|
||||
"commandName": "hello",
|
||||
"command": {
|
||||
"hello": "private",
|
||||
"speculativeAuthenticate": "foo"
|
||||
"hello": 1,
|
||||
"speculativeAuthenticate": {
|
||||
"saslStart": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"isError": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database",
|
||||
"arguments": {
|
||||
"commandName": "ismaster",
|
||||
"command": {
|
||||
"ismaster": "private",
|
||||
"speculativeAuthenticate": "foo"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"isError": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database",
|
||||
"arguments": {
|
||||
"commandName": "isMaster",
|
||||
"command": {
|
||||
"isMaster": "private",
|
||||
"speculativeAuthenticate": "foo"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"isError": true
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -394,16 +428,86 @@
|
||||
"command": {
|
||||
"hello": {
|
||||
"$$exists": false
|
||||
},
|
||||
"speculativeAuthenticate": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"commandName": "hello",
|
||||
"reply": {
|
||||
"isWritablePrimary": {
|
||||
"$$exists": false
|
||||
},
|
||||
"speculativeAuthenticate": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "legacy hello with speculative authenticate",
|
||||
"operations": [
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database",
|
||||
"arguments": {
|
||||
"commandName": "ismaster",
|
||||
"command": {
|
||||
"ismaster": 1,
|
||||
"speculativeAuthenticate": {
|
||||
"saslStart": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database",
|
||||
"arguments": {
|
||||
"commandName": "isMaster",
|
||||
"command": {
|
||||
"isMaster": 1,
|
||||
"speculativeAuthenticate": {
|
||||
"saslStart": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "ismaster",
|
||||
"command": {
|
||||
"ismaster": {
|
||||
"$$exists": false
|
||||
},
|
||||
"speculativeAuthenticate": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"commandName": "ismaster",
|
||||
"reply": {
|
||||
"ismaster": {
|
||||
"$$exists": false
|
||||
},
|
||||
"speculativeAuthenticate": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -414,6 +518,22 @@
|
||||
"command": {
|
||||
"isMaster": {
|
||||
"$$exists": false
|
||||
},
|
||||
"speculativeAuthenticate": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"commandName": "isMaster",
|
||||
"reply": {
|
||||
"ismaster": {
|
||||
"$$exists": false
|
||||
},
|
||||
"speculativeAuthenticate": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -424,6 +544,11 @@
|
||||
},
|
||||
{
|
||||
"description": "hello without speculative authenticate is not redacted",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "4.9"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "runCommand",
|
||||
@ -431,27 +556,7 @@
|
||||
"arguments": {
|
||||
"commandName": "hello",
|
||||
"command": {
|
||||
"hello": "public"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database",
|
||||
"arguments": {
|
||||
"commandName": "ismaster",
|
||||
"command": {
|
||||
"ismaster": "public"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database",
|
||||
"arguments": {
|
||||
"commandName": "isMaster",
|
||||
"command": {
|
||||
"isMaster": "public"
|
||||
"hello": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -464,15 +569,67 @@
|
||||
"commandStartedEvent": {
|
||||
"commandName": "hello",
|
||||
"command": {
|
||||
"hello": "public"
|
||||
"hello": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"commandName": "hello",
|
||||
"reply": {
|
||||
"isWritablePrimary": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "legacy hello without speculative authenticate is not redacted",
|
||||
"operations": [
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database",
|
||||
"arguments": {
|
||||
"commandName": "ismaster",
|
||||
"command": {
|
||||
"ismaster": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database",
|
||||
"arguments": {
|
||||
"commandName": "isMaster",
|
||||
"command": {
|
||||
"isMaster": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "ismaster",
|
||||
"command": {
|
||||
"ismaster": "public"
|
||||
"ismaster": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"commandName": "ismaster",
|
||||
"reply": {
|
||||
"ismaster": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -480,7 +637,17 @@
|
||||
"commandStartedEvent": {
|
||||
"commandName": "isMaster",
|
||||
"command": {
|
||||
"isMaster": "public"
|
||||
"isMaster": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"commandName": "isMaster",
|
||||
"reply": {
|
||||
"ismaster": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,6 +146,15 @@ def create_test(scenario_def, test):
|
||||
event.command['getMore'] = 42
|
||||
elif event.command_name == 'killCursors':
|
||||
event.command['cursors'] = [42]
|
||||
elif event.command_name == 'update':
|
||||
# TODO: remove this once PYTHON-1744 is done.
|
||||
# Add upsert and multi fields back into
|
||||
# expectations.
|
||||
updates = expectation[event_type]['command'][
|
||||
'updates']
|
||||
for update in updates:
|
||||
update.setdefault('upsert', False)
|
||||
update.setdefault('multi', False)
|
||||
elif event_type == "command_succeeded_event":
|
||||
event = (
|
||||
res['succeeded'].pop(0) if len(res['succeeded']) else None)
|
||||
|
||||
@ -1,100 +0,0 @@
|
||||
{
|
||||
"description": "example-insertOne",
|
||||
"schemaVersion": "1.0",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "2.6"
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll",
|
||||
"databaseName": "test",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "insertOne",
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 2
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"insertedId": {
|
||||
"$$unsetOrMatches": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"databaseName": "test",
|
||||
"command": {
|
||||
"insert": "coll",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll",
|
||||
"databaseName": "test",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
{
|
||||
"description": "entity-client-observeSensitiveCommands-type",
|
||||
"schemaVersion": "1.5",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeSensitiveCommands": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-connectionCheckOutFailedEvent-reason-type",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionCheckOutFailedEvent": {
|
||||
"reason": 10
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-connectionCheckOutStartedEvent-additionalProperties",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionCheckOutStartedEvent": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-connectionCheckedInEvent-additionalProperties",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionCheckedInEvent": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-connectionCheckedOutEvent-additionalProperties",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionCheckedOutEvent": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-connectionClosedEvent-reason-type",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionClosedEvent": {
|
||||
"reason": 10
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-connectionCreatedEvent-additionalProperties",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionCreatedEvent": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-connectionReadyEvent-additionalProperties",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionReadyEvent": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-poolClearedEvent-hasServiceId-type",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"poolClearedEvent": {
|
||||
"hasServiceId": "foo"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-poolClosedEvent-additionalProperties",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"poolClosedEvent": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-poolCreatedEvent-additionalProperties",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"poolCreatedEvent": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "expectedCmapEvent-poolReadyEvent-additionalProperties",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"poolReadyEvent": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
{
|
||||
"description": "expectedCommandEvent-commandFailedEvent-hasServiceId-type",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandFailedEvent": {
|
||||
"hasServiceId": "foo"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
{
|
||||
"description": "expectedCommandEvent-commandStartedEvent-hasServiceId-type",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"hasServiceId": "foo"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
{
|
||||
"description": "expectedCommandEvent-commandSucceededEvent-hasServiceId-type",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"hasServiceId": "foo"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-additionalProperties",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"foo": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-commandFailedEvent-commandName-type",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandFailedEvent": {
|
||||
"commandName": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-commandStartedEvent-additionalProperties",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"foo": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-commandStartedEvent-command-type",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-commandStartedEvent-commandName-type",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-commandStartedEvent-databaseName-type",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"databaseName": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-commandSucceededEvent-commandName-type",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"commandName": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-commandSucceededEvent-reply-type",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-maxProperties",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {},
|
||||
"commandSucceededEvent": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
{
|
||||
"description": "expectedEvent-minProperties",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"description": "expectedEventsForClient-eventType-enum",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid eventType value",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "foo",
|
||||
"events": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"description": "expectedEventsForClient-eventType-type",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid eventType type",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": 10,
|
||||
"events": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
{
|
||||
"description": "expectedEventsForClient-events_conflicts_with_cmap_eventType",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid event when eventType is cmap",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
{
|
||||
"description": "expectedEventsForClient-events_conflicts_with_command_eventType",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid event when eventType is command",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "command",
|
||||
"events": [
|
||||
{
|
||||
"poolCreatedEvent": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
{
|
||||
"description": "expectedEventsForClient-events_conflicts_with_default_eventType",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "invalid event when eventType is unset",
|
||||
"operations": [],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"poolCreatedEvent": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
{
|
||||
"description": "operation-ignoreResultAndError-conflicts_with_expectError",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "ignoreResultAndError used with expectError",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "bar",
|
||||
"ignoreResultAndError": true,
|
||||
"expectError": {
|
||||
"isError": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"description": "operation-ignoreResultAndError-conflicts_with_expectResult",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "ignoreResultAndError used with expectResult",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "bar",
|
||||
"ignoreResultAndError": true,
|
||||
"expectResult": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"description": "operation-ignoreResultAndError-conflicts_with_saveResultAsEntity",
|
||||
"schemaVersion": "1.3",
|
||||
"tests": [
|
||||
{
|
||||
"description": "ignoreResultAndError used with saveResultAsEntity",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "bar",
|
||||
"ignoreResultAndError": true,
|
||||
"saveResultAsEntity": "entity0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"description": "runOnRequirement-auth-type",
|
||||
"schemaVersion": "1.3",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"auth": "foo"
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"description": "runOnRequirement-serverless-enum",
|
||||
"schemaVersion": "1.4",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"serverless": "foo"
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"description": "runOnRequirement-serverless-type",
|
||||
"schemaVersion": "1.4",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"serverless": 1234
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
{
|
||||
"description": "storeEventsAsEntity-additionalProperties",
|
||||
"schemaVersion": "1.2",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"storeEventsAsEntities": [
|
||||
{
|
||||
"id": "client0_events",
|
||||
"events": [
|
||||
"CommandStartedEvent"
|
||||
],
|
||||
"foo": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
{
|
||||
"description": "storeEventsAsEntity-events-enum",
|
||||
"schemaVersion": "1.2",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"storeEventsAsEntities": [
|
||||
{
|
||||
"id": "client0_events",
|
||||
"events": [
|
||||
"foo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "storeEventsAsEntity-events-minItems",
|
||||
"schemaVersion": "1.2",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"storeEventsAsEntities": [
|
||||
{
|
||||
"id": "client0_events",
|
||||
"events": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
{
|
||||
"description": "storeEventsAsEntity-events-required",
|
||||
"schemaVersion": "1.2",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"storeEventsAsEntities": [
|
||||
{
|
||||
"id": "client0_events"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"description": "storeEventsAsEntity-events-type",
|
||||
"schemaVersion": "1.2",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"storeEventsAsEntities": [
|
||||
{
|
||||
"id": "client0_events",
|
||||
"events": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"description": "storeEventsAsEntity-id-required",
|
||||
"schemaVersion": "1.2",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"storeEventsAsEntities": [
|
||||
{
|
||||
"events": [
|
||||
"CommandStartedEvent"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
{
|
||||
"description": "storeEventsAsEntity-id-type",
|
||||
"schemaVersion": "1.2",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"storeEventsAsEntities": [
|
||||
{
|
||||
"id": 0,
|
||||
"events": [
|
||||
"CommandStartedEvent"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
{
|
||||
"description": "assertNumberConnectionsCheckedOut",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "operation fails if client field is not specified",
|
||||
"operations": [
|
||||
{
|
||||
"name": "assertNumberConnectionsCheckedOut",
|
||||
"object": "testRunner",
|
||||
"arguments": {
|
||||
"connections": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "operation fails if connections field is not specified",
|
||||
"operations": [
|
||||
{
|
||||
"name": "assertNumberConnectionsCheckedOut",
|
||||
"object": "testRunner",
|
||||
"arguments": {
|
||||
"client": "client0"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "operation fails if client entity does not exist",
|
||||
"operations": [
|
||||
{
|
||||
"name": "assertNumberConnectionsCheckedOut",
|
||||
"object": "testRunner",
|
||||
"arguments": {
|
||||
"client": "client1"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "operation fails if number of connections is incorrect",
|
||||
"operations": [
|
||||
{
|
||||
"name": "assertNumberConnectionsCheckedOut",
|
||||
"object": "testRunner",
|
||||
"arguments": {
|
||||
"client": "client0",
|
||||
"connections": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
62
test/unified-test-format/valid-fail/entity-find-cursor.json
Normal file
62
test/unified-test-format/valid-fail/entity-find-cursor.json
Normal file
@ -0,0 +1,62 @@
|
||||
{
|
||||
"description": "entity-find-cursor",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "database0Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"databaseName": "database0Name",
|
||||
"collectionName": "coll0",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "createFindCursor fails if filter is not specified",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createFindCursor",
|
||||
"object": "collection0",
|
||||
"saveResultAsEntity": "cursor0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "iterateUntilDocumentOrError fails if it references a nonexistent entity",
|
||||
"operations": [
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "cursor0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "close fails if it references a nonexistent entity",
|
||||
"operations": [
|
||||
{
|
||||
"name": "close",
|
||||
"object": "cursor0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
{
|
||||
"description": "ignoreResultAndError",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "database0Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "database0Name",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "operation errors are not ignored if ignoreResultAndError is false",
|
||||
"operations": [
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"ignoreResultAndError": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "malformed operation fails if ignoreResultAndError is true",
|
||||
"operations": [
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"foo": "bar"
|
||||
},
|
||||
"ignoreResultAndError": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
{
|
||||
"description": "assertNumberConnectionsCheckedOut",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "basic assertion succeeds",
|
||||
"operations": [
|
||||
{
|
||||
"name": "assertNumberConnectionsCheckedOut",
|
||||
"object": "testRunner",
|
||||
"arguments": {
|
||||
"client": "client0",
|
||||
"connections": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
{
|
||||
"description": "entity-client-cmap-events",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": true,
|
||||
"observeEvents": [
|
||||
"connectionReadyEvent",
|
||||
"connectionCheckedOutEvent",
|
||||
"connectionCheckedInEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "database0Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "database0Name",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "events are captured during an operation",
|
||||
"operations": [
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionReadyEvent": {}
|
||||
},
|
||||
{
|
||||
"connectionCheckedOutEvent": {}
|
||||
},
|
||||
{
|
||||
"connectionCheckedInEvent": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
182
test/unified-test-format/valid-pass/entity-find-cursor.json
Normal file
182
test/unified-test-format/valid-pass/entity-find-cursor.json
Normal file
@ -0,0 +1,182 @@
|
||||
{
|
||||
"description": "entity-find-cursor",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent",
|
||||
"commandSucceededEvent",
|
||||
"commandFailedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "database0Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"databaseName": "database0Name",
|
||||
"collectionName": "coll0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
},
|
||||
{
|
||||
"_id": 3
|
||||
},
|
||||
{
|
||||
"_id": 4
|
||||
},
|
||||
{
|
||||
"_id": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "cursors can be created, iterated, and closed",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createFindCursor",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {},
|
||||
"batchSize": 2
|
||||
},
|
||||
"saveResultAsEntity": "cursor0"
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "cursor0",
|
||||
"expectResult": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "cursor0",
|
||||
"expectResult": {
|
||||
"_id": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "cursor0",
|
||||
"expectResult": {
|
||||
"_id": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "close",
|
||||
"object": "cursor0"
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"find": "coll0",
|
||||
"filter": {},
|
||||
"batchSize": 2
|
||||
},
|
||||
"commandName": "find",
|
||||
"databaseName": "database0Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"cursor": {
|
||||
"id": {
|
||||
"$$type": "long"
|
||||
},
|
||||
"ns": {
|
||||
"$$type": "string"
|
||||
},
|
||||
"firstBatch": {
|
||||
"$$type": "array"
|
||||
}
|
||||
}
|
||||
},
|
||||
"commandName": "find"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"getMore": {
|
||||
"$$type": "long"
|
||||
},
|
||||
"collection": "coll0"
|
||||
},
|
||||
"commandName": "getMore"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"cursor": {
|
||||
"id": {
|
||||
"$$type": "long"
|
||||
},
|
||||
"ns": {
|
||||
"$$type": "string"
|
||||
},
|
||||
"nextBatch": {
|
||||
"$$type": "array"
|
||||
}
|
||||
}
|
||||
},
|
||||
"commandName": "getMore"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"killCursors": "coll0",
|
||||
"cursors": {
|
||||
"$$type": "array"
|
||||
}
|
||||
},
|
||||
"commandName": "killCursors"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandSucceededEvent": {
|
||||
"reply": {
|
||||
"cursorsKilled": {
|
||||
"$$unsetOrMatches": {
|
||||
"$$type": "array"
|
||||
}
|
||||
}
|
||||
},
|
||||
"commandName": "killCursors"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
{
|
||||
"description": "expectedEventsForClient-eventType",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": true,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent",
|
||||
"connectionReadyEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "database0Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "database0Name",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "eventType can be set to command and cmap",
|
||||
"operations": [
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "command",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"insert": "coll0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"commandName": "insert"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionReadyEvent": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "eventType defaults to command if unset",
|
||||
"operations": [
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"insert": "coll0",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"commandName": "insert"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"client": "client0",
|
||||
"eventType": "cmap",
|
||||
"events": [
|
||||
{
|
||||
"connectionReadyEvent": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
{
|
||||
"description": "ignoreResultAndError",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "database0Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "database0Name",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "operation errors are ignored if ignoreResultAndError is true",
|
||||
"operations": [
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "insertOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"ignoreResultAndError": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -323,7 +323,8 @@
|
||||
"topologies": [
|
||||
"replicaset",
|
||||
"sharded-replicaset"
|
||||
]
|
||||
],
|
||||
"serverless": "forbid"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
|
||||
@ -250,7 +250,7 @@ class EntityMapUtil(object):
|
||||
ignore_commands = spec.get('ignoreCommandMonitoringEvents', [])
|
||||
observe_sensitive_commands = spec.get(
|
||||
'observeSensitiveCommands', False)
|
||||
# TODO: SUPPORT storeEventsAsEntities
|
||||
# TODO: PYTHON-2511 support storeEventsAsEntities
|
||||
if len(observe_events) or len(ignore_commands):
|
||||
ignore_commands = [cmd.lower() for cmd in ignore_commands]
|
||||
listener = EventListenerUtil(
|
||||
@ -409,8 +409,8 @@ class MatchEvaluatorUtil(object):
|
||||
t for alias in spec for t in self.__type_alias_to_type(alias)])
|
||||
else:
|
||||
permissible_types = self.__type_alias_to_type(spec)
|
||||
self.test.assertIsInstance(
|
||||
actual[key_to_compare], permissible_types)
|
||||
value = actual[key_to_compare] if key_to_compare else actual
|
||||
self.test.assertIsInstance(value, permissible_types)
|
||||
|
||||
def _operation_matchesEntity(self, spec, actual, key_to_compare):
|
||||
expected_entity = self.test.entity_map[spec]
|
||||
@ -822,6 +822,8 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
|
||||
def _collectionOperation_createFindCursor(self, target, *args, **kwargs):
|
||||
self.__raise_if_unsupported('find', target, Collection)
|
||||
if 'filter' not in kwargs:
|
||||
self.fail('createFindCursor requires a "filter" argument')
|
||||
cursor = NonLazyCursor(target.find(*args, **kwargs))
|
||||
self.addCleanup(cursor.close)
|
||||
return cursor
|
||||
@ -909,7 +911,9 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
try:
|
||||
result = cmd(**dict(arguments))
|
||||
except Exception as exc:
|
||||
if ignore:
|
||||
# Ignore all operation errors but to avoid masking bugs don't
|
||||
# ignore things like TypeError and ValueError.
|
||||
if ignore and isinstance(exc, (PyMongoError,)):
|
||||
return
|
||||
if expect_error:
|
||||
return self.process_error(exc, expect_error)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user