/driver-core/src/test/functional/com/mongodb/internal/connection/WriteProtocolCommandEventSpecification.groovy

https://github.com/jyemin/mongo-java-driver · Groovy · 229 lines · 178 code · 33 blank · 18 comment · 5 complexity · 4f173b5eb8df3d385f1ad6c1ce199b13 MD5 · raw file

  1. /*
  2. * Copyright 2008-present MongoDB, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.mongodb.internal.connection
  17. import com.mongodb.OperationFunctionalSpecification
  18. import com.mongodb.ReadPreference
  19. import com.mongodb.connection.ClusterConnectionMode
  20. import com.mongodb.connection.ClusterId
  21. import com.mongodb.connection.ServerId
  22. import com.mongodb.connection.SocketSettings
  23. import com.mongodb.connection.netty.NettyStreamFactory
  24. import com.mongodb.event.CommandStartedEvent
  25. import com.mongodb.event.CommandSucceededEvent
  26. import com.mongodb.internal.IgnorableRequestContext
  27. import com.mongodb.internal.bulk.DeleteRequest
  28. import com.mongodb.internal.bulk.InsertRequest
  29. import com.mongodb.internal.bulk.UpdateRequest
  30. import org.bson.BsonArray
  31. import org.bson.BsonBoolean
  32. import org.bson.BsonDocument
  33. import org.bson.BsonInt32
  34. import org.bson.BsonString
  35. import org.bson.codecs.BsonDocumentCodec
  36. import spock.lang.IgnoreIf
  37. import spock.lang.Shared
  38. import static com.mongodb.ClusterFixture.getCredentialWithCache
  39. import static com.mongodb.ClusterFixture.getPrimary
  40. import static com.mongodb.ClusterFixture.getServerApi
  41. import static com.mongodb.ClusterFixture.getSslSettings
  42. import static com.mongodb.ClusterFixture.serverVersionAtLeast
  43. import static com.mongodb.connection.ClusterConnectionMode.SINGLE
  44. import static com.mongodb.internal.bulk.WriteRequest.Type.REPLACE
  45. import static com.mongodb.internal.bulk.WriteRequest.Type.UPDATE
  46. import static com.mongodb.internal.connection.ProtocolTestHelper.execute
  47. @IgnoreIf({ serverVersionAtLeast(5, 1) })
  48. class WriteProtocolCommandEventSpecification extends OperationFunctionalSpecification {
  49. @Shared
  50. InternalStreamConnection connection
  51. def setupSpec() {
  52. connection = new InternalStreamConnectionFactory(SINGLE, new NettyStreamFactory(SocketSettings.builder().build(), getSslSettings()),
  53. getCredentialWithCache(), null, null, [], null, getServerApi())
  54. .create(new ServerId(new ClusterId(), getPrimary()))
  55. connection.open()
  56. }
  57. def cleanupSpec() {
  58. connection?.close()
  59. }
  60. def 'should deliver started and completed command events for a single unacknowledged insert'() {
  61. given:
  62. def document = new BsonDocument('_id', new BsonInt32(1))
  63. def insertRequest = new InsertRequest(document)
  64. def protocol = new InsertProtocol(getNamespace(), true, insertRequest, IgnorableRequestContext.INSTANCE)
  65. def commandListener = new TestCommandListener()
  66. protocol.commandListener = commandListener
  67. def expectedEvents = [
  68. new CommandStartedEvent(1, connection.getDescription(), getDatabaseName(), 'insert',
  69. new BsonDocument('insert', new BsonString(getCollectionName()))
  70. .append('ordered', BsonBoolean.TRUE)
  71. .append('writeConcern',
  72. new BsonDocument('w', new BsonInt32(0)))
  73. .append('documents', new BsonArray(
  74. [new BsonDocument('_id', new BsonInt32(1))]))),
  75. new CommandSucceededEvent(1, connection.getDescription(), 'insert',
  76. new BsonDocument('ok', new BsonInt32(1)), 0)]
  77. when:
  78. execute(protocol, connection, async)
  79. then:
  80. commandListener.eventsWereDelivered(expectedEvents)
  81. cleanup:
  82. // force acknowledgement
  83. new CommandProtocolImpl(getDatabaseName(), new BsonDocument('drop', new BsonString(getCollectionName())),
  84. NO_OP_FIELD_NAME_VALIDATOR, ReadPreference.primary(), new BsonDocumentCodec(), true, null, null,
  85. ClusterConnectionMode.MULTIPLE, getServerApi(), IgnorableRequestContext.INSTANCE)
  86. .sessionContext(NoOpSessionContext.INSTANCE)
  87. .execute(connection)
  88. where:
  89. async << [false, true]
  90. }
  91. def 'should deliver started and completed command events for a update'() {
  92. given:
  93. def filter = new BsonDocument('_id', new BsonInt32(1))
  94. def update = new BsonDocument('$set', new BsonDocument('x', new BsonInt32(1)))
  95. def updateRequest = new UpdateRequest(filter, update, UPDATE).multi(true).upsert(true)
  96. def protocol = new UpdateProtocol(getNamespace(), true, updateRequest, IgnorableRequestContext.INSTANCE)
  97. def commandListener = new TestCommandListener()
  98. protocol.commandListener = commandListener
  99. when:
  100. execute(protocol, connection, async)
  101. then:
  102. commandListener.eventsWereDelivered([new CommandStartedEvent(1, connection.getDescription(), getDatabaseName(), 'update',
  103. new BsonDocument('update', new BsonString(getCollectionName()))
  104. .append('ordered', BsonBoolean.TRUE)
  105. .append('writeConcern',
  106. new BsonDocument('w', new BsonInt32(0)))
  107. .append('updates', new BsonArray(
  108. [new BsonDocument('q', filter)
  109. .append('u', update)
  110. .append('multi', BsonBoolean.TRUE)
  111. .append('upsert', BsonBoolean.TRUE)]))),
  112. new CommandSucceededEvent(1, connection.getDescription(), 'update',
  113. new BsonDocument('ok', new BsonInt32(1)), 0)])
  114. cleanup:
  115. // force acknowledgement
  116. new CommandProtocolImpl(getDatabaseName(), new BsonDocument('drop', new BsonString(getCollectionName())),
  117. NO_OP_FIELD_NAME_VALIDATOR, ReadPreference.primary(), new BsonDocumentCodec(), true, null, null,
  118. ClusterConnectionMode.MULTIPLE, getServerApi(), IgnorableRequestContext.INSTANCE)
  119. .sessionContext(NoOpSessionContext.INSTANCE)
  120. .execute(connection)
  121. where:
  122. async << [false, true]
  123. }
  124. def 'should deliver started and completed command events for a replace'() {
  125. given:
  126. def filter = new BsonDocument('_id', new BsonInt32(1))
  127. def update = new BsonDocument('x', new BsonInt32(1))
  128. def updateRequest = new UpdateRequest(filter, update, REPLACE).multi(false).upsert(true)
  129. def protocol = new UpdateProtocol(getNamespace(), true, updateRequest, IgnorableRequestContext.INSTANCE)
  130. def commandListener = new TestCommandListener()
  131. protocol.commandListener = commandListener
  132. when:
  133. execute(protocol, connection, async)
  134. then:
  135. commandListener.eventsWereDelivered([new CommandStartedEvent(1, connection.getDescription(), getDatabaseName(), 'update',
  136. new BsonDocument('update', new BsonString(getCollectionName()))
  137. .append('ordered', BsonBoolean.TRUE)
  138. .append('writeConcern',
  139. new BsonDocument('w', new BsonInt32(0)))
  140. .append('updates', new BsonArray(
  141. [new BsonDocument('q', filter)
  142. .append('u', update)
  143. .append('upsert', BsonBoolean.TRUE)]))),
  144. new CommandSucceededEvent(1, connection.getDescription(), 'update',
  145. new BsonDocument('ok', new BsonInt32(1)), 0)])
  146. cleanup:
  147. // force acknowledgement
  148. new CommandProtocolImpl(getDatabaseName(), new BsonDocument('drop', new BsonString(getCollectionName())),
  149. NO_OP_FIELD_NAME_VALIDATOR, ReadPreference.primary(), new BsonDocumentCodec(), true, null, null,
  150. ClusterConnectionMode.MULTIPLE, getServerApi(), IgnorableRequestContext.INSTANCE)
  151. .sessionContext(NoOpSessionContext.INSTANCE)
  152. .execute(connection)
  153. where:
  154. async << [false, true]
  155. }
  156. def 'should deliver started and completed command events for a delete'() {
  157. given:
  158. def filter = new BsonDocument('_id', new BsonInt32(1))
  159. def deleteRequest = new DeleteRequest(filter).multi(true)
  160. def protocol = new DeleteProtocol(getNamespace(), true, deleteRequest, IgnorableRequestContext.INSTANCE)
  161. def commandListener = new TestCommandListener()
  162. protocol.commandListener = commandListener
  163. def expectedEvents = [
  164. new CommandStartedEvent(1, connection.getDescription(), getDatabaseName(), 'delete',
  165. new BsonDocument('delete', new BsonString(getCollectionName()))
  166. .append('ordered', BsonBoolean.TRUE)
  167. .append('writeConcern',
  168. new BsonDocument('w', new BsonInt32(0)))
  169. .append('deletes', new BsonArray(
  170. [new BsonDocument('q', filter)
  171. .append('limit', new BsonInt32(0))]))),
  172. new CommandSucceededEvent(1, connection.getDescription(), 'delete',
  173. new BsonDocument('ok', new BsonInt32(1)), 0)]
  174. when:
  175. execute(protocol, connection, async)
  176. then:
  177. commandListener.eventsWereDelivered(expectedEvents)
  178. where:
  179. async << [false, true]
  180. }
  181. def 'should not deliver any events if encoding fails'() {
  182. given:
  183. def updateRequest = new UpdateRequest(new BsonDocument(), new BsonDocument('$set', new BsonInt32(1)), REPLACE)
  184. def protocol = new UpdateProtocol(getNamespace(), true, updateRequest, IgnorableRequestContext.INSTANCE)
  185. def commandListener = new TestCommandListener()
  186. protocol.commandListener = commandListener
  187. def expectedEvents = []
  188. when:
  189. execute(protocol, connection, async)
  190. then:
  191. thrown(IllegalArgumentException)
  192. commandListener.eventsWereDelivered(expectedEvents)
  193. where:
  194. async << [false, true]
  195. }
  196. }