|
52 | 52 | use Google\Cloud\Spanner\V1\SpannerClient; |
53 | 53 | use Google\Cloud\Spanner\V1\Transaction as TransactionProto; |
54 | 54 | use Google\Cloud\Spanner\V1\TransactionOptions; |
| 55 | +use Google\Cloud\Spanner\V1\TransactionOptions\ReadWrite\ReadLockMode as ReadLockMode; |
55 | 56 | use Google\Rpc\Code; |
56 | 57 | use PHPUnit\Framework\TestCase; |
57 | 58 | use Prophecy\Argument; |
@@ -2139,6 +2140,81 @@ public function testBatchWriteWithExcludeTxnFromChangeStreams() |
2139 | 2140 | ]); |
2140 | 2141 | } |
2141 | 2142 |
|
| 2143 | + public function testRunTransactionWithReadLockMode() |
| 2144 | + { |
| 2145 | + $expectedReadLockMode = ReadLockMode::OPTIMISTIC; |
| 2146 | + |
| 2147 | + $gapic = $this->prophesize(SpannerClient::class); |
| 2148 | + |
| 2149 | + $sessName = SpannerClient::sessionName(self::PROJECT, self::INSTANCE, self::DATABASE, self::SESSION); |
| 2150 | + $session = new SessionProto(['name' => $sessName]); |
| 2151 | + $resultSet = new ResultSet(['stats' => new ResultSetStats(['row_count_exact' => 0])]); |
| 2152 | + $gapic->createSession(Argument::cetera())->shouldBeCalled()->willReturn($session); |
| 2153 | + $gapic->deleteSession(Argument::cetera())->shouldBeCalled(); |
| 2154 | + |
| 2155 | + $sql = 'SELECT example FROM sql_query'; |
| 2156 | + $stream = $this->prophesize(ServerStream::class); |
| 2157 | + $stream->readAll()->shouldBeCalledOnce()->willReturn([$resultSet]); |
| 2158 | + $gapic->executeStreamingSql($sessName, $sql, Argument::that(function (array $options) use ($expectedReadLockMode) { |
| 2159 | + $this->assertArrayHasKey('transaction', $options); |
| 2160 | + $this->assertNotNull($transactionOptions = $options['transaction']->getBegin()); |
| 2161 | + $this->assertNotNull($readWriteTxnOptions = $transactionOptions->getReadWrite()); |
| 2162 | + $this->assertNotNull($readLockModeOption = $readWriteTxnOptions->getReadLockMode()); |
| 2163 | + $this->assertEquals($expectedReadLockMode, $readLockModeOption, "The read lock mode received was {$readLockModeOption} does not match expected {$expectedReadLockMode}"); |
| 2164 | + return true; |
| 2165 | + })) |
| 2166 | + ->shouldBeCalledOnce() |
| 2167 | + ->willReturn($stream->reveal()); |
| 2168 | + |
| 2169 | + $database = new Database( |
| 2170 | + new Grpc(['gapicSpannerClient' => $gapic->reveal()]), |
| 2171 | + $this->instance, |
| 2172 | + $this->lro->reveal(), |
| 2173 | + $this->lroCallables, |
| 2174 | + self::PROJECT, |
| 2175 | + self::DATABASE |
| 2176 | + ); |
| 2177 | + |
| 2178 | + // Test TransactionOption array format with base level property set for readLockMode |
| 2179 | + // This helps test proper formating by the library to the format expected by Spanner backend (i.e. readLockMode should be inside readWrite) |
| 2180 | + $database->runTransaction( |
| 2181 | + function (Transaction $t) use ($sql) { |
| 2182 | + // Run a fake query |
| 2183 | + $t->executeUpdate($sql); |
| 2184 | + |
| 2185 | + // Simulate calling Transaction::commmit() |
| 2186 | + $prop = new \ReflectionProperty($t, 'state'); |
| 2187 | + $prop->setAccessible(true); |
| 2188 | + $prop->setValue($t, Transaction::STATE_COMMITTED); |
| 2189 | + }, |
| 2190 | + ['transactionOptions' => ['readLockMode' => $expectedReadLockMode,] ] |
| 2191 | + ); |
| 2192 | + } |
| 2193 | + |
| 2194 | + public function testTransactionWithReadLockMode() |
| 2195 | + { |
| 2196 | + $expectedReadLockMode = ReadLockMode::OPTIMISTIC; |
| 2197 | + |
| 2198 | + $this->connection->beginTransaction( |
| 2199 | + Argument::that(function (array $args) use ($expectedReadLockMode) { |
| 2200 | + $this->assertArrayHasKey('transactionOptions', $args); |
| 2201 | + $this->assertArrayHasKey('readWrite', $args['transactionOptions']); |
| 2202 | + $this->assertArrayHasKey('readLockMode', $args['transactionOptions']['readWrite']); |
| 2203 | + $this->assertEquals( |
| 2204 | + $expectedReadLockMode, |
| 2205 | + $args['transactionOptions']['readWrite']['readLockMode'], |
| 2206 | + "The read lock mode received was {$args['transactionOptions']['readWrite']['readLockMode']} does not match expected {$expectedReadLockMode}" |
| 2207 | + ); |
| 2208 | + return true; |
| 2209 | + }) |
| 2210 | + ) |
| 2211 | + ->shouldBeCalled() |
| 2212 | + ->willReturn(['id' => self::TRANSACTION]); |
| 2213 | + |
| 2214 | + $t = $this->database->transaction(['transactionOptions' => ['readLockMode' => $expectedReadLockMode, ]]); |
| 2215 | + $this->assertInstanceOf(Transaction::class, $t); |
| 2216 | + } |
| 2217 | + |
2142 | 2218 | private function createStreamingAPIArgs() |
2143 | 2219 | { |
2144 | 2220 | $row = ['id' => 1]; |
|
0 commit comments