Skip to content

Commit

Permalink
add integration test for the 'forceResync' endpoint
Browse files Browse the repository at this point in the history
Doesn't pass currently because of the in-memory sqlite implementation.
It works like a charm with the file database though:

```
(Right before making the request, observe the thread id #142)
[cardano-wallet.wallet-engine:Info:142] [2020-01-15 10:38:04.54 UTC] bdb212cc: In sync with the node.

(Upon receiving the request)
[cardano-wallet.api-server:Info:526] [2020-01-15 10:38:04.97 UTC] [RequestId 10] [DELETE] /v2/wallets/bdb212ccd1d556b62a59f4a4a1de0cff29f61ac1/utxos

(Turning off the worker, rolling back, and switching the worker back on)
[cardano-wallet.wallet-engine:Info:142] [2020-01-15 10:38:04.97 UTC] bdb212cc: Worker has exited: main action is over.
[cardano-wallet.wallet-engine:Info:526] [2020-01-15 10:38:04.98 UTC] bdb212cc: Try rolling back to 0.0
[cardano-wallet.wallet-engine:Info:526] [2020-01-15 10:38:05.00 UTC] bdb212cc: Rolled back to 0.0

(Responding to the request)
[cardano-wallet.api-server:Info:526] [2020-01-15 10:38:05.01 UTC] [RequestId 10] 204 No Content in 0.044038928s

(And later, the worker restarted, applying blocks from the start, new thread id #528).
[cardano-wallet.wallet-engine:Info:528] [2020-01-15 10:38:05.03 UTC] bdb212cc: Applying blocks [1136063.1 ... 1144130.1]
[cardano-wallet.wallet-engine:Info:528] [2020-01-15 10:38:05.03 UTC] bdb212cc: Creating checkpoint at feb1b2c2-[1136063.1#1]
[cardano-wallet.wallet-engine:Info:528] [2020-01-15 10:38:05.04 UTC] bdb212cc: Creating checkpoint at 8920cbb4-[1136063.2#2]
[cardano-wallet.wallet-engine:Info:528] [2020-01-15 10:38:05.04 UTC] bdb212cc: Creating checkpoint at 73a21e9f-[1136063.3#3]

[...]

(Eventually, reaches the tip)
[cardano-wallet.wallet-engine:Info:528] [2020-01-15 10:38:05.18 UTC] bdb212cc: MyWallet, created at 2020-01-15 10:35:28.24351865 UTC, not delegating
[cardano-wallet.wallet-engine:Info:528] [2020-01-15 10:38:05.18 UTC] bdb212cc: syncProgress: restored
[cardano-wallet.wallet-engine:Info:528] [2020-01-15 10:38:05.18 UTC] bdb212cc: discovered 0 new transaction(s)
[cardano-wallet.wallet-engine:Info:528] [2020-01-15 10:38:05.18 UTC] bdb212cc: local tip: 8b9aba60-[1144130.1#100]
```
  • Loading branch information
KtorZ committed Jan 15, 2020
1 parent 8f2b197 commit 7d3e281
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ module Test.Integration.Framework.TestData
, errMsg500
, errMsg400NumberOfWords
, errMsgNotInDictionary
, errMsg403RejectedTip
) where

import Prelude
Expand Down Expand Up @@ -480,3 +481,9 @@ errMsgNotInDictionary = "Found an unknown word not present in the pre-defined\

errMsg400NumberOfWords :: String
errMsg400NumberOfWords = "Invalid number of words:"

errMsg403RejectedTip :: String
errMsg403RejectedTip =
"I am sorry but I refuse to rollback to the given point. \
\Notwithstanding I'll willingly rollback to the genesis point (0, 0) \
\should you demand it."
114 changes: 114 additions & 0 deletions lib/core-integration/src/Test/Integration/Scenario/API/Wallets.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE QuasiQuotes #-}
Expand All @@ -13,6 +15,8 @@ module Test.Integration.Scenario.API.Wallets

import Prelude

