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 
59 /// Configuration data for the compile_commands.json
60 struct ConfigCompileDb {
61     import dextool.compilation_db : CompileCommandFilter;
62 
63     /// Raw user input via either config or cli
64     string[] rawDbs;
65 
66     /// path to compilation databases.
67     AbsolutePath[] dbs;
68 
69     /// Flags the user wants to be automatically removed from the compile_commands.json.
70     CompileCommandFilter flagFilter;
71 }
72 
73 /// Configuration of how the mutation analyzer should act.
74 struct ConfigAnalyze {
75     /// User input of excludes before they are adjusted to relative root
76     string[] rawExclude;
77 
78     /// Exclude any files that are in these directory trees from the analysis.
79     AbsolutePath[] exclude;
80 
81     /// The size of the thread pool which affects how many files are analyzed in parallel.
82     int poolSize;
83 
84     /// What files to analyze is derived from a diff.
85     bool unifiedDiffFromStdin;
86 
87     /// Remove files from the database that aren't found when analyzing.
88     bool prune;
89 
90     /// Turn off the sqlite synchronization safety
91     bool fastDbStore;
92 }
93 
94 /// Settings for the compiler
95 struct ConfigCompiler {
96     import dextool.compilation_db : SystemCompiler = Compiler;
97 
98     /// Additional flags the user wants to add besides those that are in the compile_commands.json.
99     string[] extraFlags;
100 
101     /// True requires system includes to be passed on to the compiler via -I
102     bool forceSystemIncludes;
103 
104     /// Deduce compiler flags from this compiler and not the one in the
105     /// supplied compilation database.  / This is needed when the one specified
106     /// in the DB has e.g. a c++ stdlib that is not compatible with clang.
107     SystemCompiler useCompilerSystemIncludes;
108 }
109 
110 /// Settings for mutation testing
111 struct ConfigMutationTest {
112     ShellCommand[] mutationTester;
113     /// Find executables in this directory and add them to mutationTester.
114     Path[] testCommandDir;
115     /// Flags to add to all executables found in `testCommandDir`
116     string[] testCommandDirFlag;
117 
118     ShellCommand mutationCompile;
119     ShellCommand mutationTestCaseAnalyze;
120     TestCaseAnalyzeBuiltin[] mutationTestCaseBuiltin;
121     Nullable!Duration mutationTesterRuntime;
122     MutationOrder mutationOrder;
123     bool dryRun;
124 
125     /// How to behave when new test cases are detected.
126     enum NewTestCases {
127         doNothing,
128         /// Automatically reset alive mutants
129         resetAlive,
130     }
131 
132     NewTestCases onNewTestCases;
133 
134     /// How to behave when test cases are detected of having been removed
135     enum RemovedTestCases {
136         doNothing,
137         /// Remove it and all results connectedto the test case
138         remove,
139     }
140 
141     RemovedTestCases onRemovedTestCases;
142 
143     /// How to behave when mutants have aged.
144     enum OldMutant {
145         nothing,
146         test,
147     }
148 
149     OldMutant onOldMutants;
150     long oldMutantsNr;
151 
152     /// Max time to run mutation testing.
153     // note that Duration.max + Clock.currTime results in a negative time...
154     Duration maxRuntime = 52.dur!"weeks";
155 
156     // Constrain the mutation testing.
157     TestConstraint constraint;
158 
159     /// If constraints should be read from a unified diff via stdin.
160     bool unifiedDiffFromStdin;
161 
162     /// Stop after this many alive mutants are found. Only effective if constraint.empty is false.
163     Nullable!int maxAlive;
164 
165     /// The size of the thread pool which affects how many tests are executed in parallel.
166     int testPoolSize;
167 
168     /// Seed used when randomly choosing mutants to test in a pull request.
169     long pullRequestSeed = 42;
170 }
171 
172 /// Settings for the administration mode
173 struct ConfigAdmin {
174     AdminOperation adminOp;
175     Mutation.Status mutantStatus;
176     Mutation.Status mutantToStatus;
177     string testCaseRegex;
178     long mutationId;
179     string mutantRationale;
180 }
181 
182 struct ConfigWorkArea {
183     /// User input root.
184     string rawRoot;
185     string[] rawRestrict;
186 
187     AbsolutePath outputDirectory;
188     AbsolutePath[] restrictDir;
189 }
190 
191 /// Configuration of the generate mode.
192 struct ConfigGenerate {
193     long mutationId;
194 }