-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ea06cfd
commit 8593410
Showing
10 changed files
with
227 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
{-# LANGUAGE DisambiguateRecordFields #-} | ||
{-# LANGUAGE DuplicateRecordFields #-} | ||
{-# LANGUAGE FunctionalDependencies #-} | ||
|
||
module Test.ChainSpec | ||
( ChainTest(postTx, waitCallback) | ||
, hasInitTxWith | ||
, observesInTime | ||
, observesInTimeSatisfying | ||
) where | ||
|
||
import Test.Hydra.Prelude | ||
import Hydra.Chain (ChainEvent(Observation, observedTx)) | ||
import Hydra.Chain (PostChainTx) | ||
import Hydra.ContestationPeriod (ContestationPeriod) | ||
import Hydra.Party (Party) | ||
import Hydra.Chain (OnChainTx) | ||
import Hydra.Ledger (IsTx) | ||
import Hydra.Chain (OnChainTx(OnInitTx, contestationPeriod, parties)) | ||
import Hydra.Prelude | ||
-- import Test.DirectChainSpec (DirectChainTest(DirectChainTest)) | ||
|
||
-- Abstract over DirectChainTest and OfflineChainTest | ||
class ChainTest c tx m | c -> tx m where --TODO(Elaine): additional constraints? alternative: manual vtable ChainTest, directchain wraps | ||
postTx :: c -> PostChainTx tx -> m () | ||
waitCallback :: c -> m (ChainEvent tx) | ||
|
||
-- offlineConfigFor :: HasCallStack => Actor -> FilePath -> ContestationPeriod -> IO OfflineConfig | ||
-- offlineConfigFor me targetDir contestationPeriod = do | ||
-- undefined | ||
|
||
-- NOTE(Elaine): is this ther ight place for this?? | ||
hasInitTxWith :: (HasCallStack, IsTx tx) => ContestationPeriod -> [Party] -> OnChainTx tx -> Expectation | ||
hasInitTxWith expectedContestationPeriod expectedParties = \case | ||
OnInitTx{contestationPeriod, parties} -> do | ||
expectedContestationPeriod `shouldBe` contestationPeriod | ||
expectedParties `shouldBe` parties | ||
tx -> failure ("Unexpected observation: " <> show tx) | ||
|
||
observesInTime :: ChainTest c tx IO => IsTx tx => c -> OnChainTx tx -> IO () | ||
observesInTime chain expected = | ||
observesInTimeSatisfying chain (`shouldBe` expected) | ||
|
||
observesInTimeSatisfying :: ChainTest c tx IO => c -> (OnChainTx tx -> Expectation) -> IO () | ||
observesInTimeSatisfying c check = | ||
failAfter 10 go | ||
where | ||
go = do | ||
e <- waitCallback c | ||
case e of | ||
Observation{observedTx} -> | ||
check observedTx | ||
_TickOrRollback -> | ||
go | ||
|
||
waitMatch :: ChainTest c tx IO => c -> (ChainEvent tx -> Maybe b) -> IO b | ||
waitMatch c match = go | ||
where | ||
go = do | ||
a <- waitCallback c | ||
maybe go pure (match a) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
{-# LANGUAGE DeriveAnyClass #-} | ||
{-# LANGUAGE DuplicateRecordFields #-} | ||
{-# LANGUAGE DisambiguateRecordFields #-} | ||
{-# LANGUAGE PatternSynonyms #-} | ||
{-# LANGUAGE TupleSections #-} | ||
{-# LANGUAGE TypeApplications #-} | ||
|
||
module Test.OfflineChainSpec where | ||
import Hydra.Prelude | ||
import Test.Hydra.Prelude | ||
import Hydra.Chain (PostChainTx, ChainEvent) | ||
import Hydra.Logging (showLogsOnFailure, Tracer) | ||
import Hydra.Chain.Offline (withOfflineChain) | ||
import Hydra.Options (defaultContestationPeriod) | ||
import Hydra.Party (deriveParty) | ||
import Hydra.Chain (PostChainTx(InitTx, headParameters)) | ||
import Hydra.Options (OfflineConfig(OfflineConfig, initialUTxOFile, ledgerGenesisFile, utxoWriteBack), OfflineUTxOWriteBackConfig(), defaultOfflineConfig) | ||
import Hydra.Chain (HeadParameters(HeadParameters, contestationPeriod, parties)) | ||
import Hydra.Cluster.Util (keysFor) | ||
import Hydra.Cluster.Fixture (Actor(Alice), aliceSk) | ||
import Hydra.Chain (initHistory) | ||
import Hydra.Chain.Direct.State (initialChainState) | ||
import Hydra.Node.EventQueue (EventQueue(putEvent)) | ||
import Hydra.HeadLogic.Event (Event(OnChainEvent)) | ||
import Control.Concurrent.STM (newEmptyTMVarIO, putTMVar, takeTMVar) | ||
import Hydra.Logging (nullTracer) | ||
import Hydra.Chain (Chain(Chain, postTx)) | ||
import Hydra.Crypto (generateSigningKey) | ||
|
||
--TODO(Elaine): replace with some offlinechainlog? | ||
import Hydra.Chain.Direct.Handlers (DirectChainLog) | ||
import Hydra.Party (Party) | ||
import Hydra.Ledger.Cardano (Tx) | ||
import Hydra.Chain (HeadId(HeadId)) | ||
import Hydra.ContestationPeriod (ContestationPeriod) | ||
import Hydra.Chain (OnChainTx(OnInitTx, OnCommitTx, party, committed)) | ||
|
||
import Test.ChainSpec (hasInitTxWith, observesInTime) | ||
import Hydra.Ledger (IsTx(UTxOType)) | ||
import Hydra.Chain (ChainEvent(Observation, observedTx)) | ||
import Hydra.Chain (PostChainTx(AbortTx)) | ||
import Hydra.Chain (OnChainTx(OnAbortTx)) | ||
|
||
|
||
data OfflineChainTest tx m = OfflineChainTest | ||
{ postTx :: PostChainTx tx -> m () | ||
, waitCallback :: m (ChainEvent tx) | ||
} | ||
|
||
withOfflineChainTest :: Tracer IO DirectChainLog -> OfflineConfig | ||
-> Party | ||
-> (OfflineChainTest Tx IO -> IO b) | ||
-> IO b | ||
withOfflineChainTest tracer offlineConfig party action = do | ||
eventMVar <- newEmptyTMVarIO | ||
|
||
let callback event = atomically $ putTMVar eventMVar event | ||
globals = undefined | ||
contestationPeriod = defaultContestationPeriod | ||
withOfflineChain tracer offlineConfig globals (HeadId "HeadId") party contestationPeriod (initHistory initialChainState) callback $ \Chain{postTx} -> do | ||
action | ||
OfflineChainTest | ||
{ postTx | ||
, waitCallback = atomically $ takeTMVar eventMVar | ||
} | ||
|
||
spec :: Spec | ||
spec = around showLogsOnFailure $ do | ||
it "can init and abort an offline head given nothing has been externally comitted" $ \tracer -> do | ||
withTempDir "hydra-cluster" $ \tmp -> do | ||
(aliceCardanoVk, aliceCardanoSk) <- keysFor Alice | ||
-- let aliceHydraKey = generateSigningKey . show $ (1::Integer) --based on EndToEnd.hs | ||
let aliceParty = deriveParty aliceSk | ||
--TODO(Elaine): i think we have to make this relative see readConfigFile | ||
initialUTxO <- readJsonFileThrow (parseJSON @(UTxOType Tx)) $ initialUTxOFile defaultOfflineConfig | ||
|
||
seedInitialUTxOFromOffline initialUtxo tmp | ||
|
||
withOfflineChainTest tracer defaultOfflineConfig aliceParty $ \OfflineChainTest{postTx, waitCallback} -> do | ||
-- postTx $ InitTx | ||
-- { headParameters = HeadParameters | ||
-- { contestationPeriod = defaultContestationPeriod | ||
-- , parties = [aliceParty] | ||
-- } | ||
-- } | ||
-- we should automatically have an init, commit, event play because withOfflineChain calls initializeStateIfOffline | ||
-- but withDirectChain doesnt do this so it makes me wonder if we should revert the change | ||
|
||
|
||
|
||
event <- waitCallback -- because we've got a tmvar the stuff in withOfflineChain should block until we've read out the remaining events | ||
hasInitTxWith defaultContestationPeriod [aliceParty] $ observedTx event | ||
|
||
event' <- waitCallback | ||
-- event' `shouldBe` Observation { observedTx = OnCommitTx { party = aliceParty, committed = initialUTxO } } | ||
observedTx event' `observesInTime` OnCommitTx { party = aliceParty, committed = initialUTxO } | ||
|
||
postTx $ AbortTx {-TODO(Elaine): what are the semantics of this again -} mempty | ||
event'' <- waitCallback | ||
-- need to make observesintime etc generic to get timeout on this | ||
observedTx event'' `observesInTime` OnAbortTx | ||
|
||
|
||
|
||
|
||
pure () | ||
pure () | ||
|
||
pure () | ||
|
||
-- hasInitTxWith :: ContestationPeriod -> Party -> ChainEvent Tx -> Expectation | ||
-- hasInitTxWith expectedContestationPeriod expectedParty = \case | ||
-- OnInitTx {contestationPeriod, parties} -> pure () | ||
-- _ -> expectationFailure $ "expected InitTx, got " <> show event |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters