-
Notifications
You must be signed in to change notification settings - Fork 218
Expand file tree
/
Copy pathCheckerConfiguration.cs
More file actions
532 lines (456 loc) · 17.9 KB
/
CheckerConfiguration.cs
File metadata and controls
532 lines (456 loc) · 17.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using PChecker.Utilities;
namespace PChecker
{
#pragma warning disable CA1724 // Type names should not match namespaces
/// <summary>
/// The checker project configurations.
/// </summary>
[DataContract]
[Serializable]
public class CheckerConfiguration
{
/// <summary>
/// The P compiled path.
/// </summary>
[DataMember]
public string PCompiledPath;
/// <summary>
/// The output path.
/// </summary>
[DataMember]
public string OutputPath;
/// <summary>
/// Timeout in seconds.
/// </summary>
[DataMember]
public string OutputDirectory;
/// <summary>
/// Timeout in seconds.
/// </summary>
[DataMember]
public int Timeout;
/// <summary>
/// Memory limit in GB.
/// </summary>
[DataMember]
public double MemoryLimit;
/// <summary>
/// The assembly to be analyzed for bugs.
/// </summary>
[DataMember]
public string AssemblyToBeAnalyzed;
/// <summary>
/// Checking mode
/// </summary>
[DataMember]
public CheckerMode Mode;
/// <summary>
/// Test case to be used.
/// </summary>
[DataMember]
public string TestCaseName;
/// <summary>
/// List test cases and exit.
/// </summary>
[DataMember]
public bool ListTestCases;
/// <summary>
/// The systematic testing strategy to use.
/// </summary>
[DataMember]
public string SchedulingStrategy { get; set; }
/// <summary>
/// Number of testing schedules.
/// </summary>
[DataMember]
public int TestingIterations { get; set; }
/// <summary>
/// Custom seed to be used by the random value generator. By default,
/// this value is null indicating that no seed has been set.
/// </summary>
[DataMember]
public uint? RandomGeneratorSeed { get; set; }
/// <summary>
/// If true, the seed will increment in each
/// testing schedule.
/// </summary>
[DataMember]
public bool IncrementalSchedulingSeed;
/// <summary>
/// If true, the tester performs a full exploration,
/// and does not stop when it finds a bug.
/// </summary>
[DataMember]
public bool PerformFullExploration;
/// <summary>
/// The maximum scheduling steps to explore for fair schedulers.
/// By default this is set to 100,000 steps.
/// </summary>
[DataMember]
public int MaxFairSchedulingSteps { get; set; }
/// <summary>
/// The maximum scheduling steps to explore for unfair schedulers.
/// By default this is set to 10,000 steps.
/// </summary>
[DataMember]
public int MaxUnfairSchedulingSteps { get; set; }
/// <summary>
/// The maximum scheduling steps to explore
/// for both fair and unfair schedulers.
/// By default there is no bound.
/// </summary>
public int MaxSchedulingSteps
{
set
{
MaxUnfairSchedulingSteps = value;
MaxFairSchedulingSteps = value;
}
}
/// <summary>
/// True if the user has explicitly set the
/// fair scheduling steps bound.
/// </summary>
[DataMember]
public bool UserExplicitlySetMaxFairSchedulingSteps;
/// <summary>
/// If true, then the tester will consider an execution
/// that hits the depth bound as buggy.
/// </summary>
[DataMember]
public bool ConsiderDepthBoundHitAsBug;
/// <summary>
/// A strategy-specific bound.
/// </summary>
[DataMember]
public int StrategyBound { get; set; }
/// <summary>
/// If this option is enabled, liveness checking is enabled during bug-finding.
/// </summary>
[DataMember]
public bool IsLivenessCheckingEnabled;
/// <summary>
/// The liveness temperature threshold. If it is 0
/// then it is disabled.
/// </summary>
[DataMember]
public int LivenessTemperatureThreshold { get; set; }
/// <summary>
/// If this option is enabled, the tester is hashing the program state.
/// </summary>
[DataMember] public bool IsProgramStateHashingEnabled;
/// <summary>
/// The schedule file to be replayed.
/// </summary>
public string ScheduleFile;
/// <summary>
/// The schedule trace to be replayed.
/// </summary>
public string ScheduleTrace;
/// <summary>
/// If true, then messages are logged.
/// </summary>
[DataMember]
public bool IsVerbose { get; set; }
/// <summary>
/// Enables code coverage reporting of a program.
/// </summary>
[DataMember]
public bool ReportCodeCoverage;
/// <summary>
/// Enables activity coverage reporting of a program.
/// </summary>
[DataMember]
public bool ReportActivityCoverage { get; set; }
/// <summary>
/// Enables activity coverage debugging.
/// </summary>
public bool DebugActivityCoverage;
/// <summary>
/// Produce an XML formatted runtime log file.
/// </summary>
[DataMember]
public bool IsXmlLogEnabled { get; set; }
/// <summary>
/// Produce a JSON formatted runtime log file.
/// Defaults to true.
/// </summary>
[DataMember]
public bool IsJsonLogEnabled { get; set; } = true;
/// <summary>
/// If specified, requests a custom runtime log to be used instead of the default.
/// This is the AssemblyQualifiedName of the type to load.
/// </summary>
[DataMember]
public string CustomStateMachineRuntimeLogType;
/// <summary>
/// The testing scheduler unique endpoint.
/// </summary>
[DataMember]
public string TestingSchedulerEndPoint;
/// <summary>
/// The unique testing process id.
/// </summary>
[DataMember]
public uint TestingProcessId;
/// <summary>
/// Additional assembly specifications to instrument for code coverage, besides those in the
/// dependency graph between <see cref="AssemblyToBeAnalyzed"/> and the Microsoft.Coyote DLLs.
/// Key is filename, value is whether it is a list file (true) or a single file (false).
/// </summary>
public Dictionary<string, bool> AdditionalCodeCoverageAssemblies;
/// <summary>
/// Enables colored console output.
/// </summary>
public bool EnableColoredConsoleOutput;
/// <summary>
/// If true, then environment exit will be disabled.
/// </summary>
public bool DisableEnvironmentExit;
/// <summary>
/// Additional arguments to pass to PSym.
/// </summary>
[DataMember]
public string PSymArgs;
/// <summary>
/// Additional arguments to pass to JVM-based checker.
/// </summary>
[DataMember]
public string JvmArgs;
/// <summary>
/// Initializes a new instance of the <see cref="CheckerConfiguration"/> class.
/// </summary>
protected CheckerConfiguration()
{
PCompiledPath = Directory.GetCurrentDirectory();
OutputPath = "PCheckerOutput";
Timeout = 0;
MemoryLimit = 0;
AssemblyToBeAnalyzed = string.Empty;
Mode = CheckerMode.BugFinding;
TestCaseName = string.Empty;
ListTestCases = false;
SchedulingStrategy = "random";
TestingIterations = 1;
RandomGeneratorSeed = null;
IncrementalSchedulingSeed = false;
PerformFullExploration = false;
MaxFairSchedulingSteps = 100000; // 10 times the unfair steps
MaxUnfairSchedulingSteps = 10000;
UserExplicitlySetMaxFairSchedulingSteps = false;
TestingProcessId = 0;
ConsiderDepthBoundHitAsBug = false;
StrategyBound = 0;
IsLivenessCheckingEnabled = true;
LivenessTemperatureThreshold = 0;
IsProgramStateHashingEnabled = false;
ScheduleFile = string.Empty;
ScheduleTrace = string.Empty;
ReportCodeCoverage = false;
ReportActivityCoverage = true;
DebugActivityCoverage = false;
IsVerbose = false;
EnableColoredConsoleOutput = false;
DisableEnvironmentExit = true;
PSymArgs = "";
JvmArgs = "";
}
/// <summary>
/// Creates a new checkerConfiguration with default values.
/// </summary>
public static CheckerConfiguration Create()
{
return new CheckerConfiguration();
}
/// <summary>
/// Updates the checkerConfiguration to use the random scheduling strategy during systematic testing.
/// </summary>
public CheckerConfiguration WithRandomStrategy()
{
SchedulingStrategy = "random";
return this;
}
/// <summary>
/// Updates the checkerConfiguration to use the probabilistic scheduling strategy during systematic testing.
/// You can specify a value controlling the probability of each scheduling decision. This value is
/// specified as the integer N in the equation 0.5 to the power of N. So for N=1, the probability is
/// 0.5, for N=2 the probability is 0.25, N=3 you get 0.125, etc. By default, this value is 3.
/// </summary>
/// <param name="probabilityLevel">The probability level.</param>
public CheckerConfiguration WithProbabilisticStrategy(uint probabilityLevel = 3)
{
SchedulingStrategy = "fairpct";
StrategyBound = (int)probabilityLevel;
return this;
}
/// <summary>
/// Updates the checkerConfiguration to use the PCT scheduling strategy during systematic testing.
/// You can specify the number of priority switch points, which by default are 10.
/// </summary>
/// <param name="isFair">If true, use the fair version of PCT.</param>
/// <param name="numPrioritySwitchPoints">The nunmber of priority switch points.</param>
public CheckerConfiguration WithPCTStrategy(bool isFair, uint numPrioritySwitchPoints = 10)
{
SchedulingStrategy = isFair ? "fairpct" : "pct";
StrategyBound = (int)numPrioritySwitchPoints;
return this;
}
/// <summary>
/// Updates the configuration to use the reinforcement learning (RL) scheduling strategy
/// during systematic testing.
/// </summary>
public CheckerConfiguration WithRLStrategy()
{
this.SchedulingStrategy = "rl";
this.IsProgramStateHashingEnabled = true;
return this;
}
/// <summary>
/// Updates the checkerConfiguration to use the dfs scheduling strategy during systematic testing.
/// </summary>
public CheckerConfiguration WithDFSStrategy()
{
SchedulingStrategy = "dfs";
return this;
}
/// <summary>
/// Updates the checkerConfiguration to use the replay scheduling strategy during systematic testing.
/// This strategy replays the specified schedule trace to reproduce the same execution.
/// </summary>
/// <param name="scheduleTrace">The schedule trace to be replayed.</param>
public CheckerConfiguration WithReplayStrategy(string scheduleTrace)
{
SchedulingStrategy = "replay";
ScheduleTrace = scheduleTrace;
return this;
}
/// <summary>
/// Updates the checkerConfiguration with the specified number of schedules to run during systematic testing.
/// </summary>
/// <param name="schedules">The number of schedules to run.</param>
public CheckerConfiguration WithTestingIterations(uint schedules)
{
TestingIterations = (int)schedules;
return this;
}
/// <summary>
/// Updates the checkerConfiguration with the specified number of scheduling steps to explore per schedule
/// (for both fair and unfair schedulers) during systematic testing.
/// </summary>
/// <param name="maxSteps">The scheduling steps to explore per schedule.</param>
public CheckerConfiguration WithMaxSchedulingSteps(uint maxSteps)
{
MaxSchedulingSteps = (int)maxSteps;
return this;
}
/// <summary>
/// Updates the checkerConfiguration with the specified number of fair scheduling steps to explore
/// per schedule during systematic testing.
/// </summary>
/// <param name="maxFairSteps">The scheduling steps to explore per schedule.</param>
public CheckerConfiguration WithMaxFairSchedulingSteps(uint maxFairSteps)
{
MaxFairSchedulingSteps = (int)maxFairSteps;
return this;
}
/// <summary>
/// Updates the checkerConfiguration with the specified number of unfair scheduling steps to explore
/// per schedule during systematic testing.
/// </summary>
/// <param name="maxUnfairSteps">The scheduling steps to explore per schedule.</param>
public CheckerConfiguration WithMaxUnfairSchedulingSteps(uint maxUnfairSteps)
{
MaxUnfairSchedulingSteps = (int)maxUnfairSteps;
return this;
}
/// <summary>
/// Updates the checkerConfiguration with the specified liveness temperature threshold during systematic testing.
/// If this value is 0 it disables liveness checking.
/// </summary>
/// <param name="threshold">The liveness temperature threshold.</param>
public CheckerConfiguration WithLivenessTemperatureThreshold(uint threshold)
{
LivenessTemperatureThreshold = (int)threshold;
return this;
}
/// <summary>
/// Updates the seed used by the random value generator during systematic testing.
/// </summary>
/// <param name="seed">The seed used by the random value generator.</param>
public CheckerConfiguration WithRandomGeneratorSeed(uint seed)
{
RandomGeneratorSeed = seed;
return this;
}
/// <summary>
/// Updates the checkerConfiguration with verbose output enabled or disabled.
/// </summary>
/// <param name="isVerbose">If true, then messages are logged.</param>
public CheckerConfiguration WithVerbosityEnabled(bool isVerbose = true)
{
IsVerbose = isVerbose;
return this;
}
/// <summary>
/// Updates the checkerConfiguration with activity coverage enabled or disabled.
/// </summary>
/// <param name="isEnabled">If true, then enables activity coverage.</param>
public CheckerConfiguration WithActivityCoverageEnabled(bool isEnabled = true)
{
ReportActivityCoverage = isEnabled;
return this;
}
/// <summary>
/// Updates the checkerConfiguration with XML log generation enabled or disabled.
/// </summary>
/// <param name="isEnabled">If true, then enables XML log generation.</param>
public CheckerConfiguration WithXmlLogEnabled(bool isEnabled = true)
{
IsXmlLogEnabled = isEnabled;
return this;
}
/// <summary>
/// Set the <see cref="OutputDirectory"/> to either the user-specified <see cref="CheckerConfiguration.OutputPath"/>
/// or to a unique output directory name in the same directory as <see cref="CheckerConfiguration.AssemblyToBeAnalyzed"/>
/// and starting with its name.
/// </summary>
public void SetOutputDirectory()
{
// Do not create the output directory yet if we have to scroll back the history first.
OutputDirectory = Reporter.GetOutputDirectory(OutputPath, AssemblyToBeAnalyzed,
Mode.ToString(), createDir: false);
// The MaxHistory previous results are kept under the directory name with a suffix scrolling back from 0 to 9 (oldest).
const int MaxHistory = 10;
string makeHistoryDirName(int history) => OutputDirectory.Substring(0, OutputDirectory.Length - 1) + history;
var older = makeHistoryDirName(MaxHistory - 1);
if (Directory.Exists(older))
{
Directory.Delete(older, true);
}
if(this.SchedulingStrategy != "replay"){
for (var history = MaxHistory - 2; history >= 0; --history)
{
var newer = makeHistoryDirName(history);
if (Directory.Exists(newer))
{
Directory.Move(newer, older);
}
older = newer;
}
if (Directory.Exists(OutputDirectory))
{
Directory.Move(OutputDirectory, older);
}
}
// Now create the new directory.
Directory.CreateDirectory(OutputDirectory);
}
}
#pragma warning restore CA1724 // Type names should not match namespaces
}