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     Nullable!Duration mutationTesterRuntime;
134     MutationOrder mutationOrder;
135     bool dryRun;
136 
137     /// How to behave when new test cases are detected.
138     enum NewTestCases {
139         doNothing,
140         /// Automatically reset alive mutants
141         resetAlive,
142     }
143 
144     NewTestCases onNewTestCases;
145 
146     /// How to behave when test cases are detected of having been removed
147     enum RemovedTestCases {
148         doNothing,
149         /// Remove it and all results connectedto the test case
150         remove,
151     }
152 
153     RemovedTestCases onRemovedTestCases;
154 
155     /// How to behave when mutants have aged.
156     enum OldMutant {
157         nothing,
158         test,
159     }
160 
161     OldMutant onOldMutants;
162     long oldMutantsNr;
163 
164     /// Max time to run mutation testing.
165     // note that Duration.max + Clock.currTime results in a negative time...
166     Duration maxRuntime = 52.dur!"weeks";
167 
168     // Constrain the mutation testing.
169     TestConstraint constraint;
170 
171     /// If constraints should be read from a unified diff via stdin.
172     bool unifiedDiffFromStdin;
173 
174     /// Stop after this many alive mutants are found. Only effective if constraint.empty is false.
175     Nullable!int maxAlive;
176 
177     /// The size of the thread pool which affects how many tests are executed in parallel.
178     int testPoolSize;
179 
180     /// Seed used when randomly choosing mutants to test in a pull request.
181     long pullRequestSeed = 42;
182 
183     /// If early stopping of test command execution should be used
184     bool useEarlyTestCmdStop;
185 
186     /// If schematas are used for mutation testing.
187     bool useSchemata;
188 
189     /// Sanity check a schemata before it is used.
190     bool sanityCheckSchemata;
191 
192     /// If the schematas should additionall be written to a separate file for offline inspection.
193     bool logSchemata;
194 
195     /// Stop mutation testing after the last schemata has been executed
196     bool stopAfterLastSchema;
197 }
198 
199 /// Settings for the administration mode
200 struct ConfigAdmin {
201     AdminOperation adminOp;
202     Mutation.Status mutantStatus;
203     Mutation.Status mutantToStatus;
204     string testCaseRegex;
205     long mutationId;
206     string mutantRationale;
207 }
208 
209 struct ConfigWorkArea {
210     /// User input root.
211     string rawRoot;
212     string[] rawRestrict;
213 
214     AbsolutePath outputDirectory;
215     AbsolutePath[] restrictDir;
216 }
217 
218 /// Configuration of the generate mode.
219 struct ConfigGenerate {
220     long mutationId;
221 }