Skip to content

Commit

Permalink
Add test scaffolding for Anoma Client
Browse files Browse the repository at this point in the history
  • Loading branch information
paulcadman committed Dec 6, 2024
1 parent e2a183d commit 92d790b
Show file tree
Hide file tree
Showing 13 changed files with 437 additions and 22 deletions.
5 changes: 4 additions & 1 deletion test/Anoma.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
module Anoma where

import Anoma.Client qualified as Client
import Anoma.Compilation qualified as Compilation
import Base

allTests :: TestTree
allTests =
testGroup
"Anoma tests"
[Compilation.allTests]
[ Compilation.allTests,
Client.allTests
]
7 changes: 7 additions & 0 deletions test/Anoma/Client.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Anoma.Client where

import Anoma.Client.Positive qualified as P
import Base

allTests :: TestTree
allTests = testGroup "Execution with the Anoma client" [P.allTests]
47 changes: 47 additions & 0 deletions test/Anoma/Client/Positive.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Anoma.Client.Positive where

import Anoma.Effect.Base
import Base
import Juvix.Compiler.Nockma.Language hiding (Path)
import Juvix.Compiler.Nockma.Translation.FromTree (anomaClosure)

root :: Path Abs Dir
root = relToProject $(mkRelDir "tests/Anoma/Client/positive")

type Check =
Sem
'[ Reader [Term Natural],
EmbedIO
]

