1 /**
2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved.
3 License: MPL-2
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 
6 This Source Code Form is subject to the terms of the Mozilla Public License,
7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain
8 one at http://mozilla.org/MPL/2.0/.
9 */
10 module dextool.plugin.mutate.config;
11 
12 import core.time : Duration, dur;
13 import std.typecons : Nullable;
14 
15 import dextool.plugin.mutate.type;
16 import dextool.type : AbsolutePath, Path;
17 public import dextool.plugin.mutate.backend : Mutation, TestGroup;
18 
19 /// The mode the tool is operating in
20 enum ToolMode {
21     /// No mode set
22     none,
23     /// analyze for mutation points
24     analyzer,
25     /// center that can operate and control subcomponents
26     generate_mutant,
27     /// test mutation points with a test suite
28     test_mutants,
29     /// generate a report of the mutation points
30     report,
31     /// administrator interface for the mutation database
32     admin,
33     /// Dump the TOML configuration to the console
34     dumpConfig,
35     /// Write a TOML config to the filesystem
36     initConfig,
37 }
38 
39 /// Config of the report.
40 struct ConfigReport {
41     ReportKind reportKind;
42     ReportLevel reportLevel;
43     ReportSection[] reportSection;
44 
45     /// Directory to write logs to when writing to the filesystem.
46     AbsolutePath logDir;
47 
48     /// Controls how to sort test cases by their kill statistics.
49     ReportKillSortOrder tcKillSortOrder;
50     int tcKillSortNum = 20;
51 
52     /// User regex for reporting groups of tests
53     TestGroup[] testGroups;
54 
55     /// If a unified diff should be used in the report
56     bool unifiedDiff;
57 
58     /// If profiling data should be printed.
59     bool profile;
60 }
61 
62 /// Configuration data for the compile_commands.json
63 struct ConfigCompileDb {
64     import dextool.compilation_db : CompileCommandFilter;
65 
66     /// Raw user input via either config or cli
67     string[] rawDbs;
68 
69     /// path to compilation databases.
70     AbsolutePath[] dbs;
71 
72     /// Flags the user wants to be automatically removed from the compile_commands.json.
73     CompileCommandFilter flagFilter;
74 }
75 
76 /// Configuration of how the mutation analyzer should act.
77 struct ConfigAnalyze {
78     /// User input of excludes before they are adjusted to relative root
79     string[] rawExclude;
80 
81     /// Exclude any files that are in these directory trees from the analysis.
82     AbsolutePath[] exclude;
83 
84     /// The size of the thread pool which affects how many files are analyzed in parallel.
85     int poolSize;
86 
87     /// What files to analyze is derived from a diff.
88     bool unifiedDiffFromStdin;
89 
90     /// Remove files from the database that aren't found when analyzing.
91     bool prune;
92 
93     /// Turn off the sqlite synchronization safety
94     bool fastDbStore;
95 
96     /// If profiling data should be printed.
97     bool profile;
98 
99     /// Force the result from the files to always be saved
100     bool forceSaveAnalyze;
101 
102     /// Number of mutants to at most put in a schema (soft limit)
103     long mutantsPerSchema = 100;
104 }
105 
106 /// Settings for the compiler
107 struct ConfigCompiler {
108     import dextool.compilation_db : SystemCompiler = Compiler;
109 
110     /// Additional flags the user wants to add besides those that are in the compile_commands.json.
111     string[] extraFlags;
112 
113     /// True requires system includes to be passed on to the compiler via -I
114     bool forceSystemIncludes;
115 
116     /// Deduce compiler flags from this compiler and not the one in the
117     /// supplied compilation database.  / This is needed when the one specified
118     /// in the DB has e.g. a c++ stdlib that is not compatible with clang.
119     SystemCompiler useCompilerSystemIncludes;
120 }
121 
122 /// Settings for mutation testing
123 struct ConfigMutationTest {
124     ShellCommand[] mutationTester;
125     /// Find executables in this directory and add them to mutationTester.
126     Path[] testCommandDir;
127     /// Flags to add to all executables found in `testCommandDir`
128     string[] testCommandDirFlag;
129 
130     ShellCommand mutationCompile;
131     ShellCommand[] mutationTestCaseAnalyze;
132     TestCaseAnalyzeBuiltin[] mutationTestCaseBuiltin;
133 
134     /// If the user hard code a timeout for the test suite.
135     Nullable!Duration mutationTesterRuntime;
136 
137     /// Timeout to use when compiling.
138     Duration buildCmdTimeout = 30.dur!"minutes";
139 
140     /// In what order to choose mutants to test.
141     MutationOrder mutationOrder;
142     bool dryRun;
143 
144     /// How to behave when new test cases are detected.
145     enum NewTestCases {
146         doNothing,
147         /// Automatically reset alive mutants
148         resetAlive,
149     }
150 
151     NewTestCases onNewTestCases;
152 
153     /// How to behave when test cases are detected of having been removed
154     enum RemovedTestCases {
155         doNothing,
156         /// Remove it and all results connectedto the test case
157         remove,
158     }
159 
160     RemovedTestCases onRemovedTestCases;
161 
162     /// How to behave when mutants have aged.
163     enum OldMutant {
164         nothing,
165         test,
166     }
167 
168     OldMutant onOldMutants;
169     long oldMutantsNr;
170 
171     /// Max time to run mutation testing.
172     // note that Duration.max + Clock.currTime results in a negative time...
173     Duration maxRuntime = 52.dur!"weeks";
174 
175     // Constrain the mutation testing.
176     TestConstraint constraint;
177 
178     /// If constraints should be read from a unified diff via stdin.
179     bool unifiedDiffFromStdin;
180 
181     /// Stop after this many alive mutants are found. Only effective if constraint.empty is false.
182     Nullable!int maxAlive;
183 
184     /// The size of the thread pool which affects how many tests are executed in parallel.
185     int testPoolSize;
186 
187     /// Seed used when randomly choosing mutants to test in a pull request.
188     long pullRequestSeed = 42;
189 
190     /// If early stopping of test command execution should be used
191     bool useEarlyTestCmdStop;
192 
193     /// If schematas are used for mutation testing.
194     bool useSchemata;
195 
196     /// Sanity check a schemata before it is used.
197     bool sanityCheckSchemata;
198 
199     /// If the schematas should additionall be written to a separate file for offline inspection.
200     bool logSchemata;
201 
202     /// Stop mutation testing after the last schemata has been executed
203     bool stopAfterLastSchema;
204 }
205 
206 /// Settings for the administration mode
207 struct ConfigAdmin {
208     AdminOperation adminOp;
209     Mutation.Status mutantStatus;
210     Mutation.Status mutantToStatus;
211     string testCaseRegex;
212     long mutationId;
213     string mutantRationale;
214 }
215 
216 struct ConfigWorkArea {
217     /// User input root.
218     string rawRoot;
219     string[] rawRestrict;
220 
221     AbsolutePath outputDirectory;
222     AbsolutePath[] restrictDir;
223 }
224 
225 /// Configuration of the generate mode.
226 struct ConfigGenerate {
227     long mutationId;
228 }