Skip to content

Commit 037be8c

Browse files
MakarovSdmitry-timofeev
authored andcommitted
Add TestKit#getSnapshot [ECR-3216] (#972)
Add TestKit#getSnapshot for most common cases when only several snapshots are created and can be removed when testkit is closed. Make TestKit#withSnapshot accept Consumer<Snapshot> as a parameter, and add TestKit#applySnapshot. These methods remain for (rare) usages that require a large number of snapshots or native proxies and cannot rely on de-allocation on Testkit#close.
1 parent e6f7206 commit 037be8c

15 files changed

Lines changed: 301 additions & 283 deletions

File tree

exonum-java-binding/cryptocurrency-demo/src/test/java/com/exonum/binding/cryptocurrency/CryptocurrencySchemaIntegrationTest.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import com.exonum.binding.common.crypto.PublicKey;
2222
import com.exonum.binding.common.hash.HashCode;
23+
import com.exonum.binding.core.storage.database.Snapshot;
2324
import com.exonum.binding.test.RequiresNativeLibrary;
2425
import com.exonum.binding.testkit.TestKit;
2526
import com.exonum.binding.testkit.TestKitExtension;
@@ -40,24 +41,20 @@ class CryptocurrencySchemaIntegrationTest {
4041

4142
@Test
4243
void getStateHashes(TestKit testKit) {
43-
testKit.withSnapshot((view) -> {
44-
CryptocurrencySchema schema = new CryptocurrencySchema(view);
44+
Snapshot view = testKit.getSnapshot();
45+
CryptocurrencySchema schema = new CryptocurrencySchema(view);
4546

46-
HashCode walletsMerkleRoot = schema.wallets().getRootHash();
47-
ImmutableList<HashCode> expectedHashes = ImmutableList.of(walletsMerkleRoot);
47+
HashCode walletsMerkleRoot = schema.wallets().getRootHash();
48+
ImmutableList<HashCode> expectedHashes = ImmutableList.of(walletsMerkleRoot);
4849

49-
assertThat(schema.getStateHashes()).isEqualTo(expectedHashes);
50-
return null;
51-
});
50+
assertThat(schema.getStateHashes()).isEqualTo(expectedHashes);
5251
}
5352

5453
@Test
5554
void walletHistoryNoRecords(TestKit testKit) {
56-
testKit.withSnapshot((view) -> {
57-
CryptocurrencySchema schema = new CryptocurrencySchema(view);
55+
Snapshot view = testKit.getSnapshot();
56+
CryptocurrencySchema schema = new CryptocurrencySchema(view);
5857

59-
assertThat(schema.transactionsHistory(WALLET_OWNER_KEY)).isEmpty();
60-
return null;
61-
});
58+
assertThat(schema.transactionsHistory(WALLET_OWNER_KEY)).isEmpty();
6259
}
6360
}

exonum-java-binding/cryptocurrency-demo/src/test/java/com/exonum/binding/cryptocurrency/transactions/CreateWalletTxTest.java

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.exonum.binding.common.crypto.PublicKey;
3030
import com.exonum.binding.common.message.TransactionMessage;
3131
import com.exonum.binding.core.blockchain.Blockchain;
32+
import com.exonum.binding.core.storage.database.Snapshot;
3233
import com.exonum.binding.core.storage.indices.MapIndex;
3334
import com.exonum.binding.core.transaction.RawTransaction;
3435
import com.exonum.binding.cryptocurrency.CryptocurrencySchema;
@@ -79,17 +80,15 @@ void executeCreateWalletTx(TestKit testKit) {
7980
newCreateWalletTransaction(DEFAULT_INITIAL_BALANCE, OWNER_KEY_PAIR);
8081
testKit.createBlockWithTransactions(transactionMessage);
8182

82-
testKit.withSnapshot((view) -> {
83-
// Check that entries have been added
84-
CryptocurrencySchema schema = new CryptocurrencySchema(view);
85-
MapIndex<PublicKey, Wallet> wallets = schema.wallets();
86-
87-
PublicKey emulatedNodePublicKey = OWNER_KEY_PAIR.getPublicKey();
88-
assertThat(wallets.containsKey(emulatedNodePublicKey)).isTrue();
89-
assertThat(wallets.get(emulatedNodePublicKey).getBalance())
90-
.isEqualTo(DEFAULT_INITIAL_BALANCE);
91-
return null;
92-
});
83+
// Check that entries have been added
84+
Snapshot view = testKit.getSnapshot();
85+
CryptocurrencySchema schema = new CryptocurrencySchema(view);
86+
MapIndex<PublicKey, Wallet> wallets = schema.wallets();
87+
88+
PublicKey emulatedNodePublicKey = OWNER_KEY_PAIR.getPublicKey();
89+
assertThat(wallets.containsKey(emulatedNodePublicKey)).isTrue();
90+
assertThat(wallets.get(emulatedNodePublicKey).getBalance())
91+
.isEqualTo(DEFAULT_INITIAL_BALANCE);
9392
}
9493