data ClientTest = ClientTest
{ _clientTestNum :: Int,
_clientTestTag :: Text,
_clientRelRoot :: Path Rel Dir,
_clientMainFile :: Path Rel File,
_clientAssertion :: forall r. (Members '[Error SimpleError, Anoma, EmbedIO] r) => Term Natural -> Sem r ()
}

makeLenses ''ClientTest

clientTestName :: ClientTest -> Text
clientTestName t = numberedTestName (t ^. clientTestNum) (t ^. clientTestTag)

withRootCopy :: (Path Abs Dir -> IO a) -> IO a
withRootCopy = withRootTmpCopy root

fromClientTest :: ClientTest -> TestTree
fromClientTest t = testCase (clientTestName t) assertion
where
assertion :: Assertion
assertion = runM . runProcess . runSimpleErrorHUnit . ignoreLogger $ do
res :: AnomaResult <- liftIO $ withRootCopy (compileMain False (t ^. clientRelRoot) (t ^. clientMainFile))
let program :: Term Natural = (res ^. anomaClosure)
p <- envAnomaPath
runAnomaEphemeral p ((t ^. clientAssertion) program)

allTests :: TestTree
allTests =
testGroup
"Anoma Client positive tests"
[]
2 changes: 1 addition & 1 deletion test/Anoma/Compilation/Negative.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Anoma.Compilation.Negative where

import Base
import Base hiding (compileMain)
import Juvix.Compiler.Backend (Target (TargetAnoma))
import Juvix.Compiler.Core.Error
import Juvix.Prelude qualified as Prelude
Expand Down
21 changes: 1 addition & 20 deletions test/Anoma/Compilation/Positive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module Anoma.Compilation.Positive (allTests) where
import Anoma.Effect.Base
import Anoma.Effect.RunNockma
import Base
import Juvix.Compiler.Backend (Target (TargetAnoma))
import Juvix.Compiler.Nockma.Anoma
import Juvix.Compiler.Nockma.Evaluator
import Juvix.Compiler.Nockma.Language
Expand Down Expand Up @@ -87,9 +86,6 @@ mkAnomaTest' _anomaTestMode _anomaProgramStorage _anomaTestNum _anomaTestTag _an
{ ..
}

envAnomaPath :: (MonadIO m) => m AnomaPath
envAnomaPath = AnomaPath <$> getAnomaPathAbs

mkAnomaNodeTest :: AnomaTest -> TestTree
mkAnomaNodeTest a@AnomaTest {..} =
testCase (anomaTestName a <> " - node") assertion
Expand All @@ -115,22 +111,7 @@ mkAnomaNodeTest a@AnomaTest {..} =
$ _anomaCheck

withRootCopy :: (Prelude.Path Abs Dir -> IO a) -> IO a
withRootCopy action = withSystemTempDir "test" $ \tmpRootDir -> do
copyDirRecur root tmpRootDir
action tmpRootDir

compileMain :: Bool -> Prelude.Path Rel Dir -> Prelude.Path Rel File -> Prelude.Path Abs Dir -> IO AnomaResult
compileMain enableDebug relRoot mainFile rootCopyDir = do
let testRootDir = rootCopyDir <//> relRoot
entryPoint <-
set entryPointTarget (Just TargetAnoma) . set entryPointDebug enableDebug
<$> testDefaultEntryPointIO testRootDir (testRootDir <//> mainFile)
(over anomaClosure removeInfoUnlessDebug) . (^. pipelineResult) . snd <$> testRunIO entryPoint upToAnoma
where
removeInfoUnlessDebug :: Term Natural -> Term Natural
removeInfoUnlessDebug
| enableDebug = id
| otherwise = removeInfoRec
withRootCopy = withRootTmpCopy root

mkAnomaTest ::
Int ->
Expand Down
25 changes: 25 additions & 0 deletions test/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ module Base
)
where

import Anoma.Effect.Base
import Control.Exception qualified as E
import Control.Monad.Extra as Monad
import Data.Algorithm.Diff
import Data.Algorithm.DiffOutput
import GHC.Generics qualified as GHC
import Juvix.Compiler.Backend (Target (TargetAnoma))
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.Termination
import Juvix.Compiler.Nockma.Language hiding (Path)
import Juvix.Compiler.Nockma.Translation.FromTree (anomaClosure)
import Juvix.Compiler.Pipeline.EntryPoint.IO
import Juvix.Compiler.Pipeline.Loader.PathResolver
import Juvix.Compiler.Pipeline.Run
Expand Down Expand Up @@ -211,3 +215,24 @@ numberedTestName i str = "Test" <> to3DigitString i <> ": " <> str

testCase :: (HasTextBackend str) => str -> Assertion -> TestTree
testCase name = HUnit.testCase (toPlainString name)

withRootTmpCopy :: Path Abs Dir -> (Path Abs Dir -> IO a) -> IO a
withRootTmpCopy root action = withSystemTempDir "test" $ \tmpRootDir -> do
copyDirRecur root tmpRootDir
action tmpRootDir

compileMain :: Bool -> Path Rel Dir -> Path Rel File -> Path Abs Dir -> IO AnomaResult
compileMain enableDebug relRoot mainFile rootCopyDir = do
let testRootDir = rootCopyDir <//> relRoot
entryPoint <-
set entryPointTarget (Just TargetAnoma) . set entryPointDebug enableDebug
<$> testDefaultEntryPointIO testRootDir (testRootDir <//> mainFile)
(over anomaClosure removeInfoUnlessDebug) . (^. pipelineResult) . snd <$> testRunIO entryPoint upToAnoma
where
removeInfoUnlessDebug :: Term Natural -> Term Natural
removeInfoUnlessDebug
| enableDebug = id
| otherwise = removeInfoRec

envAnomaPath :: (MonadIO m) => m AnomaPath
envAnomaPath = AnomaPath <$> getAnomaPathAbs
9 changes: 9 additions & 0 deletions tests/Anoma/Client/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Package;

import PackageDescription.V2 open;

package : Package :=
defaultPackage@{
name := "client-test";
dependencies := [defaultStdlib; path "library/"];
};
105 changes: 105 additions & 0 deletions tests/Anoma/Client/Swap.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
--- translated from https://github.com/anoma/anoma/blob/61413dfc6460b7bf96e9207ce3b9d22b9c678f09/apps/anoma_node/lib/examples/e_transaction.ex#L309
module Swap;

import Stdlib.Prelude open;
import ResourceMachine open;
import TransactionRequest open;
import Stdlib.Debug.Trace open;
import ByteArray open;

trivial_true_resource_eph : Resource :=
mkResource@{
label := 0;
logic := \{_ _ := true};
ephemeral := true;
quantity := 1;
data := 0;
nullifier-key := replicate 32 0x0 |> mkByteArray |> toAnomaContents;
rseed := 0;
nonce := 0;
};

trivial_true_nullifier_eph : Nat := nullifier trivial_true_resource_eph;

trivial_true_eph_nullifier : Proof :=
let
publicInputs : Public-Inputs :=
mkPublic-Inputs@{
commitments := [];
nullifiers := [trivial_true_nullifier_eph];
self-tag := trivial_true_nullifier_eph;
other-public := 0;
};
privateInputs : Private-Inputs :=
mkPrivate-Inputs@{
committed-resources := [];
nullified-resources := [trivial_true_resource_eph];
other-private := 0;
};
in mkProofLogic trivial_true_resource_eph publicInputs privateInputs;

trivial_true_eph_nullifier_action : Action :=
mkAction@{
commitments := [];
nullifiers := [trivial_true_nullifier_eph];
proofs := [trivial_true_eph_nullifier];
app-data := 0;
};

nullify_intent_eph : Transaction :=
mkTransaction@{
roots := [];
delta := actionDelta trivial_true_eph_nullifier_action;
actions := [trivial_true_eph_nullifier_action];
delta-proof := 0;
};

trivial_true_resource : Resource :=
mkResource@{
label := 0;
logic := \{_ _ := true};
ephemeral := true;
quantity := 1;
data := 0;
nullifier-key := replicate 32 0x0 |> mkByteArray |> toAnomaContents;
rseed := 0;
nonce := 2;
};

trivial_true_commitment : Proof :=
let
true_commitment : Nat := commitment trivial_true_resource;
publicInputs : Public-Inputs :=
mkPublic-Inputs@{
commitments := [true_commitment];
nullifiers := [];
self-tag := true_commitment;
other-public := 0;
};
privateInputs : Private-Inputs :=
mkPrivate-Inputs@{
committed-resources := [trivial_true_resource];
nullified-resources := [];
other-private := 0;
};
in mkProofLogic trivial_true_resource publicInputs privateInputs;

trivial_true_commit_action : Action :=
mkAction@{
commitments := [commitment trivial_true_resource];
nullifiers := [];
proofs := [trivial_true_commitment];
app-data := 0;
};

commit_intent : Transaction :=
mkTransaction@{
roots := [];
delta := actionDelta trivial_true_commit_action;
actions := [trivial_true_commit_action];
delta-proof := 0;
};

main : TransactionRequest :=
TransactionRequest.fromTransaction
(Transaction.compose nullify_intent_eph commit_intent);
47 changes: 47 additions & 0 deletions tests/Anoma/Client/Trivial.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Trivial;

import Stdlib.Prelude open;
import ResourceMachine open;
import TransactionRequest open;

logic (pub : Public-Inputs) (priv : Private-Inputs) : Bool := false;

r1 : Resource :=
mkResource@{
label := 1;
logic;
ephemeral := true;
data := 0;
quantity := 0;
nullifier-key := 0;
nonce := 0;
rseed := 0;
};

a1 : Action :=
mkAction@{
commitments := [];
nullifiers := [];
proofs :=
[mkProofLogic r1 (mkPublic-Inputs [] [] 0 0) (mkPrivate-Inputs [] [] 0)];
app-data := 0;
};

trivialTransaction : Transaction :=
mkTransaction@{
roots := [];
actions := [a1];
delta := zeroDelta;
delta-proof := 0;
};

emptyTransaction : Transaction :=
mkTransaction@{
roots := [];
actions := [];
delta := zeroDelta;
delta-proof := 0;
};

main : TransactionRequest :=
TransactionRequest.fromTransaction emptyTransaction;
18 changes: 18 additions & 0 deletions tests/Anoma/Client/library/ByteArray.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module ByteArray;

import Stdlib.Prelude open;

builtin bytearray
axiom ByteArray : Type;

builtin bytearray-from-list-byte
axiom mkByteArray : List Byte -> ByteArray;

builtin bytearray-length
axiom size : ByteArray -> Nat;

builtin anoma-bytearray-to-anoma-contents
axiom toAnomaContents : ByteArray -> Nat;

builtin anoma-bytearray-from-anoma-contents
axiom fromAnomaContents : Nat -> Nat -> ByteArray;
9 changes: 9 additions & 0 deletions tests/Anoma/Client/library/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Package;

import PackageDescription.V2 open;

package : Package :=
defaultPackage@{
name := "anoma-client-library";
dependencies := [defaultStdlib];
};
Loading

0 comments on commit 92d790b

Please sign in to comment.