private void AutoTest(Frequency clockFrequency, TimeInterval operationTime, double maxStdErrRelative, long minInvokeCount) { var job = new Job { Infrastructure = { Clock = new MockClock(clockFrequency) }, Accuracy = { MaxStdErrRelative = maxStdErrRelative } }.Freeze(); var stage = CreateStage(job, data => data.InvokeCount * operationTime); long invokeCount = stage.Run(); output.WriteLine($"InvokeCount = {invokeCount} (Min= {minInvokeCount}, Max = {MaxPossibleInvokeCount})"); Assert.InRange(invokeCount, minInvokeCount, MaxPossibleInvokeCount); }
public static string GenerateRandomId(Job job) { string presentation = CharacteristicSetPresenter.Display.ToPresentation(job); if (presentation == "") return "DefaultJob"; int seed = presentation.GetHashCode(); var random = new Random(seed); string id = ""; for (int i = 0; i < 6; i++) id += (char) ('A' + random.Next(26)); return "Job-" + id; }
private void SpecificTest(TimeInterval iterationTime, TimeInterval operationTime, long minInvokeCount, long maxInvokeCount) { var job = new Job { Infrastructure = { Clock = new MockClock(Frequency.MHz) }, Run = { IterationTime = iterationTime } }.Freeze(); var stage = CreateStage(job, data => data.InvokeCount * operationTime); long invokeCount = stage.Run(); output.WriteLine($"InvokeCount = {invokeCount} (Min= {minInvokeCount}, Max = {maxInvokeCount})"); Assert.InRange(invokeCount, minInvokeCount, maxInvokeCount); }
private static Job CreateJob(string id, int launchCount, int warmupCount, int targetCount, RunStrategy? runStrategy) { var job = new Job(id); if (launchCount != DefaultValue) job.Run.LaunchCount = launchCount; if (warmupCount != DefaultValue) job.Run.WarmupCount = warmupCount; if (targetCount != DefaultValue) job.Run.TargetCount = targetCount; if (runStrategy != null) job.Run.RunStrategy = runStrategy.Value; return job.Freeze(); }
internal static void Generate(Job job, TextReader source, TextWriter destination, IResolver resolver) { var xmlReader = XmlReader.Create(source); var xmlDocument = new XmlDocument(); var configurationElement = GetOrCreateConfigurationElement(xmlDocument, xmlReader); var runtimeElement = GetOrCreateRuntimeElement(xmlDocument, configurationElement); ClearAllCustomRuntimeSettingsExceptRedirects(runtimeElement); GenerateJitSettings(xmlDocument, runtimeElement, job.Env); GenerateGCSettings(xmlDocument, runtimeElement, job.Env.Gc, resolver); xmlDocument.Save(destination); }
public void CustomToolchainsAreSupported() { var logger = new OutputLogger(Output); var generator = new MyGenerator(); var builder = new MyBuilder(); var executor = new MyExecutor(); var myToolchain = new Toolchain("My", generator, builder, executor); var job = new Job(Job.Dry) { Infrastructure = { Toolchain = myToolchain} }; var config = CreateSimpleConfig(logger).With(job); CanExecute<ToolchainBenchmark>(config, fullValidation: false); Assert.True(generator.Done); Assert.True(builder.Done); Assert.True(executor.Done); }
internal Engine(Action<long> idleAction, Action<long> mainAction, Job targetJob, Action setupAction, Action cleanupAction, long operationsPerInvoke, bool isDiagnoserAttached) { IdleAction = idleAction; MainAction = mainAction; TargetJob = targetJob; SetupAction = setupAction; CleanupAction = cleanupAction; OperationsPerInvoke = operationsPerInvoke; IsDiagnoserAttached = isDiagnoserAttached; Resolver = new CompositeResolver(BenchmarkRunnerCore.DefaultResolver, EngineResolver.Instance); Clock = targetJob.ResolveValue(InfrastructureMode.ClockCharacteristic, Resolver); ForceAllocations = targetJob.ResolveValue(GcMode.ForceCharacteristic, Resolver); UnrollFactor = targetJob.ResolveValue(RunMode.UnrollFactorCharacteristic, Resolver); Strategy = targetJob.ResolveValue(RunMode.RunStrategyCharacteristic, Resolver); EvaluateOverhead = targetJob.ResolveValue(AccuracyMode.EvaluateOverheadCharacteristic, Resolver); InvocationCount = targetJob.ResolveValue(RunMode.InvocationCountCharacteristic, Resolver); warmupStage = new EngineWarmupStage(this); pilotStage = new EnginePilotStage(this); targetStage = new EngineTargetStage(this); }
/// <summary> /// Creates a new job based on the given job without any environment variables. /// </summary> /// <param name="job">The original job</param> /// <returns>The new job which doesn't have any environment variables</returns> public static Job WithoutEnvironmentVariables(this Job job) => job.With(Array.Empty <EnvironmentVariable>());
private static Job WithCore(this Job job, Action<Job> updateCallback) { job = new Job(job); updateCallback(job); return job; }
public static Job WithHeapAffinitizeMask(this Job job, int heapAffinitizeMask) => job.WithCore(j => j.Environment.Gc.HeapAffinitizeMask = heapAffinitizeMask);
public static Job WithHeapCount(this Job job, int heapCount) => job.WithCore(j => j.Environment.Gc.HeapCount = heapCount);
/// <summary> /// On 64-bit platforms, enables arrays that are greater than 2 gigabytes (GB) in total size. /// <value>false: Arrays greater than 2 GB in total size are not enabled. This is the default.</value> /// <value>true: Arrays greater than 2 GB in total size are enabled on 64-bit platforms.</value> /// </summary> public static Job WithGcAllowVeryLargeObjects(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.AllowVeryLargeObjects = value);
/// <summary> /// Runs the job with a specific NuGet dependency which will be resolved during the Job build process /// </summary> /// <param name="job"></param> /// <param name="packageName">The NuGet package name, the latest version will be resolved</param> /// <returns></returns> public static Job WithNuGet(this Job job, string packageName) => job.WithNuGet(packageName, string.Empty);
/// <summary> /// Specifies which outliers should be removed from the distribution /// </summary> public static Job WithOutlierMode(this Job job, OutlierMode value) => job.WithCore(j => j.Accuracy.OutlierMode = value);
/// <summary> /// Specifies if the overhead should be evaluated (Idle runs) and it's average value subtracted from every result. /// True by default, very important for nano-benchmarks. /// </summary> public static Job WithEvaluateOverhead(this Job job, bool value) => job.WithCore(j => j.Accuracy.EvaluateOverhead = value);
/// <summary> /// Minimum count of benchmark invocations per iteration /// The default value is 4. /// </summary> public static Job WithMinInvokeCount(this Job job, int value) => job.WithCore(j => j.Accuracy.MinInvokeCount = value);
/// <summary> /// Minimum time of a single iteration. Unlike Run.IterationTime, this characteristic specifies only the lower limit. In case of need, BenchmarkDotNet can increase this value. /// The default value is 500 milliseconds. /// </summary> public static Job WithMinIterationTime(this Job job, TimeInterval value) => job.WithCore(j => j.Accuracy.MinIterationTime = value);
/// <summary> /// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error). /// Doesn't have a default value. /// <remarks>If <see cref="AccuracyMode.MaxRelativeError"/> is also provided, the smallest value is used as stop criteria.</remarks> /// </summary> public static Job WithMaxAbsoluteError(this Job job, TimeInterval value) => job.WithCore(j => j.Accuracy.MaxAbsoluteError = value);
// Accuracy /// <summary> /// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error). /// The default value is 0.02. /// <remarks>If <see cref="AccuracyMode.MaxAbsoluteError"/> is also provided, the smallest value is used as stop criteria.</remarks> /// </summary> public static Job WithMaxRelativeError(this Job job, double value) => job.WithCore(j => j.Accuracy.MaxRelativeError = value);
/// <summary> /// Runs the job with a specific NuGet dependencies which will be resolved during the Job build process /// </summary> /// <param name="job"></param> /// <param name="nuGetReferences">A collection of NuGet dependencies</param> /// <returns></returns> public static Job WithNuGet(this Job job, IReadOnlyCollection <NuGetReference> nuGetReferences) => job.WithCore(j => j.Infrastructure.NuGetReferences = nuGetReferences);
public MockEngine(ITestOutputHelper output, Job job, Func<IterationData, TimeInterval> measure) { this.output = output; this.measure = measure; TargetJob = job; }
private string GetMonoArguments(Job job, string exeName, string args, IResolver resolver) { // from mono --help: "Usage is: mono [options] program [program-options]" return new StringBuilder(30) .Append(job.ResolveValue(EnvMode.JitCharacteristic, resolver) == Jit.Llvm ? "--llvm" : "--nollvm") .Append(' ') .Append(exeName) .Append(' ') .Append(args) .ToString(); }
public static Job WithRemoveOutliers(this Job job, bool value) => job.WithCore(j => j.Accuracy.OutlierMode = value ? OutlierMode.OnlyUpper : OutlierMode.None);
/// <summary> /// Specifies whether the BenchmarkDotNet's benchmark runner forces full garbage collection after each benchmark invocation /// <value>false: Does not force garbage collection.</value> /// <value>true: Forces full garbage collection after each benchmark invocation. This is the default.</value> /// </summary> public static Job WithGcForce(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.Force = value);
/// <summary> /// Specifies whether the common language runtime runs server garbage collection. /// <value>false: Does not run server garbage collection. This is the default.</value> /// <value>true: Runs server garbage collection.</value> /// </summary> public static Job WithGcServer(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.Server = value);
public static Job WithGcRetainVm(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.RetainVm = value);
public static Job WithAnalyzeLaunchVariance(this Job job, bool value) => job.WithCore(j => j.Accuracy.AnalyzeLaunchVariance = value);
public static Job WithNoAffinitize(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.NoAffinitize = value);
// Meta public static Job AsBaseline(this Job job) => job.WithCore(j => j.Meta.Baseline = true);
public static Job With(this Job job, GcMode gc) => job.WithCore(j => EnvironmentMode.GcCharacteristic[j] = gc);
public static Job WithBaseline(this Job job, bool value) => job.WithCore(j => j.Meta.Baseline = value);
/// <summary> /// ProcessorAffinity for the benchmark process. /// See also: https://msdn.microsoft.com/library/system.diagnostics.process.processoraffinity.aspx /// </summary> public static Job WithAffinity(this Job job, IntPtr affinity) => job.WithCore(j => j.Environment.Affinity = affinity);
public static Job WithIsBaseline(this Job job, bool value) => value?job.AsBaseline() : job;
public static Job With(this Job job, IReadOnlyList <Argument> arguments) => job.WithCore(j => j.Infrastructure.Arguments = arguments);
public static void Test01Create() { var j = new Job("CustomId"); Equal(j.Frozen, false); Equal(j.Env.Frozen, false); Equal(j.Run.Frozen, false); Equal(j.Env.Gc.AllowVeryLargeObjects, false); Equal(j.Env.Platform, Platform.AnyCpu); Equal(j.Run.RunStrategy, RunStrategy.Throughput); // set by default Equal(j.Id, "CustomId"); Equal(j.DisplayInfo, "CustomId"); Equal(j.ResolvedId, "CustomId"); Equal(j.ResolvedId, j.FolderInfo); Equal(j.Env.Id, "CustomId"); // freeze var old = j; j = j.Freeze(); Same(old, j); j = j.Freeze(); Same(old, j); Equal(j.Frozen, true); Equal(j.Env.Frozen, true); Equal(j.Run.Frozen, true); Equal(j.Env.Gc.AllowVeryLargeObjects, false); Equal(j.Env.Platform, Platform.AnyCpu); Equal(j.Run.RunStrategy, RunStrategy.Throughput); // set by default Equal(j.Id, "CustomId"); Equal(j.DisplayInfo, "CustomId"); Equal(j.ResolvedId, "CustomId"); Equal(j.ResolvedId, j.FolderInfo); Equal(j.Env.Id, "CustomId"); // unfreeze old = j; j = j.UnfreezeCopy(); NotSame(old, j); Equal(j.Frozen, false); Equal(j.Env.Frozen, false); Equal(j.Run.Frozen, false); Equal(j.Env.Gc.AllowVeryLargeObjects, false); Equal(j.Env.Platform, Platform.AnyCpu); Equal(j.Run.RunStrategy, RunStrategy.Throughput); // set by default Equal(j.Id, "Default"); // id reset True(j.DisplayInfo == "DefaultJob", "DisplayInfo = " + j.DisplayInfo); True(j.ResolvedId == "DefaultJob", "ResolvedId = " + j.ResolvedId); Equal(j.ResolvedId, j.FolderInfo); Equal(j.Env.Id, "Default"); // new job j = new Job(j.Freeze()); Equal(j.Frozen, false); Equal(j.Env.Frozen, false); Equal(j.Run.Frozen, false); Equal(j.Env.Gc.AllowVeryLargeObjects, false); Equal(j.Env.Platform, Platform.AnyCpu); Equal(j.Run.RunStrategy, RunStrategy.Throughput); // set by default Equal(j.Id, "Default"); // id reset True(j.DisplayInfo == "DefaultJob", "DisplayInfo = " + j.DisplayInfo); True(j.ResolvedId == "DefaultJob", "ResolvedId = " + j.ResolvedId); Equal(j.ResolvedId, j.FolderInfo); Equal(j.Env.Id, "Default"); }
private EnginePilotStage CreateStage(Job job, Func<IterationData, TimeInterval> measure) { var engine = new MockEngine(output, job, measure); return new EnginePilotStage(engine); }
public static void Test04Apply() { var j = new Job() { Run = { TargetCount = 1 } }; AssertProperties(j, "TargetCount=1"); j.Apply( new Job { Env = { Platform = Platform.X64 }, Run = { TargetCount = 2 } }); AssertProperties(j, "Platform=X64, TargetCount=2"); // filter by properties j.Env.Apply( new Job() .With(Jit.RyuJit) .WithGcAllowVeryLargeObjects(true) .WithTargetCount(3) .WithLaunchCount(22)); AssertProperties(j, "Jit=RyuJit, Platform=X64, AllowVeryLargeObjects=True, TargetCount=2"); // apply subnode j.Apply( new GcMode() { AllowVeryLargeObjects = false }); AssertProperties(j, "Jit=RyuJit, Platform=X64, AllowVeryLargeObjects=False, TargetCount=2"); // Apply empty j.Apply(Job.Default); // does nothing AssertProperties(j, "Jit=RyuJit, Platform=X64, AllowVeryLargeObjects=False, TargetCount=2"); }
public static void Test06CharacteristicHacks() { var j = new Job(); Equal(j.Run.TargetCount, 0); RunMode.TargetCountCharacteristic[j] = 123; Equal(j.Run.TargetCount, 123); var old = j.Run; Job.RunCharacteristic[j] = new RunMode(); Equal(j.Run.TargetCount, 0); Job.RunCharacteristic[j] = old; old.TargetCount = 234; Equal(j.Run.TargetCount, 234); Equal(RunMode.TargetCountCharacteristic[j], 234); Characteristic a = Job.RunCharacteristic; // will not throw: a[j] = new RunMode(); Throws<ArgumentNullException>(() => a[j] = null); // nulls for job nodes are not allowed; Throws<ArgumentNullException>(() => a[j] = Characteristic.EmptyValue); Throws<ArgumentException>(() => a[j] = new EnvMode()); // not assignable; Throws<ArgumentException>(() => a[j] = new CharacteristicSet()); // not assignable; Throws<ArgumentException>(() => a[j] = 123); // not assignable; a = InfrastructureMode.ToolchainCharacteristic; // will not throw: a[j] = ClassicToolchain.Instance; a[j] = null; a[j] = Characteristic.EmptyValue; Throws<ArgumentException>(() => a[j] = new EnvMode()); // not assignable; Throws<ArgumentException>(() => a[j] = new CharacteristicSet()); // not assignable; Throws<ArgumentException>(() => a[j] = 123); // not assignable; }
/// <summary> /// Creates a new job based on the given job with additional environment variable. /// All existed environment variables of the original job will be copied to the new one. /// If the original job already contains an environment variable with the same key, it will be overriden. /// </summary> /// <param name="job">The original job</param> /// <param name="key">The key of the new environment variable</param> /// <param name="value">The value of the new environment variable</param> /// <returns>The new job with additional environment variable</returns> public static Job WithEnvironmentVariable(this Job job, [NotNull] string key, [NotNull] string value) => job.With(new EnvironmentVariable(key, value));
/// <summary> /// mutator job should not be added to the config, but instead applied to other jobs in given config /// </summary> public static Job AsMutator(this Job job) => job.WithCore(j => j.Meta.IsMutator = true);
/// <summary> /// Runs the job with a specific NuGet dependency which will be resolved during the Job build process /// </summary> /// <param name="job"></param> /// <param name="packageName">The NuGet package name</param> /// <param name="packageVersion">The NuGet package version</param> /// <returns></returns> public static Job WithNuGet(this Job job, string packageName, string packageVersion) => job.WithCore(j => j.Infrastructure.NuGetReferences = new NuGetReferenceList(j.Infrastructure.NuGetReferences ?? Array.Empty <NuGetReference>()) { new NuGetReference(packageName, packageVersion) });
public static void Test03IdDoesNotFlow() { var j = new Job(EnvMode.LegacyJitX64, RunMode.Long); // id will not flow, new Job False(j.HasValue(JobMode.IdCharacteristic)); False(j.Env.HasValue(JobMode.IdCharacteristic)); Job.EnvCharacteristic[j] = EnvMode.LegacyJitX86.UnfreezeCopy(); // id will not flow False(j.HasValue(JobMode.IdCharacteristic)); False(j.Env.HasValue(JobMode.IdCharacteristic)); var c = new CharacteristicSet(EnvMode.LegacyJitX64, RunMode.Long); // id will not flow, new CharacteristicSet False(c.HasValue(JobMode.IdCharacteristic)); Job.EnvCharacteristic[c] = EnvMode.LegacyJitX86.UnfreezeCopy(); // id will not flow False(c.HasValue(JobMode.IdCharacteristic)); JobMode.IdCharacteristic[c] = "MyId"; // id set explicitly Equal(c.Id, "MyId"); j = new Job("MyId", EnvMode.LegacyJitX64, RunMode.Long); // id set explicitly Equal(j.Id, "MyId"); Equal(j.Env.Id, "MyId"); Job.EnvCharacteristic[j] = EnvMode.LegacyJitX86.UnfreezeCopy(); // id will not flow Equal(j.Id, "MyId"); Equal(j.Env.Id, "MyId"); j = j.With(Jit.RyuJit); // id will not flow False(j.HasValue(JobMode.IdCharacteristic)); }
/// <summary> /// use it if you want to specify custom default settings for default job used by console arguments parser /// </summary> public static Job AsDefault(this Job job, bool value = true) => job.WithCore(j => j.Meta.IsDefault = value);
public static void Test05ApplyCharacteristicSet() { var set1 = new CharacteristicSet(); var set2 = new CharacteristicSet(); set1 .Apply( new EnvMode { Platform = Platform.X64 }) .Apply( new Job { Run = { LaunchCount = 2 }, Env = { Platform = Platform.X86 } }); AssertProperties(set1, "LaunchCount=2, Platform=X86"); Equal(Job.EnvCharacteristic[set1].Platform, Platform.X86); Equal(set1.HasValue(Job.EnvCharacteristic), true); Equal(EnvMode.PlatformCharacteristic[set1], Platform.X86); set2.Apply(EnvMode.RyuJitX64).Apply(new GcMode { Concurrent = true }); Equal(Job.RunCharacteristic[set2], null); Equal(set2.HasValue(Job.RunCharacteristic), false); AssertProperties(set2, "Concurrent=True, Jit=RyuJit, Platform=X64"); var temp = set1.UnfreezeCopy(); set1.Apply(set2); set2.Apply(temp); AssertProperties(set1, "Concurrent=True, Jit=RyuJit, LaunchCount=2, Platform=X64"); AssertProperties(set2, "Concurrent=True, Jit=RyuJit, LaunchCount=2, Platform=X86"); var j = new Job(); AssertProperties(j, "Default"); j.Env.Gc.Apply(set1); AssertProperties(j, "Concurrent=True"); j.Run.Apply(set1); AssertProperties(j, "Concurrent=True, LaunchCount=2"); j.Env.Apply(set1); AssertProperties(j, "Jit=RyuJit, Platform=X64, Concurrent=True, LaunchCount=2"); j.Apply(set1); AssertProperties(j, "Jit=RyuJit, Platform=X64, Concurrent=True, LaunchCount=2"); }
/// <summary> /// Specifies whether the common language runtime runs garbage collection on a separate thread. /// <value>false: Does not run garbage collection concurrently.</value> /// <value>true: Runs garbage collection concurrently. This is the default.</value> /// </summary> public static Job WithGcConcurrent(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.Concurrent = value);
public static void Test02Modify() { var j = new Job("SomeId"); Equal(j.Id, "SomeId"); Equal(j.Env.Platform, Platform.AnyCpu); Equal(j.Run.LaunchCount, 0); False(j.HasValue(EnvMode.PlatformCharacteristic)); False(j.Env.HasValue(EnvMode.PlatformCharacteristic)); False(j.HasValue(RunMode.LaunchCountCharacteristic)); False(j.Run.HasValue(RunMode.LaunchCountCharacteristic)); AssertProperties(j, "Default"); AssertProperties(j.Env, "Default"); // 1. change values j.Env.Platform = Platform.X64; j.Run.LaunchCount = 1; Equal(j.Id, "SomeId"); Equal(j.Env.Platform, Platform.X64); Equal(j.Run.LaunchCount, 1); True(j.HasValue(EnvMode.PlatformCharacteristic)); True(j.Env.HasValue(EnvMode.PlatformCharacteristic)); True(j.HasValue(RunMode.LaunchCountCharacteristic)); True(j.Run.HasValue(RunMode.LaunchCountCharacteristic)); AssertProperties(j, "Platform=X64, LaunchCount=1"); AssertProperties(j.Env, "Platform=X64"); AssertProperties(j.Run, "LaunchCount=1"); // 2. reset Env mode (hack via Characteristic setting) var oldEnv = j.Env; Job.EnvCharacteristic[j] = new EnvMode(); Equal(j.Id, "SomeId"); Equal(j.Env.Platform, Platform.AnyCpu); Equal(j.Run.LaunchCount, 1); False(j.HasValue(EnvMode.PlatformCharacteristic)); False(j.Env.HasValue(EnvMode.PlatformCharacteristic)); True(j.HasValue(RunMode.LaunchCountCharacteristic)); True(j.Run.HasValue(RunMode.LaunchCountCharacteristic)); AssertProperties(j, "LaunchCount=1"); AssertProperties(j.Env, "Default"); AssertProperties(j.Run, "LaunchCount=1"); // 2.1 proof that oldEnv was the same Equal(j.Id, "SomeId"); Equal(oldEnv.Platform, Platform.X64); True(oldEnv.HasValue(EnvMode.PlatformCharacteristic)); Equal(oldEnv.Id, "Platform=X64"); // 3. update Env mode (hack via Characteristic setting) Job.EnvCharacteristic[j] = new EnvMode() { Platform = Platform.X86 }; Equal(j.Id, "SomeId"); Equal(j.Env.Platform, Platform.X86); Equal(j.Run.LaunchCount, 1); True(j.HasValue(EnvMode.PlatformCharacteristic)); True(j.Env.HasValue(EnvMode.PlatformCharacteristic)); True(j.HasValue(RunMode.LaunchCountCharacteristic)); True(j.Run.HasValue(RunMode.LaunchCountCharacteristic)); AssertProperties(j, "Platform=X86, LaunchCount=1"); AssertProperties(j.Env, "Platform=X86"); AssertProperties(j.Run, "LaunchCount=1"); // 4. Freeze-unfreeze: j = j.Freeze().UnfreezeCopy(); Equal(j.Id, "Platform=X86, LaunchCount=1"); Equal(j.Env.Platform, Platform.X86); Equal(j.Run.LaunchCount, 1); True(j.HasValue(EnvMode.PlatformCharacteristic)); True(j.Env.HasValue(EnvMode.PlatformCharacteristic)); True(j.HasValue(RunMode.LaunchCountCharacteristic)); True(j.Run.HasValue(RunMode.LaunchCountCharacteristic)); AssertProperties(j, "Platform=X86, LaunchCount=1"); AssertProperties(j.Env, "Platform=X86"); AssertProperties(j.Run, "LaunchCount=1"); // 5. Test .With extensions j = j.Freeze() .WithId("NewId"); Equal(j.Id, "NewId"); // id set j = j.Freeze() .With(Platform.X64) .WithLaunchCount(2); Equal(j.Id, "Platform=X64, LaunchCount=2"); // id lost Equal(j.Env.Platform, Platform.X64); Equal(j.Run.LaunchCount, 2); True(j.HasValue(EnvMode.PlatformCharacteristic)); True(j.Env.HasValue(EnvMode.PlatformCharacteristic)); True(j.HasValue(RunMode.LaunchCountCharacteristic)); True(j.Run.HasValue(RunMode.LaunchCountCharacteristic)); AssertProperties(j, "Platform=X64, LaunchCount=2"); AssertProperties(j.Env, "Platform=X64"); AssertProperties(j.Run, "LaunchCount=2"); }
public static Job WithGcCpuGroups(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.CpuGroups = value);