9594
@Test
@@ -107,14 +106,12 @@ void executeAlreadyExistingWalletTx(TestKit testKit) {
107106
testKit.createBlockWithTransactions(transactionMessage2);
108107

109108
// Check that the second tx has failed
110-
testKit.withSnapshot((view) -> {
111-
Blockchain blockchain = Blockchain.newInstance(view);
112-
Optional<TransactionResult> txResult = blockchain.getTxResult(transactionMessage2.hash());
113-
TransactionResult expectedTransactionResult =
114-
TransactionResult.error(WALLET_ALREADY_EXISTS.errorCode, null);
115-
assertThat(txResult).hasValue(expectedTransactionResult);
116-
return null;
117-
});
109+
Snapshot view = testKit.getSnapshot();
110+
Blockchain blockchain = Blockchain.newInstance(view);
111+
Optional<TransactionResult> txResult = blockchain.getTxResult(transactionMessage2.hash());
112+
TransactionResult expectedTransactionResult =
113+
TransactionResult.error(WALLET_ALREADY_EXISTS.errorCode, null);
114+
assertThat(txResult).hasValue(expectedTransactionResult);
118115
}
119116

120117
@Test

exonum-java-binding/cryptocurrency-demo/src/test/java/com/exonum/binding/cryptocurrency/transactions/TransferTxHistoryTest.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.exonum.binding.common.crypto.PublicKey;
2626
import com.exonum.binding.common.hash.HashCode;
2727
import com.exonum.binding.common.message.TransactionMessage;
28+
import com.exonum.binding.core.storage.database.Snapshot;
2829
import com.exonum.binding.core.storage.indices.ProofMapIndexProxy;
2930
import com.exonum.binding.cryptocurrency.CryptocurrencySchema;
3031
import com.exonum.binding.cryptocurrency.CryptocurrencyServiceModule;
@@ -72,25 +73,24 @@ void transfersHistoryBetweenTwoAccountsTest(TestKit testKit) {
7273
seed2, ACCOUNT_2, ACCOUNT_1.getPublicKey(), transferSum2);
7374
testKit.createBlockWithTransactions(transferTx2);
7475

75-
testKit.withSnapshot((view) -> {
76-
// Check that wallets have correct balances
77-
CryptocurrencySchema schema = new CryptocurrencySchema(view);
78-
ProofMapIndexProxy<PublicKey, Wallet> wallets = schema.wallets();
79-
long expectedBalance1 = initialBalance - transferSum1 + transferSum2;
80-
assertThat(wallets.get(ACCOUNT_1.getPublicKey()).getBalance())
81-
.isEqualTo(expectedBalance1);
82-
long expectedBalance2 = initialBalance + transferSum1 - transferSum2;
83-
assertThat(wallets.get(ACCOUNT_2.getPublicKey()).getBalance())
84-
.isEqualTo(expectedBalance2);
76+
Snapshot view = testKit.getSnapshot();
8577

86-
// Check history
87-
HashCode messageHash1 = transferTx1.hash();
88-
HashCode messageHash2 = transferTx2.hash();
89-
assertThat(schema.transactionsHistory(ACCOUNT_1.getPublicKey()))
90-
.containsExactly(messageHash1, messageHash2);
91-
assertThat(schema.transactionsHistory(ACCOUNT_2.getPublicKey()))
92-
.containsExactly(messageHash1, messageHash2);
93-
return null;
94-
});
78+
// Check that wallets have correct balances
79+
CryptocurrencySchema schema = new CryptocurrencySchema(view);
80+
ProofMapIndexProxy<PublicKey, Wallet> wallets = schema.wallets();
81+
long expectedBalance1 = initialBalance - transferSum1 + transferSum2;
82+
assertThat(wallets.get(ACCOUNT_1.getPublicKey()).getBalance())
83+
.isEqualTo(expectedBalance1);
84+
long expectedBalance2 = initialBalance + transferSum1 - transferSum2;
85+
assertThat(wallets.get(ACCOUNT_2.getPublicKey()).getBalance())
86+
.isEqualTo(expectedBalance2);
87+
88+
// Check history
89+
HashCode messageHash1 = transferTx1.hash();
90+
HashCode messageHash2 = transferTx2.hash();
91+
assertThat(schema.transactionsHistory(ACCOUNT_1.getPublicKey()))
92+
.containsExactly(messageHash1, messageHash2);
93+
assertThat(schema.transactionsHistory(ACCOUNT_2.getPublicKey()))
94+
.containsExactly(messageHash1, messageHash2);
9595
}
9696
}

