sim: added run subcommand

And a nice sim of random preferred content expressions.
This commit is contained in:
Joey Hess 2024-09-24 12:01:54 -04:00
parent 9571162057
commit 540bd5e1ab
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 53 additions and 17 deletions

View file

@ -531,7 +531,7 @@ applySimCommand' (CommandNotPresent _ _) _ _ = error "applySimCommand' CommandNo
handleStep :: Bool -> Int -> Int -> SimState SimRepo -> Annex (SimState SimRepo) handleStep :: Bool -> Int -> Int -> SimState SimRepo -> Annex (SimState SimRepo)
handleStep muststabilize startn n st handleStep muststabilize startn n st
| n > 0 = do | n >= 0 = do
let (st', actions) = getactions unsyncactions st let (st', actions) = getactions unsyncactions st
(st'', restactions) <- runoneaction actions st' (st'', restactions) <- runoneaction actions st'
if null restactions if null restactions
@ -550,7 +550,7 @@ handleStep muststabilize startn n st
| otherwise = checkstabalized st | otherwise = checkstabalized st
where where
runrest actions st' n' runrest actions st' n'
| n' > 0 = do | n' >= 0 = do
(st'', restactions) <- runoneaction actions st' (st'', restactions) <- runoneaction actions st'
if null restactions if null restactions
then handleStep muststabilize startn n' st' then handleStep muststabilize startn n' st'

View file

@ -22,19 +22,21 @@ cmd = command "sim" SectionTesting
paramCommand (withParams seek) paramCommand (withParams seek)
seek :: CmdParams -> CommandSeek seek :: CmdParams -> CommandSeek
seek ("start":[]) = start Nothing seek ("start":[]) = startsim Nothing
seek ("start":simfile:[]) = start (Just simfile) seek ("start":simfile:[]) = startsim (Just simfile)
seek ("end":[]) = do seek ("end":[]) = endsim
simdir <- fromRawFilePath <$> fromRepo gitAnnexSimDir
whenM (liftIO $ doesDirectoryExist simdir) $ do
liftIO $ removeDirectoryRecursive simdir
showLongNote $ UnquotedString "Sim ended."
seek ("show":[]) = do seek ("show":[]) = do
simdir <- fromRepo gitAnnexSimDir simdir <- fromRepo gitAnnexSimDir
liftIO (restoreSim simdir) >>= \case liftIO (restoreSim simdir) >>= \case
Left err -> giveup err Left err -> giveup err
Right st -> liftIO $ putStr $ generateSimFile $ Right st -> showsim st
reverse $ simHistory st seek ("run":simfile:[]) = startsim' (Just simfile) >>= cleanup
where
cleanup st = do
endsim
when (simFailed st) $ do
showsim st
giveup "Simulation shown above had errors."
seek ps = case parseSimCommand ps of seek ps = case parseSimCommand ps of
Left err -> giveup err Left err -> giveup err
Right simcmd -> do Right simcmd -> do
@ -48,8 +50,16 @@ seek ps = case parseSimCommand ps of
when (simFailed st' && not (simFailed st)) $ when (simFailed st' && not (simFailed st)) $
giveup "Simulation had errors." giveup "Simulation had errors."
start :: Maybe FilePath -> CommandSeek startsim :: Maybe FilePath -> CommandSeek
start simfile = do startsim simfile = startsim' simfile >>= cleanup
where
cleanup st = do
liftIO $ suspendSim st
when (simFailed st) $
giveup "Simulation had errors."
startsim' :: Maybe FilePath -> Annex (SimState SimRepo)
startsim' simfile = do
simdir <- fromRawFilePath <$> fromRepo gitAnnexSimDir simdir <- fromRawFilePath <$> fromRepo gitAnnexSimDir
whenM (liftIO $ doesDirectoryExist simdir) $ whenM (liftIO $ doesDirectoryExist simdir) $
giveup "A sim was previously started. Use `git-annex sim end` to stop it before starting a new one." giveup "A sim was previously started. Use `git-annex sim end` to stop it before starting a new one."
@ -68,12 +78,19 @@ start simfile = do
repobyname <- mkGetExistingRepoByName repobyname <- mkGetExistingRepoByName
createAnnexDirectory (toRawFilePath simdir) createAnnexDirectory (toRawFilePath simdir)
let st' = recordSeed st cs let st' = recordSeed st cs
st'' <- go st' repobyname cs go st' repobyname cs
liftIO $ suspendSim st''
when (simFailed st'') $
giveup "Simulation had errors."
go st _ [] = return st go st _ [] = return st
go st repobyname (c:cs) = do go st repobyname (c:cs) = do
st' <- runSimCommand c repobyname st st' <- runSimCommand c repobyname st
go st' repobyname cs go st' repobyname cs
endsim :: CommandSeek
endsim = do
simdir <- fromRawFilePath <$> fromRepo gitAnnexSimDir
whenM (liftIO $ doesDirectoryExist simdir) $ do
liftIO $ removeDirectoryRecursive simdir
showLongNote $ UnquotedString "Sim ended."
showsim :: SimState SimRepo -> Annex ()
showsim = liftIO . putStr . generateSimFile . reverse . simHistory

View file

@ -12,6 +12,8 @@ git annex sim show
git annex sim end git annex sim end
git annex sim run my.sim
# DESCRIPTION # DESCRIPTION
This command simulates the behavior of git-annex in a network of This command simulates the behavior of git-annex in a network of
@ -32,6 +34,10 @@ as well as analyzing the results of the simulation.
Use "git annex sim end" to finish the simulation, and clean up. Use "git annex sim end" to finish the simulation, and clean up.
As a convenience, to run a sim from a file, and then stop it, use
"git-annex sim run". If there is a problem running the sim, it will be
shown before it is stopped.
# THE SIM FILE # THE SIM FILE
This text file is used to configure the simulation and also to report on This text file is used to configure the simulation and also to report on

View file

@ -0,0 +1,13 @@
# This is a simulation of random preferred content expressions.
# git-annex sim run this in a loop to explore if an expression can fail to
# stabilize
init foo
init bar
connect foo <-> bar
addmulti 10 .x 100.0kB 10.0MB foo
addmulti 10 .y 100.0kB 10.0MB foo
randomwanted bar largerthan=1MB include=*.x anything present
randomwanted foo largerthan=1MB include=*.x anything present
# 40 is the maximum possible steps, in case bar wants to get all 20 files,
# and foo wants to drop them all
stepstable 40