import Cardano.Wallet.Api.Link
( Discriminate )
import Cardano.Wallet.Api.Types
( AddressAmount (..)
, ApiCoinSelection
Expand All @@ -29,13 +33,20 @@ import Cardano.Wallet.Primitive.Mnemonic
import Cardano.Wallet.Primitive.Types
( SyncProgress (..)
, WalletDelegation (..)
, WalletId
, walletNameMaxLength
, walletNameMinLength
)
import Control.Monad
( forM_ )
import Data.Aeson
( FromJSON )
import Data.Generics.Internal.VL.Lens
( view, (^.) )
import Data.Generics.Product.Fields
( HasField' )
import Data.Generics.Product.Typed
( HasType )
import Data.List.NonEmpty
( NonEmpty ((:|)) )
import Data.Quantity
Expand All @@ -44,6 +55,8 @@ import Data.Text
( Text )
import Data.Text.Class
( toText )
import GHC.Generics
( Generic )
import Numeric.Natural
( Natural )
import Test.Hspec
Expand All @@ -59,8 +72,10 @@ import Test.Integration.Framework.DSL
, coinSelectionInputs
, coinSelectionOutputs
, delegation
, emptyIcarusWallet
, emptyRandomWallet
, emptyWallet
, eventually
, expectErrorMessage
, expectEventually
, expectFieldEqual
Expand Down Expand Up @@ -93,6 +108,7 @@ import Test.Integration.Framework.TestData
, chineseMnemonics18
, chineseMnemonics9
, errMsg400ParseError
, errMsg403RejectedTip
, errMsg403WrongPass
, errMsg404NoEndpoint
, errMsg404NoWallet
Expand Down Expand Up @@ -1779,3 +1795,101 @@ spec = do
ru <- request @ApiWallet ctx ("GET", endpoint) Default newName
expectResponseCode @IO HTTP.status404 ru
expectErrorMessage (errMsg404NoWallet wid) ru

describe "WALLETS_RESYNC_01" $ do
scenarioWalletResync01_happyPath @'Shelley emptyWallet
scenarioWalletResync01_happyPath @'Byron emptyRandomWallet
scenarioWalletResync01_happyPath @'Byron emptyIcarusWallet

describe "WALLETS_RESYNC_02" $ do
scenarioWalletResync02_notGenesis @'Shelley emptyWallet
scenarioWalletResync02_notGenesis @'Byron emptyRandomWallet
scenarioWalletResync02_notGenesis @'Byron emptyIcarusWallet

describe "WALLETS_RESYNC_03" $ do
scenarioWalletResync03_invalidPayload @'Shelley emptyWallet
scenarioWalletResync03_invalidPayload @'Byron emptyRandomWallet
scenarioWalletResync03_invalidPayload @'Byron emptyIcarusWallet


-- force resync eventually get us back to the same point
scenarioWalletResync01_happyPath
:: forall style t n wallet.
( n ~ 'Testnet
, Discriminate style
, HasType (ApiT WalletId) wallet
, HasField' "state" wallet (ApiT SyncProgress)
, FromJSON wallet
, Generic wallet
, Show wallet
)
=> (Context t -> IO wallet)
-> SpecWith (Context t)
scenarioWalletResync01_happyPath fixture = it
"force resync eventually get us back to the same point" $ \ctx -> do
w <- fixture ctx

-- 1. Wait for wallet to be synced
eventually $ do
v <- request @wallet ctx (Link.getWallet @style w) Default Empty
verify v [ expectFieldSatisfy @IO #state (== (ApiT Ready)) ]

-- 2. Force a resync
let payload = Json [json|{ "epoch_number": 0, "slot_number": 0 }|]
r <- request @wallet ctx (Link.forceResyncWallet @style w) Default payload
verify r [ expectResponseCode @IO HTTP.status204 ]

-- 3. The wallet eventually re-sync
eventually $ do
v <- request @wallet ctx (Link.getWallet @style w) Default Empty
verify v [ expectFieldSatisfy @IO #state (== (ApiT Ready)) ]

-- force resync eventually get us back to the same point
scenarioWalletResync02_notGenesis
:: forall style t n wallet.
( n ~ 'Testnet
, Discriminate style
, HasType (ApiT WalletId) wallet
, HasField' "state" wallet (ApiT SyncProgress)
, FromJSON wallet
, Generic wallet
, Show wallet
)
=> (Context t -> IO wallet)
-> SpecWith (Context t)
scenarioWalletResync02_notGenesis fixture = it
"given point is not genesis (i.e. (0, 0))" $ \ctx -> do
w <- fixture ctx

-- 1. Force a resync on an invalid point (/= from genesis)
let payload = Json [json|{ "epoch_number": 14, "slot_number": 42 }|]
r <- request @wallet ctx (Link.forceResyncWallet @style w) Default payload
verify r
[ expectResponseCode @IO HTTP.status403
, expectErrorMessage errMsg403RejectedTip
]

-- force resync eventually get us back to the same point
scenarioWalletResync03_invalidPayload
:: forall style t n wallet.
( n ~ 'Testnet
, Discriminate style
, HasType (ApiT WalletId) wallet
, HasField' "state" wallet (ApiT SyncProgress)
, FromJSON wallet
, Generic wallet
, Show wallet
)
=> (Context t -> IO wallet)
-> SpecWith (Context t)
scenarioWalletResync03_invalidPayload fixture = it
"given payload is invalid (camelCase)" $ \ctx -> do
w <- fixture ctx

-- 1. Force a resync using an invalid payload
let payload = Json [json|{ "epochNumber": 0, "slot_number": 0 }|]
r <- request @wallet ctx (Link.forceResyncWallet @style w) Default payload
verify r
[ expectResponseCode @IO HTTP.status400
, expectErrorMessage "key 'epoch_number' not present"
]

0 comments on commit 7d3e281

Please sign in to comment.