exonum-java-binding/cryptocurrency-demo/src/test/java/com/exonum/binding/cryptocurrency/transactions/TransferTxTest.java

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.exonum.binding.common.hash.HashCode;
3434
import com.exonum.binding.common.message.TransactionMessage;
3535
import com.exonum.binding.core.blockchain.Blockchain;
36+
import com.exonum.binding.core.storage.database.Snapshot;
3637
import com.exonum.binding.core.storage.indices.ProofMapIndexProxy;
3738
import com.exonum.binding.core.transaction.RawTransaction;
3839
import com.exonum.binding.core.transaction.Transaction;
@@ -110,25 +111,24 @@ void executeTransfer(TestKit testKit) {
110111
seed, FROM_KEY_PAIR, TO_KEY_PAIR.getPublicKey(), transferSum);
111112
testKit.createBlockWithTransactions(transferTx);
112113

113-
testKit.withSnapshot((view) -> {
114-
// Check that wallets have correct balances
115-
CryptocurrencySchema schema = new CryptocurrencySchema(view);
116-
ProofMapIndexProxy<PublicKey, Wallet> wallets = schema.wallets();
117-
long expectedFromValue = initialBalance - transferSum;
118-
assertThat(wallets.get(FROM_KEY_PAIR.getPublicKey()).getBalance())
119-
.isEqualTo(expectedFromValue);
120-
long expectedToValue = initialBalance + transferSum;
121-
assertThat(wallets.get(TO_KEY_PAIR.getPublicKey()).getBalance())
122-
.isEqualTo(expectedToValue);
123-
124-
// Check history
125-
HashCode messageHash = transferTx.hash();
126-
assertThat(schema.transactionsHistory(FROM_KEY_PAIR.getPublicKey()))
127-
.containsExactly(messageHash);
128-
assertThat(schema.transactionsHistory(TO_KEY_PAIR.getPublicKey()))
129-
.containsExactly(messageHash);
130-
return null;
131-
});
114+
Snapshot view = testKit.getSnapshot();
115+
116+
// Check that wallets have correct balances
117+
CryptocurrencySchema schema = new CryptocurrencySchema(view);
118+
ProofMapIndexProxy<PublicKey, Wallet> wallets = schema.wallets();
119+
long expectedFromValue = initialBalance - transferSum;
120+
assertThat(wallets.get(FROM_KEY_PAIR.getPublicKey()).getBalance())
121+
.isEqualTo(expectedFromValue);
122+
long expectedToValue = initialBalance + transferSum;
123+
assertThat(wallets.get(TO_KEY_PAIR.getPublicKey()).getBalance())
124+
.isEqualTo(expectedToValue);
125+
126+
// Check history
127+
HashCode messageHash = transferTx.hash();
128+
assertThat(schema.transactionsHistory(FROM_KEY_PAIR.getPublicKey()))
129+
.containsExactly(messageHash);
130+
assertThat(schema.transactionsHistory(TO_KEY_PAIR.getPublicKey()))
131+
.containsExactly(messageHash);
132132
}
133133

134134
@Test
@@ -146,14 +146,12 @@ void executeTransfer_NoSuchFromWallet(TestKit testKit) {
146146
seed, FROM_KEY_PAIR, TO_KEY_PAIR.getPublicKey(), transferSum);
147147
testKit.createBlockWithTransactions(transferTx);
148148

