From 2cbdf324ab6c79ebf0bb4c0a98591cac1d752e46 Mon Sep 17 00:00:00 2001 From: Andreas Schildbach Date: Sat, 29 Mar 2014 10:26:57 +0100 Subject: [PATCH] Fix race of mock clock with current time if tests are all run sequentially. This commit requires you to use one of the setMockClock() variants before being able to roll it. --- .../src/main/java/com/google/bitcoin/core/Utils.java | 12 ++++++++++-- .../java/com/google/bitcoin/core/ChainSplitTest.java | 1 + .../bitcoin/core/TransactionBroadcastTest.java | 1 + .../protocols/channels/ChannelConnectionTest.java | 1 + .../protocols/channels/PaymentChannelStateTest.java | 12 ++++++------ .../bitcoin/wallet/DefaultCoinSelectorTest.java | 1 + 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/core/Utils.java b/core/src/main/java/com/google/bitcoin/core/Utils.java index bdb7f99a..b796b611 100644 --- a/core/src/main/java/com/google/bitcoin/core/Utils.java +++ b/core/src/main/java/com/google/bitcoin/core/Utils.java @@ -1,5 +1,6 @@ /** * Copyright 2011 Google Inc. + * Copyright 2014 Andreas Schildbach * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -460,13 +461,20 @@ public class Utils { */ public static Date rollMockClockMillis(long millis) { if (mockTime == null) - mockTime = new Date(); + throw new IllegalStateException("You need to use setMockClock() first."); mockTime = new Date(mockTime.getTime() + millis); return mockTime; } /** - * Sets the mock clock to the given time (in seconds) + * Sets the mock clock to the current time. + */ + public static void setMockClock() { + mockTime = new Date(); + } + + /** + * Sets the mock clock to the given time (in seconds). */ public static void setMockClock(long mockClock) { mockTime = new Date(mockClock * 1000); diff --git a/core/src/test/java/com/google/bitcoin/core/ChainSplitTest.java b/core/src/test/java/com/google/bitcoin/core/ChainSplitTest.java index 89e8c897..4a920353 100644 --- a/core/src/test/java/com/google/bitcoin/core/ChainSplitTest.java +++ b/core/src/test/java/com/google/bitcoin/core/ChainSplitTest.java @@ -52,6 +52,7 @@ public class ChainSplitTest { @Before public void setUp() throws Exception { BriefLogFormatter.init(); + Utils.setMockClock(); // Use mock clock Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO; unitTestParams = UnitTestParams.get(); wallet = new Wallet(unitTestParams); diff --git a/core/src/test/java/com/google/bitcoin/core/TransactionBroadcastTest.java b/core/src/test/java/com/google/bitcoin/core/TransactionBroadcastTest.java index e41f8547..aeeeada9 100644 --- a/core/src/test/java/com/google/bitcoin/core/TransactionBroadcastTest.java +++ b/core/src/test/java/com/google/bitcoin/core/TransactionBroadcastTest.java @@ -52,6 +52,7 @@ public class TransactionBroadcastTest extends TestWithPeerGroup { @Override @Before public void setUp() throws Exception { + Utils.setMockClock(); // Use mock clock super.setUp(new MemoryBlockStore(UnitTestParams.get())); peerGroup.addWallet(wallet); // Fix the random permutation that TransactionBroadcast uses to shuffle the peers. diff --git a/core/src/test/java/com/google/bitcoin/protocols/channels/ChannelConnectionTest.java b/core/src/test/java/com/google/bitcoin/protocols/channels/ChannelConnectionTest.java index 29e75b92..e97fde0e 100644 --- a/core/src/test/java/com/google/bitcoin/protocols/channels/ChannelConnectionTest.java +++ b/core/src/test/java/com/google/bitcoin/protocols/channels/ChannelConnectionTest.java @@ -63,6 +63,7 @@ public class ChannelConnectionTest extends TestWithWallet { @Before public void setUp() throws Exception { super.setUp(); + Utils.setMockClock(); // Use mock clock sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN); sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN); wallet.addExtension(new StoredPaymentChannelClientStates(wallet, failBroadcaster)); diff --git a/core/src/test/java/com/google/bitcoin/protocols/channels/PaymentChannelStateTest.java b/core/src/test/java/com/google/bitcoin/protocols/channels/PaymentChannelStateTest.java index 210e101b..3612ea76 100644 --- a/core/src/test/java/com/google/bitcoin/protocols/channels/PaymentChannelStateTest.java +++ b/core/src/test/java/com/google/bitcoin/protocols/channels/PaymentChannelStateTest.java @@ -114,7 +114,7 @@ public class PaymentChannelStateTest extends TestWithWallet { public void basic() throws Exception { // Check it all works when things are normal (no attacks, no problems). - Utils.rollMockClock(0); // Use mock clock + Utils.setMockClock(); // Use mock clock final long EXPIRE_TIME = Utils.currentTimeMillis()/1000 + 60*60*24; serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME); @@ -228,7 +228,7 @@ public class PaymentChannelStateTest extends TestWithWallet { StoredPaymentChannelClientStates stateStorage = new StoredPaymentChannelClientStates(wallet, mockBroadcaster); wallet.addOrUpdateExtension(stateStorage); - Utils.rollMockClock(0); // Use mock clock + Utils.setMockClock(); // Use mock clock final long EXPIRE_TIME = Utils.currentTimeMillis()/1000 + 60*60*24; serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME); @@ -330,7 +330,7 @@ public class PaymentChannelStateTest extends TestWithWallet { // We'll broadcast only one tx: multisig contract - Utils.rollMockClock(0); // Use mock clock + Utils.setMockClock(); // Use mock clock final long EXPIRE_TIME = Utils.currentTimeMillis()/1000 + 60*60*24; serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME); @@ -541,7 +541,7 @@ public class PaymentChannelStateTest extends TestWithWallet { chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), createFakeTx(params, Utils.CENT, myAddress))); assertEquals(Utils.CENT, wallet.getBalance()); - Utils.rollMockClock(0); // Use mock clock + Utils.setMockClock(); // Use mock clock final long EXPIRE_TIME = Utils.currentTimeMillis()/1000 + 60*60*24; serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME); @@ -644,7 +644,7 @@ public class PaymentChannelStateTest extends TestWithWallet { public void serverAddsFeeTest() throws Exception { // Test that the server properly adds the necessary fee at the end (or just drops the payment if its not worth it) - Utils.rollMockClock(0); // Use mock clock + Utils.setMockClock(); // Use mock clock final long EXPIRE_TIME = Utils.currentTimeMillis()/1000 + 60*60*24; serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME); @@ -730,7 +730,7 @@ public class PaymentChannelStateTest extends TestWithWallet { // Tests that if the client double-spends the multisig contract after it is sent, no more payments are accepted // Start with a copy of basic().... - Utils.rollMockClock(0); // Use mock clock + Utils.setMockClock(); // Use mock clock final long EXPIRE_TIME = Utils.currentTimeMillis()/1000 + 60*60*24; serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME); diff --git a/core/src/test/java/com/google/bitcoin/wallet/DefaultCoinSelectorTest.java b/core/src/test/java/com/google/bitcoin/wallet/DefaultCoinSelectorTest.java index 51a29fe1..cff9d6f3 100644 --- a/core/src/test/java/com/google/bitcoin/wallet/DefaultCoinSelectorTest.java +++ b/core/src/test/java/com/google/bitcoin/wallet/DefaultCoinSelectorTest.java @@ -39,6 +39,7 @@ public class DefaultCoinSelectorTest extends TestWithWallet { @Override public void setUp() throws Exception { super.setUp(); + Utils.setMockClock(); // Use mock clock } @After