Skip to content

Commit

Permalink
Allowing backwards compatibility with ds-test
Browse files Browse the repository at this point in the history
  • Loading branch information
msooseth committed Dec 2, 2024
1 parent be2a67c commit 88ccb41
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 9 deletions.
11 changes: 7 additions & 4 deletions cli/cli.hs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ data Command w

-- symbolic execution opts
, root :: w ::: Maybe String <?> "Path to project root directory (default: . )"
, projectType :: w ::: Maybe ProjectType <?> "Is this a CombinedJSON or Foundry project (default: Foundry)"
, projectType :: w ::: Maybe ProjectType <?> "Is this a CombinedJSON, Foundry, or DSTest project (default: Foundry)"
, initialStorage :: w ::: Maybe (InitialStorage) <?> "Starting state for storage: Empty, Abstract (default Abstract)"
, sig :: w ::: Maybe Text <?> "Signature of types to decode / encode"
, arg :: w ::: [String] <?> "Values to encode"
Expand Down Expand Up @@ -147,11 +147,11 @@ data Command w
, rpc :: w ::: Maybe URL <?> "Fetch state from a remote node"
, block :: w ::: Maybe W256 <?> "Block state is be fetched from"
, root :: w ::: Maybe String <?> "Path to project root directory (default: . )"
, projectType :: w ::: Maybe ProjectType <?> "Is this a CombinedJSON or Foundry project (default: Foundry)"
, projectType :: w ::: Maybe ProjectType <?> "Is this a CombinedJSON, Foundry, or DSTest project (default: Foundry)"
}
| Test -- Run Foundry unit tests
{ root :: w ::: Maybe String <?> "Path to project root directory (default: . )"
, projectType :: w ::: Maybe ProjectType <?> "Is this a CombinedJSON or Foundry project (default: Foundry)"
, projectType :: w ::: Maybe ProjectType <?> "Is this a CombinedJSON, Foundry, or DSTest project (default: Foundry)"
, rpc :: w ::: Maybe URL <?> "Fetch state from a remote node"
, number :: w ::: Maybe W256 <?> "Block: number"
, verbose :: w ::: Maybe Int <?> "Append call trace: {1} failures {2} all"
Expand Down Expand Up @@ -308,7 +308,9 @@ getSrcInfo cmd = do
else pure emptyDapp

getProjectType :: Command Options.Unwrapped -> ProjectType
getProjectType cmd = fromMaybe Foundry cmd.projectType
getProjectType cmd =
let pt = fromMaybe Foundry cmd.projectType
in if elem pt [Foundry, DSTest] then Foundry else CombinedJSON

getRoot :: Command Options.Unwrapped -> IO FilePath
getRoot cmd = maybe getCurrentDirectory makeAbsolute (cmd.root)
Expand Down Expand Up @@ -674,6 +676,7 @@ unitTestOptions cmd solvers buildOutput = do
, testParams = params
, dapp = srcInfo
, ffiAllowed = cmd.ffi
, checkFailBit = cmd.projectType == Just DSTest
}
parseInitialStorage :: InitialStorage -> BaseState
parseInitialStorage Empty = EmptyBase
Expand Down
2 changes: 1 addition & 1 deletion src/EVM/Solidity.hs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ instance Monoid BuildOutput where
mempty = BuildOutput mempty mempty

-- | The various project types understood by hevm
data ProjectType = CombinedJSON | Foundry
data ProjectType = CombinedJSON | Foundry | DSTest
deriving (Eq, Show, Read, ParseField)

data SourceCache = SourceCache
Expand Down
11 changes: 8 additions & 3 deletions src/EVM/UnitTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ data UnitTestOptions s = UnitTestOptions
, dapp :: DappInfo
, testParams :: TestVMParams
, ffiAllowed :: Bool
, checkFailBit:: Bool
}

data TestVMParams = TestVMParams
Expand Down Expand Up @@ -199,12 +200,16 @@ symRun opts@UnitTestOptions{..} vm (Sig testName types) = do
shouldFail = "proveFail" `isPrefixOf` callSig

-- define postcondition depending on `shouldFail`
let postcondition = curry $ case shouldFail of
let testContract store = fromMaybe (internalError "test contract not found in state") (Map.lookup vm.state.contract store)
failed store = case Map.lookup cheatCode store of
Just cheatContract -> Expr.readStorage' (Lit 0x6661696c65640000000000000000000000000000000000000000000000000000) cheatContract.storage .== Lit 1
Nothing -> And (Expr.readStorage' (Lit 0) (testContract store).storage) (Lit 2) .== Lit 2
postcondition = curry $ case shouldFail of
True -> \(_, post) -> case post of
Success {} -> PBool False
Success _ _ _ store -> if opts.checkFailBit then failed store else PBool False
_ -> PBool True
False -> \(_, post) -> case post of
Success _ _ _ _ -> PBool True
Success _ _ _ store -> if opts.checkFailBit then PNeg (failed store) else PBool True
Failure _ _ (Revert msg) -> case msg of
ConcreteBuf b ->
if (BS.isPrefixOf (selector "Error(string)") b) || b == panicMsg 0x01 then PBool False
Expand Down
3 changes: 2 additions & 1 deletion test/EVM/Test/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ testOpts solvers root buildOutput match maxIter allowFFI rpcinfo = do
, testParams = params
, dapp = srcInfo
, ffiAllowed = allowFFI
, checkFailBit = False
}

processFailedException :: String -> String -> [String] -> Int -> IO a
Expand All @@ -78,7 +79,7 @@ callProcessCwd cmd args cwd = do

compile :: App m => ProjectType -> FilePath -> FilePath -> m (Either String BuildOutput)
compile CombinedJSON _root _src = internalError "unsupported compile type: CombinedJSON"
compile Foundry root src = do
compile _ root src = do
liftIO $ createDirectory (root </> "src")
liftIO $ writeFile (root </> "src" </> "unit-tests.t.sol") =<< readFile =<< Paths.getDataFileName src
liftIO $ initLib (root </> "lib" </> "tokens") ("test" </> "contracts" </> "lib" </> "erc20.sol") "erc20.sol"
Expand Down

0 comments on commit 88ccb41

Please sign in to comment.