149-
testKit.withSnapshot((view) -> {
150-
Blockchain blockchain = Blockchain.newInstance(view);
151-
Optional<TransactionResult> txResult = blockchain.getTxResult(transferTx.hash());
152-
TransactionResult expectedTransactionResult =
153-
TransactionResult.error(UNKNOWN_SENDER.errorCode, null);
154-
assertThat(txResult).hasValue(expectedTransactionResult);
155-
return null;
156-
});
149+
Snapshot view = testKit.getSnapshot();
150+
Blockchain blockchain = Blockchain.newInstance(view);
151+
Optional<TransactionResult> txResult = blockchain.getTxResult(transferTx.hash());
152+
TransactionResult expectedTransactionResult =
153+
TransactionResult.error(UNKNOWN_SENDER.errorCode, null);
154+
assertThat(txResult).hasValue(expectedTransactionResult);
157155
}
158156

159157
@Test
@@ -171,14 +169,12 @@ void executeTransfer_NoSuchToWallet(TestKit testKit) {
171169
seed, FROM_KEY_PAIR, TO_KEY_PAIR.getPublicKey(), transferSum);
172170
testKit.createBlockWithTransactions(transferTx);
173171

174-
testKit.withSnapshot((view) -> {
175-
Blockchain blockchain = Blockchain.newInstance(view);
176-
Optional<TransactionResult> txResult = blockchain.getTxResult(transferTx.hash());
177-
TransactionResult expectedTransactionResult =
178-
TransactionResult.error(UNKNOWN_RECEIVER.errorCode, null);
179-
assertThat(txResult).hasValue(expectedTransactionResult);
180-
return null;
181-
});
172+
Snapshot view = testKit.getSnapshot();
173+
Blockchain blockchain = Blockchain.newInstance(view);
174+
Optional<TransactionResult> txResult = blockchain.getTxResult(transferTx.hash());
175+
TransactionResult expectedTransactionResult =
176+
TransactionResult.error(UNKNOWN_RECEIVER.errorCode, null);
177+
assertThat(txResult).hasValue(expectedTransactionResult);
182178
}
183179

184180
@Test
@@ -190,14 +186,12 @@ void executeTransfer_RejectsSameSenderAndReceiver(TestKit testKit) {
190186
seed, FROM_KEY_PAIR, FROM_KEY_PAIR.getPublicKey(), transferSum);
191187
testKit.createBlockWithTransactions(transferTx);
192188

193-
testKit.withSnapshot((view) -> {
194-
Blockchain blockchain = Blockchain.newInstance(view);
195-
Optional<TransactionResult> txResult = blockchain.getTxResult(transferTx.hash());
196-
TransactionResult expectedTransactionResult =
197-
TransactionResult.error(SAME_SENDER_AND_RECEIVER.errorCode, null);
198-
assertThat(txResult).hasValue(expectedTransactionResult);
199-
return null;
200-
});
189+
Snapshot view = testKit.getSnapshot();
190+
Blockchain blockchain = Blockchain.newInstance(view);
191+
Optional<TransactionResult> txResult = blockchain.getTxResult(transferTx.hash());
192+
TransactionResult expectedTransactionResult =
193+
TransactionResult.error(SAME_SENDER_AND_RECEIVER.errorCode, null);
194+
assertThat(txResult).hasValue(expectedTransactionResult);
201195
}
202196

203197
@Test
@@ -219,14 +213,12 @@ void executeTransfer_InsufficientFunds(TestKit testKit) {
219213
seed, FROM_KEY_PAIR, TO_KEY_PAIR.getPublicKey(), transferSum);
220214
testKit.createBlockWithTransactions(transferTx);
221215

222-
testKit.withSnapshot((view) -> {
223-
Blockchain blockchain = Blockchain.newInstance(view);
224-
Optional<TransactionResult> txResult = blockchain.getTxResult(transferTx.hash());
225-
TransactionResult expectedTransactionResult =
226-
TransactionResult.error(INSUFFICIENT_FUNDS.errorCode, null);
227-
assertThat(txResult).hasValue(expectedTransactionResult);
228-
return null;
229-
});
216+
Snapshot view = testKit.getSnapshot();
217+
Blockchain blockchain = Blockchain.newInstance(view);
218+
Optional<TransactionResult> txResult = blockchain.getTxResult(transferTx.hash());
219+
TransactionResult expectedTransactionResult =
220+
TransactionResult.error(INSUFFICIENT_FUNDS.errorCode, null);
221+
assertThat(txResult).hasValue(expectedTransactionResult);
230222
}
231223

