Skip to content

Commit 4da153d

Browse files
authored
Merge pull request haskell#10588 from 9999years/vcs-arbitrary
VCS tests: Make smaller `Arbitrary` repositories to speed up `long-tests` 4.2x
2 parents 3f9ce03 + 351ebb2 commit 4da153d

File tree

1 file changed

+54
-12
lines changed
  • cabal-install/tests/UnitTests/Distribution/Client

1 file changed

+54
-12
lines changed

cabal-install/tests/UnitTests/Distribution/Client/VCS.hs

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ import UnitTests.Distribution.Client.ArbitraryInstances
5656
tests :: MTimeChange -> [TestTree]
5757
tests mtimeChange =
5858
map
59+
-- Are you tuning performance for these tests? The size of the arbitrary
60+
-- instances involved is very significant, because each element generated
61+
-- corresponds to one or more Git subcommands being run.
62+
--
63+
-- See [Tuning Arbitrary Instances] below for more information and
64+
-- parameters.
5965
(localOption $ QuickCheckTests 10)
6066
[ ignoreInWindows "See issue #8048 and #9519" $
6167
testGroup
@@ -472,6 +478,7 @@ instance Arbitrary PrngSeed where
472478
-- VCS commands to make a repository on-disk.
473479

474480
data SubmodulesSupport = SubmodulesSupported | SubmodulesNotSupported
481+
deriving (Show, Eq)
475482

476483
class KnownSubmodulesSupport (a :: SubmodulesSupport) where
477484
submoduleSupport :: SubmodulesSupport
@@ -484,7 +491,11 @@ instance KnownSubmodulesSupport 'SubmodulesNotSupported where
484491

485492
data FileUpdate = FileUpdate FilePath String
486493
deriving (Show)
487-
data SubmoduleAdd = SubmoduleAdd FilePath FilePath (Commit 'SubmodulesSupported)
494+
data SubmoduleAdd = SubmoduleAdd
495+
{ submodulePath :: FilePath
496+
, submoduleSource :: FilePath
497+
, submoduleCommit :: Commit 'SubmodulesSupported
498+
}
488499
deriving (Show)
489500

490501
newtype Commit (submodules :: SubmodulesSupport)
@@ -525,40 +536,71 @@ data RepoRecipe submodules
525536
genFileName :: Gen FilePath
526537
genFileName = (\c -> "file" </> [c]) <$> choose ('A', 'E')
527538

539+
-- [Tuning Arbitrary Instances]
540+
--
541+
-- Arbitrary repo recipes can get quite large due to nesting:
542+
--
543+
-- - `RepoRecipes` contain a number of groups (`TaggedCommits` or `BranchCommits`).
544+
-- - Groups contain a number of `Commit`s.
545+
-- - Commits contain a number of operations (`FileUpdate` or `SubmoduleAdd`).
546+
--
547+
-- There's also another wrinkle in that `SubmoduleAdd`s contain a `Commit`
548+
-- themselves, so square the `operationsPerCommit` number!
549+
--
550+
-- Then, a rough upper bound of the number of `git` calls required for an
551+
-- arbitrary `RepoRecipe` is
552+
-- `groupsPerRecipe * commitsPerGroup * operationsPerCommit^2`.
553+
--
554+
-- The original implementation of these instances, which chose
555+
-- reasonable-sounding size parameters of 5-15, led to a maximum of 1875
556+
-- operations per test case! No wonder they took so long!
557+
--
558+
-- In most cases, we only care about one or many operations, so "two" is a fine
559+
-- stand-in for "many" :)
560+
groupsPerRecipe :: Int
561+
groupsPerRecipe = 3
562+
563+
commitsPerGroup :: Int
564+
commitsPerGroup = 3
565+
566+
operationsPerCommit :: Int
567+
operationsPerCommit = 3
568+
528569
instance Arbitrary FileUpdate where
529-
arbitrary = genOnlyFileUpdate
570+
arbitrary = FileUpdate <$> genFileName <*> genFileContent
530571
where
531-
genOnlyFileUpdate = FileUpdate <$> genFileName <*> genFileContent
532572
genFileContent = vectorOf 10 (choose ('#', '~'))
533573

534574
instance Arbitrary SubmoduleAdd where
535-
arbitrary = genOnlySubmoduleAdd
575+
arbitrary = SubmoduleAdd <$> genFileName <*> genSubmoduleSrc <*> arbitrary
536576
where
537-
genOnlySubmoduleAdd = SubmoduleAdd <$> genFileName <*> genSubmoduleSrc <*> arbitrary
538577
genSubmoduleSrc = vectorOf 20 (choose ('a', 'z'))
539578

540579
instance forall submodules. KnownSubmodulesSupport submodules => Arbitrary (Commit submodules) where
541-
arbitrary = Commit <$> shortListOf1 5 fileUpdateOrSubmoduleAdd
580+
arbitrary = Commit <$> shortListOf1 operationsPerCommit (sized fileUpdateOrSubmoduleAdd)
542581
where
543-
fileUpdateOrSubmoduleAdd =
582+
fileUpdateOrSubmoduleAdd 0 = Left <$> arbitrary
583+
fileUpdateOrSubmoduleAdd size =
544584
case submoduleSupport @submodules of
545585
SubmodulesSupported ->
546586
frequency
547587
[ (10, Left <$> arbitrary)
548-
, (1, Right <$> arbitrary)
588+
, -- A `SubmoduleAdd` contains a `Commit`, so we make sure to scale
589+
-- down the size in the recursive call to avoid unbounded nesting.
590+
(1, Right <$> resize (size `div` 2) arbitrary)
549591
]
550592
SubmodulesNotSupported -> Left <$> arbitrary
551593
shrink (Commit writes) = Commit <$> filter (not . null) (shrink writes)
552594

553595
instance KnownSubmodulesSupport submodules => Arbitrary (TaggedCommits submodules) where
554-
arbitrary = TaggedCommits <$> genTagName <*> shortListOf1 5 arbitrary
596+
arbitrary = TaggedCommits <$> genTagName <*> shortListOf1 commitsPerGroup arbitrary
555597
where
556598
genTagName = ("tag_" ++) <$> shortListOf1 5 (choose ('A', 'Z'))
557599
shrink (TaggedCommits tag commits) =
558600
TaggedCommits tag <$> filter (not . null) (shrink commits)
559601

560602
instance KnownSubmodulesSupport submodules => Arbitrary (BranchCommits submodules) where
561-
arbitrary = BranchCommits <$> genBranchName <*> shortListOf1 5 arbitrary
603+
arbitrary = BranchCommits <$> genBranchName <*> shortListOf1 commitsPerGroup arbitrary
562604
where
563605
genBranchName =
564606
sized $ \n ->
@@ -568,12 +610,12 @@ instance KnownSubmodulesSupport submodules => Arbitrary (BranchCommits submodule
568610
BranchCommits branch <$> filter (not . null) (shrink commits)
569611

570612
instance KnownSubmodulesSupport submodules => Arbitrary (NonBranchingRepoRecipe submodules) where
571-
arbitrary = NonBranchingRepoRecipe <$> shortListOf1 15 arbitrary
613+
arbitrary = NonBranchingRepoRecipe <$> shortListOf1 groupsPerRecipe arbitrary
572614
shrink (NonBranchingRepoRecipe xs) =
573615
NonBranchingRepoRecipe <$> filter (not . null) (shrink xs)
574616

575617
instance KnownSubmodulesSupport submodules => Arbitrary (BranchingRepoRecipe submodules) where
576-
arbitrary = BranchingRepoRecipe <$> shortListOf1 15 taggedOrBranch
618+
arbitrary = BranchingRepoRecipe <$> shortListOf1 groupsPerRecipe taggedOrBranch
577619
where
578620
taggedOrBranch =
579621
frequency

0 commit comments

Comments
 (0)