packages feed

sydtest-mutation-driver 0.1.0.0 → 0.2.0.0

raw patch · 4 files changed

+34/−6 lines, 4 filessetup-changed

Files

CHANGELOG.md view
@@ -1,5 +1,14 @@ # Changelog +## [0.2.0.0] - 2026-09-11++### Fixed++* The output of the run that killed a control is kept, so the flaky test behind+  a control failure can be found.+++ ## [0.1.0.0] - 2026-07-16  * First released version.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
src/Test/Syd/Mutation/Driver/Mutate.hs view
@@ -281,15 +281,16 @@             -- timeout is the control failing (the suite is unsound).             pure $               if isControlOperator (augmentedMutationRecordOperator record)-                then asControlResult (classifyOutcomes record outcomes)+                then asControlResult outcomes (classifyOutcomes record outcomes)                 else classifyOutcomes record outcomes      -- Map a control mutation's raw classification onto the control-specific     -- results.  An uncovered control never reaches here (it short-circuits     -- above), and 'classifyOutcomes' only ever yields killed/timed-out/survived.-    asControlResult = \case+    asControlResult outcomes = \case       MutationSurvived sm -> MutationControlPassed (survivedMutationRecord sm)-      MutationKilled record -> MutationControlFailed (ControlFailedMutation record Nothing)+      MutationKilled record ->+        MutationControlFailed (ControlFailedMutation record (killingSuiteLog outcomes))       MutationTimedOut tm ->         MutationControlFailed           (ControlFailedMutation (timedOutMutationRecord tm) (timedOutMutationLogFile tm))@@ -317,10 +318,16 @@                     listToMaybe [rf | SuiteSurvived (Just rf) <- NE.toList outcomes]                 }       where-        isKilled SuiteKilled = True+        isKilled (SuiteKilled _) = True         isKilled _ = False         mTimedOut = listToMaybe [(micros, mLog) | SuiteTimedOut micros mLog <- NE.toList outcomes] +    -- \| The log of the first suite that killed the mutation, when one was+    -- kept.  Only a control's kill keeps one (see 'runOneSuite'), which is+    -- also the only caller.+    killingSuiteLog outcomes =+      listToMaybe [rf | SuiteKilled (Just rf) <- NE.toList outcomes]+     runOneSuite record mid suiteName = do       (exe, mResourceDir) <- case Map.lookup suiteName suiteConfigs of         Just SuiteConfig {suiteConfigExe, suiteConfigResourceDir} ->@@ -386,7 +393,17 @@               mRelFile <- copyChildLog "timeout-" mid suiteName logPath               pure (SuiteTimedOut elapsedMicros mRelFile)             Right ec -> case ec of-              ExitFailure _ -> pure SuiteKilled+              ExitFailure _ -> do+                -- A kill is the expected outcome and its output says nothing,+                -- except for a control: a no-op cannot legitimately be killed,+                -- so the child's output is the only place that names the test+                -- which killed it, and without it the flaky test behind a+                -- control failure cannot be found.+                mRelFile <-+                  if isControlOperator (augmentedMutationRecordOperator record)+                    then copyChildLog "control-failure-" mid suiteName logPath+                    else pure Nothing+                pure (SuiteKilled mRelFile)               ExitSuccess -> do                 mRelFile <- copyChildLog "survivor-" mid suiteName logPath                 pure (SuiteSurvived mRelFile)
sydtest-mutation-driver.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           sydtest-mutation-driver-version:        0.1.0.0+version:        0.2.0.0 synopsis:       Out-of-process mutation testing driver for sydtest. description:    Standalone driver executable that orchestrates the coverage and mutation phases of sydtest's mutation testing infrastructure. Spawns instrumented sydtest test suite executables as children. category:       Testing