232224
@Test

exonum-java-binding/integration-tests/src/test/java/com/exonum/binding/test/BlockchainIntegrationTest.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.exonum.binding.common.message.TransactionMessage;
3838
import com.exonum.binding.core.blockchain.Block;
3939
import com.exonum.binding.core.blockchain.Blockchain;
40+
import com.exonum.binding.core.storage.database.Snapshot;
4041
import com.exonum.binding.core.storage.indices.KeySetIndexProxy;
4142
import com.exonum.binding.core.storage.indices.MapIndex;
4243
import com.exonum.binding.core.storage.indices.ProofMapIndexProxy;
@@ -134,9 +135,7 @@ void commitBlock() {
134135

135136
@Test
136137
void containsBlock() {
137-
testKitTest((blockchain) -> {
138-
assertThat(blockchain.containsBlock(block)).isTrue();
139-
});
138+
testKitTest((blockchain) -> assertThat(blockchain.containsBlock(block)).isTrue());
140139
}
141140

142141
@Test
@@ -426,12 +425,9 @@ void getTransactionPool() {
426425
}
427426

428427
private void testKitTest(Consumer<Blockchain> test) {
429-
testKit.withSnapshot((view) -> {
430-
Blockchain blockchain = Blockchain.newInstance(view);
431-
test.accept(blockchain);
432-
433-
return null;
434-
});
428+
Snapshot view = testKit.getSnapshot();
429+
Blockchain blockchain = Blockchain.newInstance(view);
430+
test.accept(blockchain);
435431
}
436432

437433
private static void assertGenesisBlock(Block actualBlock) {

exonum-java-binding/integration-tests/src/test/java/com/exonum/binding/test/TimeSchemaProxyIntegrationTest.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.assertj.core.api.Assertions.assertThat;
2020

2121
import com.exonum.binding.common.crypto.PublicKey;
22+
import com.exonum.binding.core.storage.database.Snapshot;
2223
import com.exonum.binding.core.storage.indices.MapIndex;
2324
import com.exonum.binding.testkit.EmulatedNode;
2425
import com.exonum.binding.testkit.FakeTimeProvider;
@@ -96,12 +97,9 @@ private void setUpConsolidatedTime() {
9697
}
9798

9899
private void testKitTest(Consumer<TimeSchema> test) {
99-
testKit.withSnapshot((view) -> {
100-
TimeSchema timeSchema = TimeSchema.newInstance(view);
101-
test.accept(timeSchema);
102-
103-
return null;
104-
});
100+
Snapshot view = testKit.getSnapshot();
101+
TimeSchema timeSchema = TimeSchema.newInstance(view);
102+
test.accept(timeSchema);
105103
}
106104

107105
private <K, V> Map<K, V> toMap(MapIndex<K, V> mapIndex) {

exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/QaSchemaIntegrationTest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.assertj.core.api.Assertions.assertThat;
2020

2121
import com.exonum.binding.common.hash.HashCode;
22+
import com.exonum.binding.core.storage.database.Snapshot;
2223
import com.exonum.binding.test.RequiresNativeLibrary;
2324
import com.exonum.binding.testkit.TestKit;
2425
import com.exonum.binding.testkit.TestKitExtension;
@@ -36,16 +37,14 @@ class QaSchemaIntegrationTest {
3637

3738
@Test
3839
void getStateHashesEmptyDb(TestKit testKit) {
39-
testKit.withSnapshot((view) -> {
40-
QaSchema schema = new QaSchema(view);
40+
Snapshot view = testKit.getSnapshot();
41+
QaSchema schema = new QaSchema(view);
4142

42-
List<HashCode> stateHashes = schema.getStateHashes();
43+
List<HashCode> stateHashes = schema.getStateHashes();
4344

44-
assertThat(stateHashes).hasSize(1);
45+
assertThat(stateHashes).hasSize(1);
4546

46-
HashCode countersRootHash = schema.counters().getRootHash();
47-
assertThat(stateHashes.get(0)).isEqualTo(countersRootHash);
48-
return null;
49-
});
47+
HashCode countersRootHash = schema.counters().getRootHash();
48+
assertThat(stateHashes.get(0)).isEqualTo(countersRootHash);
5049
}
5150
}

0 commit comments

Comments
 (0)