From 1fe0e999e3d389d8daab79fa228e86dd6d2ea866 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Thu, 28 Feb 2013 11:31:35 +0100 Subject: [PATCH] Make the XmParser config test runtime more consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the test uses a frequency of 5 string/5 double/1 list for generating Arbitrary instances of ListConfig. However, the list case has simply a "choose (1, 20)" `vectorOf` arbitrary, which means it could recurse forever. Manually running only this test gives runtime as such: - ~100-200ms: very often - ~1-2s: often - ~5s: rare - ~20s: very rare (but I hit this when running < 30 times the test, soβ¦) On average, this makes this test one of the slowest ones, which is annoying. By changing to a sized generator, we can control the depth of the recursion, ensuring that we have a consistent runtime: out of 100 runs, one is 229ms, one is 164ms, the other are 80-120ms. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- .../hs/Test/Ganeti/Hypervisor/Xen/XmParser.hs | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/test/hs/Test/Ganeti/Hypervisor/Xen/XmParser.hs b/test/hs/Test/Ganeti/Hypervisor/Xen/XmParser.hs index f6f7a31d6..f22b5154d 100644 --- a/test/hs/Test/Ganeti/Hypervisor/Xen/XmParser.hs +++ b/test/hs/Test/Ganeti/Hypervisor/Xen/XmParser.hs @@ -48,17 +48,31 @@ import Ganeti.Hypervisor.Xen.XmParser -- * Arbitraries --- | Arbitrary instance for generating configurations. --- A completely arbitrary configuration would contain too many lists and its --- size would be to big to be actually parsable in reasonable time. --- This Arbitrary builds a random Config that is still of a reasonable size. --- Avoid generating strings that might be interpreted as numbers. +-- | Generator for 'ListConfig'. +-- +-- A completely arbitrary configuration would contain too many lists +-- and its size would be to big to be actually parsable in reasonable +-- time. This generator builds a random Config that is still of a +-- reasonable size, and it also Avoids generating strings that might +-- be interpreted as numbers. +genConfig :: Int -> Gen LispConfig +genConfig 0 = + -- only terminal values for size 0 + frequency [ (5, liftM LCString (genName `suchThat` (not . canBeNumber))) + , (5, liftM LCDouble arbitrary) + ] +genConfig n = + -- for size greater than 0, allow "some" lists + frequency [ (5, liftM LCString (resize n genName `suchThat` + (not . canBeNumber))) + , (5, liftM LCDouble arbitrary) + , (1, liftM LCList (choose (1, n) >>= + (\n' -> vectorOf n' (genConfig $ n `div` n')))) + ] + +-- | Arbitrary instance for 'LispConfig' using 'genConfig'. instance Arbitrary LispConfig where - arbitrary = frequency - [ (5, liftM LCString (genName `suchThat` (not . canBeNumber))) - , (5, liftM LCDouble arbitrary) - , (1, liftM LCList (choose(1,20) >>= (`vectorOf` arbitrary))) - ] + arbitrary = sized genConfig -- | Determines conservatively whether a string could be a number. canBeNumber :: String -> Bool -- GitLab