diff --git a/lib/Echidna/Campaign.hs b/lib/Echidna/Campaign.hs index 3beedb00b..7e6e851ae 100644 --- a/lib/Echidna/Campaign.hs +++ b/lib/Echidna/Campaign.hs @@ -85,7 +85,7 @@ runWorker -> GenDict -- ^ Generation dictionary -> Int -- ^ Worker id starting from 0 -> [[Tx]] -- ^ Initial corpus of transactions - -> Int -- ^ Test limit for this worker + -> Maybe Int -- ^ Test limit for this worker -> m (WorkerStopReason, WorkerState) runWorker callback vm world dict workerId initialCorpus testLimit = do metaCacheRef <- asks (.metadataCache) @@ -135,10 +135,10 @@ runWorker callback vm world dict workerId initialCorpus testLimit = do if | stopOnFail && any final tests -> lift callback >> pure FastFailed - | (null tests || any isOpen tests) && ncalls < testLimit -> + | (null tests || any isOpen tests) && maybe True (ncalls <) testLimit -> fuzz >> continue - | ncalls >= testLimit && any (\t -> isOpen t && isOptimizationTest t) tests -> do + | maybe False (ncalls >=) testLimit && any (\t -> isOpen t && isOptimizationTest t) tests -> do liftIO $ atomicModifyIORef' testsRef $ \sharedTests -> (closeOptimizationTest <$> sharedTests, ()) continue diff --git a/lib/Echidna/Config.hs b/lib/Echidna/Config.hs index 05012ea27..f1fc80651 100644 --- a/lib/Echidna/Config.hs +++ b/lib/Echidna/Config.hs @@ -85,7 +85,7 @@ instance FromJSON EConfigWithUsage where pure $ TestConf classify (const psender) campaignConfParser = CampaignConf - <$> v ..:? "testLimit" ..!= defaultTestLimit + <$> v ..:? "testLimit" <*> v ..:? "stopOnFail" ..!= False <*> v ..:? "estimateGas" ..!= False <*> v ..:? "seqLen" ..!= defaultSequenceLength diff --git a/lib/Echidna/Types/Campaign.hs b/lib/Echidna/Types/Campaign.hs index 85f0ca478..72c802ff2 100644 --- a/lib/Echidna/Types/Campaign.hs +++ b/lib/Echidna/Types/Campaign.hs @@ -14,7 +14,7 @@ import Echidna.Types.Tx (Tx) -- | Configuration for running an Echidna 'Campaign'. data CampaignConf = CampaignConf - { testLimit :: Int + { testLimit :: Maybe Int -- ^ Maximum number of function calls to execute while fuzzing , stopOnFail :: Bool -- ^ Whether to stop the campaign immediately if any property fails @@ -116,9 +116,6 @@ initialWorkerState = , ncalls = 0 } -defaultTestLimit :: Int -defaultTestLimit = 50000 - defaultSequenceLength :: Int defaultSequenceLength = 100 diff --git a/lib/Echidna/UI.hs b/lib/Echidna/UI.hs index e8aadcc35..f10090f81 100644 --- a/lib/Echidna/UI.hs +++ b/lib/Echidna/UI.hs @@ -78,8 +78,10 @@ ui vm world dict initialCorpus = do -- Distribute over all workers, could be slightly bigger overall due to -- ceiling but this doesn't matter - perWorkerTestLimit = ceiling - (fromIntegral conf.campaignConf.testLimit / fromIntegral nworkers :: Double) + perWorkerTestLimit = + case conf.campaignConf.testLimit of + Nothing -> Nothing + Just t -> Just $ ceiling (fromIntegral t / fromIntegral nworkers :: Double) chunkSize = ceiling (fromIntegral (length initialCorpus) / fromIntegral nworkers :: Double) diff --git a/lib/Echidna/UI/Widgets.hs b/lib/Echidna/UI/Widgets.hs index 64f649515..46561ce43 100644 --- a/lib/Echidna/UI/Widgets.hs +++ b/lib/Echidna/UI/Widgets.hs @@ -159,8 +159,8 @@ summaryWidget env uiState = <=> perfWidget uiState <=> - str ("Total calls: " <> progress (sum $ (.ncalls) <$> uiState.campaigns) - env.cfg.campaignConf.testLimit) + str ("Total calls: " <> maybe (show totalCalls) (progress totalCalls) env.cfg.campaignConf.testLimit) + totalCalls = (sum $ (.ncalls) <$> uiState.campaigns) middle = padLeft (Pad 1) $ str ("Unique instructions: " <> show uiState.coverage) diff --git a/src/Main.hs b/src/Main.hs index 5f4a50887..fcbc12d8a 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -275,7 +275,7 @@ options = Options <> help "Timeout given in seconds.") <*> optional (option auto $ long "test-limit" <> metavar "INTEGER" - <> help ("Number of sequences of transactions to generate during testing. Default is " ++ show defaultTestLimit)) + <> help "Number of sequences of transactions to generate during testing. Default is unbounded.") <*> optional (option auto $ long "shrink-limit" <> metavar "INTEGER" <> help ("Number of tries to attempt to shrink a failing sequence of transactions. Default is " ++ show defaultShrinkLimit)) @@ -333,7 +333,7 @@ overrideConfig config Options{..} = do overrideCampaignConf campaignConf = campaignConf { corpusDir = cliCorpusDir <|> campaignConf.corpusDir - , testLimit = fromMaybe campaignConf.testLimit cliTestLimit + , testLimit = cliTestLimit <|> campaignConf.testLimit , shrinkLimit = fromMaybe campaignConf.shrinkLimit cliShrinkLimit , seqLen = fromMaybe campaignConf.seqLen cliSeqLen , seed = cliSeed <|> campaignConf.seed diff --git a/src/test/Common.hs b/src/test/Common.hs index b02e99045..2faf3a5cf 100644 --- a/src/test/Common.hs +++ b/src/test/Common.hs @@ -67,7 +67,7 @@ overrideQuiet conf = overrideLimits :: EConfig -> EConfig overrideLimits conf = - conf { campaignConf = conf.campaignConf { testLimit = 10000 + conf { campaignConf = conf.campaignConf { testLimit = Just 10000 , shrinkLimit = 4000 }} type SolcVersion = Version diff --git a/src/test/Tests/Seed.hs b/src/test/Tests/Seed.hs index 62ddddae2..b686977d0 100644 --- a/src/test/Tests/Seed.hs +++ b/src/test/Tests/Seed.hs @@ -21,7 +21,7 @@ seedTests = where cfg s = defaultConfig { campaignConf = CampaignConf - { testLimit = 600 + { testLimit = Just 600 , stopOnFail = False , estimateGas = False , seqLen = 20